Просмотр исходного кода

【服务项目维护】【待确认项目】必填项没标

张田田 8 месяцев назад
Родитель
Сommit
3826eff3f1
1 измененных файлов с 178 добавлено и 27 удалено
  1. 178 27
      src/service/ConfirmItems.vue

+ 178 - 27
src/service/ConfirmItems.vue

@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import { ref, reactive, watch, onMounted, defineEmits, nextTick } from 'vue';
-import { message } from 'ant-design-vue';
+import { notification } from 'ant-design-vue';
 import { PlusOutlined } from '@ant-design/icons-vue';
 import { branchMethod } from '@/request/api/system.api';
 import { useRequest } from 'alova/client';
@@ -43,10 +43,10 @@ const supplierOptions = ref<any[]>([]);
 const supplierArr = ref<any[]>([]);
 supplierOptions.value = [];
 function getSupplier(params: any) {
-  getAllSupplierMethod(params).then((res) => {
-    if (res?.length > 0) {
-      supplierArr.value = res;
-      supplierOptions.value = res.map((item: any) => ({
+  getAllSupplierMethod(params).then((res: unknown) => {
+    if (Array.isArray(res) && res.length > 0) {
+      supplierArr.value = res as any[];
+      supplierOptions.value = (res as any[]).map((item: any) => ({
         label: item.name,
         value: item.id,
       }));
@@ -149,11 +149,19 @@ const handlePreview = async (file: UploadFile) => {
 };
 
 function removeHerb(idx: number) {
-  props.data.cpMedicines.splice(idx, 1);
+  if (Array.isArray(props.data.cpMedicines)) {
+    // eslint-disable-next-line vue/no-mutating-props
+    props.data.cpMedicines.splice(idx, 1);
+  }
 }
 
 function addHerb() {
-  props.data.cpMedicines.push({ name: '', dosage: '', unit: 'g' });
+  if (!Array.isArray(props.data.cpMedicines)) {
+    // eslint-disable-next-line vue/no-mutating-props
+    props.data.cpMedicines = [] as any[];
+  }
+  // eslint-disable-next-line vue/no-mutating-props
+  (props.data.cpMedicines as any[]).push({ name: '', dosage: '' } as any);
 }
 
 function handleCancel() {
@@ -165,14 +173,141 @@ const emit = defineEmits<{
   (e: 'submit', data: SystemItemModel): void;
 }>();
 
+function validate(): boolean {
+  const d = props.data as any;
+  // 计价规则 必填
+  if (d.pricingType === undefined || d.pricingType === null || d.pricingType === '') {
+    notification.error({
+      message: '请选择计价规则',
+      description: '请选择计价规则',
+    });
+    return false;
+  }
+  // 单价 必填(当一口价时)
+  if (d.pricingType === '0') {
+    const unitPrice = d.cpFixedPricingRule?.unitPrice;
+    if (unitPrice === undefined || unitPrice === null || unitPrice === '') {
+      notification.error({
+        message: '请填写单价',
+        description: '请填写单价',
+      });
+      return false;
+    }
+    // 计价单位 必填
+    if (!d.cpFixedPricingRule?.pricingUnit) {
+      notification.error({
+        message: '请填写计价单位',
+        description: '请填写计价单位',
+      });
+      return false;
+    }
+    // 转换剂量 必填
+    if (!d.cpFixedPricingRule?.convertDose) {
+      notification.error({
+        message: '请填写转换剂量',
+        description: '请填写转换剂量',
+      });
+      return false;
+    }
+    // 转换单位 必填
+    if (!d.cpFixedPricingRule?.convertUnit) {
+      notification.error({
+        message: '请选择转换单位',
+        description: '请选择转换单位',
+      });
+      return false;
+    }
+  }
+  // 穴位/经络/部位 范围 必填(当动态计价时)
+  if (d.pricingType === '1') {
+    const rules = d.cpDynamicPricingRule;
+    if (!Array.isArray(rules) || rules.length < 2) {
+      notification.error({
+        message: '请完善穴位/经络/部位的计价规则',
+        description: '请完善穴位/经络/部位的计价规则',
+      });
+      return false;
+    }
+
+    // 验证计价1
+    const rule1 = rules[0];
+    if (!rule1 || rule1.min === undefined || rule1.min === '') {
+      notification.error({
+        message: '请填写计价1的穴位/经络/部位范围',
+        description: '请填写计价1的穴位/经络/部位范围',
+      });
+      return false;
+    }
+    if (rule1.priceType === undefined || rule1.priceType === null || rule1.priceType === '') {
+      notification.error({
+        message: '请选择计价1的计价类型',
+        description: '请选择计价1的计价类型',
+      });
+      return false;
+    }
+    if (!rule1.price || rule1.price === '') {
+      notification.error({
+        message: '请填写计价1的价格',
+        description: '请填写计价1的价格',
+      });
+      return false;
+    }
+
+    // 验证计价2
+    const rule2 = rules[1];
+    if (!rule2 || rule2.max === undefined || rule2.max === '') {
+      notification.error({
+        message: '请填写计价2的穴位/经络/部位范围',
+        description: '请填写计价2的穴位/经络/部位范围',
+      });
+      return false;
+    }
+    if (rule2.priceType === undefined || rule2.priceType === null || rule2.priceType === '') {
+      notification.error({
+        message: '请选择计价2的计价类型',
+        description: '请选择计价2的计价类型',
+      });
+      return false;
+    }
+    if (!rule2.price || rule2.price === '') {
+      notification.error({
+        message: '请填写计价2的价格',
+        description: '请填写计价2的价格',
+      });
+      return false;
+    }
+  }
+  // 机构 必填
+  if (!d.institutionId) {
+    notification.error({
+      message: '请选择机构名称',
+      description: '请选择机构名称',
+    });
+    return false;
+  }
+  // 供应商 必填
+  if (!d.conditioningProgramSupplierId) {
+    notification.error({
+      message: '请选择供应商',
+      description: '请选择供应商',
+    });
+    return false;
+  }
+  return true;
+}
+
 function handleOk() {
+  if (!validate()) return;
   if (showOffLine.value && !props.data.isOffline) {
     props.data.isOffline = 'N';
   }
-  confirmOrgConfirmMethod(props.data).then(() => {
-    emit('submit', props.data);
+  confirmOrgConfirmMethod(props.data as SystemItemModel).then(() => {
+    emit('submit', props.data as SystemItemModel);
     VxeUI.modal.close('confirm-item-modal');
-    message.success('提交成功');
+    notification.success({
+      message: '提交成功',
+      description: '提交成功',
+    });
   });
 }
 // 创建一个响应式变量来控制 checkbox 的状态
@@ -217,26 +352,26 @@ function handleSelect(value: string, node: any, extra: any) {
       <div>{{ data.conditioningProgramType }}</div>
     </div>
     <div class="form-row">
-      <label>计价规则:</label>
+      <label><span class="required-star">*</span>计价规则:</label>
       <div>{{ data.pricingType === '0' ? '一口价' : '按穴位/经络/部位' }}</div>
     </div>
     <div class="form-row" v-if="data.pricingType === '0'">
-      <label>单价:</label>
-      <a-input v-model:value="data.cpFixedPricingRule.unitPrice" placeholder="请输入" style="width: 100px; margin-left: 8px" />
+      <label><span class="required-star">*</span>单价:</label>
+      <a-input v-model:value="data.cpFixedPricingRule!.unitPrice" placeholder="请输入" style="width: 100px; margin-left: 8px" />
       <span style="margin-left: 20px">元</span>
       <span style="margin-left: 20px">计价单位:</span>
-      <a-input v-model:value="data.cpFixedPricingRule.pricingUnit" placeholder="请输入" style="width: 100px; margin-left: 8px" />
+      <a-input v-model:value="data.cpFixedPricingRule!.pricingUnit" placeholder="请输入" style="width: 100px; margin-left: 8px" />
       <span style="margin-left: 20px">相当于</span>
-      <a-input v-model:value="data.cpFixedPricingRule.convertDose" placeholder="请输入" style="width: 100px; margin-left: 8px" />
-      <a-select v-model:value="data.cpFixedPricingRule.convertUnit" style="width: 60px; margin-left: 8px" :options="unitOptions" placeholder="请选择" />
+      <a-input v-model:value="data.cpFixedPricingRule!.convertDose" placeholder="请输入" style="width: 100px; margin-left: 8px" />
+      <a-select v-model:value="data.cpFixedPricingRule!.convertUnit" style="width: 60px; margin-left: 8px" :options="unitOptions" placeholder="请选择" />
       <span style="color: #aaa; margin-left: 10px">(使用单位)</span>
     </div>
     <div v-if="data.pricingType === '1'" class="per-rule">
       <div class="price-row">
-        <span>计价1:</span>
-        <span class="flex items-center">当"穴位/经络/部位" ≤ <a-input placeholder="请输入" class="w-20 ml-2 mr-2" v-model:value="data.cpDynamicPricingRule[0].min" />个时,</span>
+        <span><span class="required-star">*</span>计价1:</span>
+        <span class="flex items-center">当"穴位/经络/部位" ≤ <a-input placeholder="请输入" class="w-20 ml-2 mr-2" v-model:value="data.cpDynamicPricingRule![0].min" />个时,</span>
         <a-select
-          v-model:value="data.cpDynamicPricingRule[0].priceType"
+          v-model:value="data.cpDynamicPricingRule![0].priceType"
           :options="[
             { label: '单价', value: 0, priceType: 0 },
             { label: '一口价', value: 1, priceType: 1 },
@@ -245,16 +380,16 @@ function handleSelect(value: string, node: any, extra: any) {
           placeholder="请选择"
         />
         <span>=</span>
-        <a-input v-model:value="data.cpDynamicPricingRule[0].price" style="width: 80px; margin: 0 4px" placeholder="请输入" />
+        <a-input v-model:value="data.cpDynamicPricingRule![0].price" style="width: 80px; margin: 0 4px" placeholder="请输入" />
         <span>元</span>
       </div>
       <div class="price-row">
-        <span>计价2:</span>
+        <span><span class="required-star">*</span>计价2:</span>
         <span class="flex items-center"
-          >当"穴位/经络/部位" &gt; <a-input placeholder="请输入" class="w-20 ml-2 mr-2" v-model:value="data.cpDynamicPricingRule[1].max" />个时,</span
+          >当"穴位/经络/部位" &gt; <a-input placeholder="请输入" class="w-20 ml-2 mr-2" v-model:value="data.cpDynamicPricingRule![1].max" disabled />个时,</span
         >
         <a-select
-          v-model:value="data.cpDynamicPricingRule[1].priceType"
+          v-model:value="data.cpDynamicPricingRule![1].priceType"
           :options="[
             { label: '单价', value: 0, priceType: 0 },
             { label: '一口价', value: 1, priceType: 1 },
@@ -263,7 +398,7 @@ function handleSelect(value: string, node: any, extra: any) {
           placeholder="请选择"
         />
         <span>=</span>
-        <a-input v-model:value="data.cpDynamicPricingRule[1].price" style="width: 80px; margin: 0 4px" placeholder="请输入" />
+        <a-input v-model:value="data.cpDynamicPricingRule![1].price" style="width: 80px; margin: 0 4px" placeholder="请输入" />
         <span>元</span>
       </div>
     </div>
@@ -274,10 +409,12 @@ function handleSelect(value: string, node: any, extra: any) {
     <div class="form-row">
       <label>中药组成:</label>
       <div class="herb-list">
-        <template v-for="(herb, idx) in data.cpMedicines" :key="idx">
+        <template v-for="(herb, idx) in data.cpMedicines || []" :key="idx">
           <div class="herb-item">
             <button class="herb-remove" @click="removeHerb(idx)" type="button">×</button>
+            <!-- eslint-disable-next-line vue/no-mutating-props -->
             <RemoteSelect :load="cpMedicinesMethod" key-prop="name" v-model:value="herb.name" />
+            <!-- eslint-disable-next-line vue/no-mutating-props -->
             <a-input v-model:value="herb.dosage" class="herb-dosage" placeholder="剂量" />
             <span>g</span>
           </div>
@@ -286,7 +423,8 @@ function handleSelect(value: string, node: any, extra: any) {
       </div>
     </div>
     <div class="form-row">
-      <label>机构名称:</label>
+      <label><span class="required-star">*</span>机构名称:</label>
+      <!-- eslint-disable-next-line vue/no-mutating-props -->
       <a-tree-select
         v-model:value="data.institutionId"
         style="width: 400px"
@@ -299,7 +437,8 @@ function handleSelect(value: string, node: any, extra: any) {
       ></a-tree-select>
     </div>
     <div class="form-row">
-      <label>供应商:</label>
+      <label><span class="required-star">*</span>供应商:</label>
+      <!-- eslint-disable-next-line vue/no-mutating-props -->
       <a-select v-model:value="data.conditioningProgramSupplierId" :options="supplierOptions" placeholder="请选择供应商" style="width: 400px" allow-clear class="mr-10" />
       <a-checkbox v-model:checked="isOffline" style="margin-right: 8px" @change="toggleOnlineStatus" v-show="showOffLine"> 线下项目 </a-checkbox>
     </div>
@@ -356,6 +495,10 @@ html,
   font-weight: 500;
   color: #222;
   margin-right: 8px;
+  .required-star {
+    color: #ff4d4f;
+    margin-right: 4px;
+  }
 }
 .form-container {
   position: relative;
@@ -374,6 +517,10 @@ html,
     width: 110px;
     font-weight: 500;
     color: #222;
+    .required-star {
+      color: #ff4d4f;
+      margin-right: 4px;
+    }
   }
   input,
   select {
@@ -446,4 +593,8 @@ html,
   height: 36px;
   margin-right: 10px;
 }
+.required-star {
+  color: #ff4d4f;
+  margin-right: 4px;
+}
 </style>