Переглянути джерело

feat(utils): 添加价格格式和价格比较验证函数

- 新增 validatePriceFormat 函数用于验证价格格式(整数部分最多6位,小数部分最多2位)
- 新增 validatePriceComparison 函数用于验证两个价格之间的大小关系
- 在 newGroup.vue 和 newVoucher.vue 中引入并应用新的价格验证规则
- 扩展 voucher 补充说明字段最大长度从300到500字符
- 添加价格字段变更时的相互验证触发逻辑
congxuesong 1 місяць тому
батько
коміт
fd49bc3d62

+ 63 - 0
src/utils/eleValidate.ts

@@ -441,3 +441,66 @@ export function validateDateListArray(
 export function validatePositiveIntegerForNumber(errorMessage: string = "必须为正整数") {
   return validatePositiveInteger(errorMessage, { required: false, checkLeadingZero: false });
 }
+
+/**
+ * 验证价格格式(整数部分最多6位,小数部分最多2位)
+ * @param errorMessage - 错误提示信息,默认为"整数部分最多6位,小数部分最多2位"
+ * @returns 验证函数
+ */
+export function validatePriceFormat(errorMessage: string = "整数部分最多6位,小数部分最多2位") {
+  return (rule: any, value: any, callback: any) => {
+    if (!value || value.toString().trim() === "") {
+      callback();
+      return;
+    }
+    const strValue = value.toString().trim();
+    // 验证格式:整数部分最多6位,小数部分最多2位
+    const regex = /^\d{1,6}(\.\d{1,2})?$/;
+    if (!regex.test(strValue)) {
+      callback(new Error(errorMessage));
+      return;
+    }
+    callback();
+  };
+}
+
+/**
+ * 验证价格比较(第一个价格必须大于等于第二个价格)
+ * @param getFirstPrice - 获取第一个价格的函数(通常是抵扣价格)
+ * @param getSecondPrice - 获取第二个价格的函数(通常是售卖价格)
+ * @param errorMessage - 错误提示信息,默认为"抵扣价格不能低于售卖价格"
+ * @returns 验证函数
+ */
+export function validatePriceComparison(
+  getFirstPrice: () => any,
+  getSecondPrice: () => any,
+  errorMessage: string = "抵扣价格不能低于售卖价格"
+) {
+  return (rule: any, value: any, callback: any) => {
+    const firstPrice = getFirstPrice();
+    const secondPrice = getSecondPrice();
+
+    // 如果任一价格为空,不进行验证
+    if (!firstPrice || !secondPrice || firstPrice.toString().trim() === "" || secondPrice.toString().trim() === "") {
+      callback();
+      return;
+    }
+
+    const firstNum = Number(firstPrice);
+    const secondNum = Number(secondPrice);
+
+    // 如果转换失败,不进行验证(由其他验证规则处理)
+    if (isNaN(firstNum) || isNaN(secondNum)) {
+      callback();
+      return;
+    }
+
+    // 验证第一个价格必须大于等于第二个价格
+    if (firstNum < secondNum) {
+      callback(new Error(errorMessage));
+      return;
+    }
+
+    callback();
+  };
+}

+ 7 - 1
src/views/groupPackageManagement/newGroup.vue

@@ -471,7 +471,8 @@ import {
   validatePositiveInteger,
   validateDateRangeArray,
   validateConditionalRequired,
-  validateDateListArray
+  validateDateListArray,
+  validatePriceFormat
 } from "@/utils/eleValidate";
 
 // ==================== 响应式数据定义 ====================
@@ -650,6 +651,10 @@ const rules = reactive({
         callback();
       },
       trigger: "blur"
+    },
+    {
+      validator: validatePriceFormat("整数部分最多6位,小数部分最多2位"),
+      trigger: "blur"
     }
   ],
   effectiveDateType: [{ required: true, message: "请选择有效期" }],
@@ -1059,6 +1064,7 @@ onMounted(async () => {
 const goBack = () => {
   router.go(-1);
 };
+
 const beforeAvatarUpload = (file: any) => {
   console.log(file);
   return false;

+ 58 - 2
src/views/voucherManagement/newVoucher.vue

@@ -206,7 +206,7 @@
             <h3 style="font-weight: bold">补充说明:</h3>
             <el-form-item label="补充说明" prop="supplement">
               <el-input
-                maxlength="300"
+                maxlength="500"
                 v-model="voucherModel.supplement"
                 :rows="4"
                 type="textarea"
@@ -244,7 +244,9 @@ import {
   validateDateRangeArray,
   validateConditionalRequired,
   validateArrayMinLength,
-  validateDateListArray
+  validateDateListArray,
+  validatePriceFormat,
+  validatePriceComparison
 } from "@/utils/eleValidate";
 
 // ==================== 响应式数据定义 ====================
@@ -265,6 +267,18 @@ const rules = reactive({
     {
       validator: validatePositiveNumber("抵扣价格必须为正数"),
       trigger: "blur"
+    },
+    {
+      validator: validatePriceFormat("整数部分最多6位,小数部分最多2位"),
+      trigger: "blur"
+    },
+    {
+      validator: validatePriceComparison(
+        () => voucherModel.value.offprice,
+        () => voucherModel.value.price,
+        "抵扣价格不能低于售卖价格"
+      ),
+      trigger: "blur"
     }
   ],
   price: [
@@ -272,6 +286,18 @@ const rules = reactive({
     {
       validator: validatePositiveNumber("售卖价格必须为正数"),
       trigger: "blur"
+    },
+    {
+      validator: validatePriceFormat("整数部分最多6位,小数部分最多2位"),
+      trigger: "blur"
+    },
+    {
+      validator: validatePriceComparison(
+        () => voucherModel.value.offprice,
+        () => voucherModel.value.price,
+        "抵扣价格不能低于售卖价格"
+      ),
+      trigger: "blur"
     }
   ],
   startDate: [
@@ -547,6 +573,36 @@ watch(
 );
 
 /**
+ * 监听抵扣价格变化
+ * 当抵扣价格改变时,重新验证售卖价格
+ */
+watch(
+  () => voucherModel.value.offprice,
+  () => {
+    if (voucherModel.value.price) {
+      nextTick(() => {
+        ruleFormRef.value?.validateField("price");
+      });
+    }
+  }
+);
+
+/**
+ * 监听售卖价格变化
+ * 当售卖价格改变时,重新验证抵扣价格
+ */
+watch(
+  () => voucherModel.value.price,
+  () => {
+    if (voucherModel.value.offprice) {
+      nextTick(() => {
+        ruleFormRef.value?.validateField("offprice");
+      });
+    }
+  }
+);
+
+/**
  * 监听使用开始时间变化
  * 更新虚拟字段以支持表单验证
  */