Ver código fonte

四大变更增加是否滞后金额滞后至(月份)

xiongxing 2 semanas atrás
pai
commit
06ee055c72

+ 87 - 27
src/views/changes/ChangeFood/AddForm.vue

@@ -56,9 +56,7 @@
           </el-col>
           <el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
             <el-form-item prop="changeDate">
-              <template #label>
-                原餐饮费
-              </template>
+              <template #label> 原餐饮费 </template>
               <el-input v-model="dataForm.oldActualAmount" disabled />
             </el-form-item>
           </el-col>
@@ -100,10 +98,34 @@
                 active-text="是"
                 inactive-text="否"
               />
+
+              <span style="color: #666; font-size: 14px; margin-left: 5vw; margin-right: 10px"
+                >是否滞后</span
+              >
+              <el-switch
+                v-model="dataForm.isHysteresis"
+                size="default"
+                inline-prompt
+                active-text="是"
+                inactive-text="否"
+                @change="onHysteresisChange"
+              />
             </div>
           </el-col>
         </el-row>
 
+        <el-row v-if="dataForm.isHysteresis">
+          <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+            <el-form-item label="差额滞后至" prop="hysteresisMonth" required>
+              <TgDatePicker
+                v-model="dataForm.hysteresisMonth"
+                type="month"
+                placeholder="请选择年月"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
         <el-row v-if="dataForm.isDiscount">
           <el-col :xs="24" :sm="24" :md="24" :lg="9" :xl="9">
             <el-form-item label="折扣金额(元)" prop="discountAmount">
@@ -112,12 +134,12 @@
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="9" :xl="9">
             <el-form-item label="折扣率" prop="discount">
-              <TgInputNumber v-model="discount" @blur="handleBlur(dataForm, 2)" disabled/>
+              <TgInputNumber v-model="discount" @blur="handleBlur(dataForm, 2)" disabled />
             </el-form-item>
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6">
             <el-form-item label="折后价格" prop="actualAmount">
-              <span class="price">¥{{ dataForm.amount-discountAmount }}</span>
+              <span class="price">¥{{ dataForm.amount - discountAmount }}</span>
             </el-form-item>
           </el-col>
         </el-row>
@@ -129,7 +151,7 @@
             maxlength="200"
             :show-word-limit="true"
             type="textarea"
-            rows="3"
+            :rows="3"
           />
         </el-form-item>
 
@@ -205,7 +227,7 @@ let dataForm = ref({
   expectName: '',
   expectId: '',
   overheadChargeId: '',
-  expectOverheadChargeId:'',
+  expectOverheadChargeId: '',
   categoryName: '',
   originalAmount: 0,
   changeDate: formatTime(Date.now(), 'yyyy-MM-dd'),
@@ -213,6 +235,8 @@ let dataForm = ref({
   changeFiles: [],
   itemName: undefined,
   isDiscount: false,
+  isHysteresis: false,
+  hysteresisMonth: '',
   startTenantId: '',
   tenantId: ''
 })
@@ -224,16 +248,41 @@ const dataRule = reactive<FormRules>({
   //comeDate: [{required: true, message: '时间不能为空', trigger: 'blur'}],
   //discountBond: [isValidNumberDis()],
   //outPerson: [{required: true, message: '陪同人不能为空', trigger: 'blur'}],
-  reason: [{ required: true, message: '变更原因不能为空', trigger: 'blur' }]
+  reason: [{ required: true, message: '变更原因不能为空', trigger: 'blur' }],
+  hysteresisMonth: [
+    {
+      validator: (_rule, value, callback) => {
+        if (!dataForm.value.isHysteresis) {
+          callback()
+          return
+        }
+        if (!value) {
+          callback(new Error('请选择差额滞后月份'))
+        } else {
+          callback()
+        }
+      },
+      trigger: ['change', 'blur']
+    }
+  ]
 })
 
+const onHysteresisChange = (val: boolean) => {
+  if (!val) {
+    dataForm.value.hysteresisMonth = ''
+    formRef.value?.clearValidate(['hysteresisMonth'])
+  }
+}
+
 // 折扣和折扣率换算
 const handleBlur = (item: any, type = 0) => {
   if (type == 1) {
     // 折扣价格
     item.discountAmount = discountAmount.value
     item.actualAmount = item.amount - discountAmount.value
-    item.discount = item.discountAmount ? (1000 - (item.discountAmount / item.amount) * 1000) * 10 / 1000 : ''
+    item.discount = item.discountAmount
+      ? ((1000 - (item.discountAmount / item.amount) * 1000) * 10) / 1000
+      : ''
     discount.value = item.discount
   } else if (type == 2) {
     item.discount = discount.value
@@ -301,10 +350,17 @@ const handleChange = () => {
   // 在tree中找到这棵树的上一级
   let node = findTreeNode(treeList.value, item?.superiorsId, 'id', 'childrenList')
   // 找到对应的名称
-  const res = getParentNodesById(treeList.value, node.parentId, node.id, 'name', 'parentId', 'childrenList')
+  const res = getParentNodesById(
+    treeList.value,
+    node.parentId,
+    node.id,
+    'name',
+    'parentId',
+    'childrenList'
+  )
   // 只保留最后两位
-  if(res.length - 2 > 0){
-    for(let i = 0; i <= res.length - 2; i++){
+  if (res.length - 2 > 0) {
+    for (let i = 0; i <= res.length - 2; i++) {
       res.pop()
     }
   }
@@ -317,8 +373,6 @@ const handleChange = () => {
   //     dataForm.value.originalAmount = item.price
   //   }
   // })
-
-
 }
 
 // 是否打折
@@ -330,9 +384,9 @@ const handleSwicth = () => {
   discountAmount.value = ''
 }
 
-const disabledDate = (time) =>{
+const disabledDate = (time) => {
   const now = new Date()
-  const startOfMonth = new Date(now.getFullYear(), now.getMonth()-8, 1)
+  const startOfMonth = new Date(now.getFullYear(), now.getMonth() - 8, 1)
   const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 5, 0)
   return time < startOfMonth || time > endOfMonth
 }
@@ -348,7 +402,7 @@ const open = async (tId, id?: any, detail: boolean = false, status) => {
   await getTreeData()
   if (id) {
     try {
-      const res = await getCateringDetail(id, status,isDetail.value)
+      const res = await getCateringDetail(id, status, isDetail.value)
       dataForm.value = res
       dataForm.value.itemName = res.originalName
       dataForm.value.type = 6
@@ -356,9 +410,9 @@ const open = async (tId, id?: any, detail: boolean = false, status) => {
       dataForm.value.type = parseInt(res.type) //注意要用int类型才会正常展示
       dataForm.value.bedName = res.bedName
       dataForm.value.changeFiles = JSON.parse(res.changeFiles)
-      if(!res.startTenantId){
+      if (!res.startTenantId) {
         dataForm.value.startTenantId = getTenantId()
-      }else if(!dataForm.value.tenantId){
+      } else if (!dataForm.value.tenantId) {
         dataForm.value.tenantId = dataForm.value.startTenantId
       }
     } catch (err) {}
@@ -370,13 +424,16 @@ defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 /** 提交表单 */
 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
 const submitForm = async () => {
-  if(formLoading.value){
+  if (formLoading.value) {
     return
   }
 
   // 二次确认
   try {
-    await message.confirm('请认真核对变更生效日期,以及原餐饮价格和新餐饮价格!餐饮变更会影响餐饮费用!', '提示')
+    await message.confirm(
+      '请认真核对变更生效日期,以及原餐饮价格和新餐饮价格!餐饮变更会影响餐饮费用!',
+      '提示'
+    )
   } catch {
     return
   }
@@ -391,10 +448,11 @@ const submitForm = async () => {
     let dataFormUP = {
       ...dataForm.value,
       isDiscount: dataForm.value.isDiscount ? 1 : 0,
+      hysteresisMonth: dataForm.value.isHysteresis || '',
       changeFiles: JSON.stringify(dataForm.value.changeFiles) //改成字符串
     }
-    if(dataFormUP.isDiscount==0){
-      dataFormUP.actualAmount =  dataFormUP.amount
+    if (dataFormUP.isDiscount == 0) {
+      dataFormUP.actualAmount = dataFormUP.amount
     }
     const res = await cateringChangeCreate(dataFormUP)
     if (res) {
@@ -404,9 +462,9 @@ const submitForm = async () => {
       emit('success')
     }
   } finally {
-    setTimeout(()=>{
+    setTimeout(() => {
       formLoading.value = false
-    },500)
+    }, 500)
   }
 }
 
@@ -429,15 +487,17 @@ const resetForm = () => {
     expectId: '',
     originalAmount: 0,
     overheadChargeId: '',
-    expectOverheadChargeId:'',
+    expectOverheadChargeId: '',
     categoryName: '',
     changeDate: undefined,
     reason: undefined,
     changeFiles: [],
     itemName: undefined,
     isDiscount: false,
+    isHysteresis: false,
+    hysteresisMonth: '',
     startTenantId: '',
-    tenantId: '',
+    tenantId: ''
   }
   formRef.value?.resetFields()
 }

+ 186 - 69
src/views/elderly/elder/bed-change/ProcessForm.vue

@@ -11,7 +11,13 @@
       <el-row :gutter="20">
         <el-col :span="12" :xs="24">
           <el-form-item label="长者姓名" prop="elderlyId">
-            <SelectElder ref="selectElderRef" v-model="dataForm.elderlyId" @elder="handleSelectElder" type="1" :tId="dataForm.tenantId"/>
+            <SelectElder
+              ref="selectElderRef"
+              v-model="dataForm.elderlyId"
+              @elder="handleSelectElder"
+              type="1"
+              :tId="dataForm.tenantId"
+            />
           </el-form-item>
         </el-col>
         <el-col :span="12" :xs="24">
@@ -27,22 +33,22 @@
         <el-col :span="12" :xs="24">
           <el-form-item label="原床位类型" prop="overheadChargeId">
             <TgSelect
-                v-model="dataForm.overheadChargeId"
-                placeholder="请选择"
-                disabled
-                :list="bedList"
-                dict-label="chargeName"
-                dict-value="id"
-              >
-                <el-option v-for="t in bedList" :key="t.id" :label="t.chargeName" :value="t.id" />
-              </TgSelect>
+              v-model="dataForm.overheadChargeId"
+              placeholder="请选择"
+              disabled
+              :list="bedList"
+              dict-label="chargeName"
+              dict-value="id"
+            >
+              <el-option v-for="t in bedList" :key="t.id" :label="t.chargeName" :value="t.id" />
+            </TgSelect>
           </el-form-item>
         </el-col>
         <el-col :span="12" :xs="24">
-            <el-form-item label="变更生效日期" prop="changeDate">
-              <!-- :disabledDate="(arg) => disabledDate(arg)" -->
-              <TgDatePicker v-model="dataForm.changeDate" type="date" placeholder="变更生效日期" />
-            </el-form-item>
+          <el-form-item label="变更生效日期" prop="changeDate">
+            <!-- :disabledDate="(arg) => disabledDate(arg)" -->
+            <TgDatePicker v-model="dataForm.changeDate" type="date" placeholder="变更生效日期" />
+          </el-form-item>
         </el-col>
         <el-col :span="12" :xs="24">
           <el-form-item label="原床位价格" prop="actualAmount">
@@ -51,7 +57,13 @@
         </el-col>
         <el-col :span="12" :xs="24">
           <el-form-item label="新床位" prop="expectId">
-            <SelectRoom v-model="dataForm.expectId"  @bed="bedChange"  :disabled="!dataForm.elderlyId" status="0" :tId="dataForm.tenantId"/>
+            <SelectRoom
+              v-model="dataForm.expectId"
+              @bed="bedChange"
+              :disabled="!dataForm.elderlyId"
+              status="0"
+              :tId="dataForm.tenantId"
+            />
           </el-form-item>
         </el-col>
         <el-col :span="12" :xs="24">
@@ -100,19 +112,45 @@
         </el-col>
         <el-col :span="12" :xs="24">
           <el-form-item label="是否打折" prop="isDiscount">
-            <TgSwitch v-model="dataForm.isDiscount" @change="handleSwitch"/>
+            <TgSwitch v-model="dataForm.isDiscount" @change="handleSwitch" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12" :xs="24">
+          <el-form-item label="是否滞后">
+            <TgSwitch
+              v-model="dataForm.isHysteresis"
+              active-value="1"
+              inactive-value="0"
+              @change="handleHysteresisSwitch"
+            />
           </el-form-item>
         </el-col>
-        <template v-if="dataForm.isDiscount==1">
+        <el-col :span="12" :xs="24" v-if="dataForm.isHysteresis === '1'">
+          <el-form-item label="差额滞后至" prop="hysteresisMonth" required>
+            <TgDatePicker
+              v-model="dataForm.hysteresisMonth"
+              type="month"
+              placeholder="请选择差额滞后月份"
+            />
+          </el-form-item>
+        </el-col>
+        <template v-if="dataForm.isDiscount == 1">
           <el-col :span="12" :xs="24">
             <el-form-item label="折扣金额(元)" prop="discountAmount">
-              <TgInput v-model="discountAmount" append-text="¥" @blur="handleBlur(dataForm, 1)" style="width: 10vw;"/>
-              <el-text style="color: red;margin-left: 2vw">折后金额:{{dataForm.amount-discountAmount}}</el-text>
+              <TgInput
+                v-model="discountAmount"
+                append-text="¥"
+                @blur="handleBlur(dataForm, 1)"
+                style="width: 10vw"
+              />
+              <el-text style="color: red; margin-left: 2vw"
+                >折后金额:{{ dataForm.amount - discountAmount }}</el-text
+              >
             </el-form-item>
           </el-col>
           <el-col :span="12" :xs="24">
             <el-form-item label="折扣率" prop="discount">
-              <TgInputNumber v-model="discount" @blur="handleBlur(dataForm, 2)"  disabled/>
+              <TgInputNumber v-model="discount" @blur="handleBlur(dataForm, 2)" disabled />
             </el-form-item>
           </el-col>
         </template>
@@ -138,17 +176,22 @@
         <el-row :gutter="20">
           <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
             <el-form-item label="长者姓名" prop="elderlyId">
-              <SelectElder v-model="dataForm.elderlyId" type="1" :toggleType="isDetail"/>
+              <SelectElder v-model="dataForm.elderlyId" type="1" :toggleType="isDetail" />
             </el-form-item>
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
             <el-form-item label="证件号码" prop="idCard">
-              <TgInput v-model="dataForm.idCard" disabled :toggleType="isDetail"/>
+              <TgInput v-model="dataForm.idCard" disabled :toggleType="isDetail" />
             </el-form-item>
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
             <el-form-item label="变更生效日期" prop="changeDate">
-              <TgDatePicker v-model="dataForm.changeDate" type="date" placeholder="变更生效日期" :toggleType="isDetail"/>
+              <TgDatePicker
+                v-model="dataForm.changeDate"
+                type="date"
+                placeholder="变更生效日期"
+                :toggleType="isDetail"
+              />
             </el-form-item>
           </el-col>
         </el-row>
@@ -174,19 +217,19 @@
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
             <el-form-item label="床位号" prop="originalName">
-              <TgInput v-model="dataForm.originalName" :toggleType="isDetail"/>
+              <TgInput v-model="dataForm.originalName" :toggleType="isDetail" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
             <el-form-item label="床位价格" prop="originalAmount">
-              <TgInput v-model="dataForm.originalAmount" :toggleType="isDetail"/>
+              <TgInput v-model="dataForm.originalAmount" :toggleType="isDetail" />
             </el-form-item>
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
             <el-form-item label="是否打折" prop="originalIsDiscount">
-              <TgSwitch v-model="dataForm.originalIsDiscount" :toggleType="isDetail"/>
+              <TgSwitch v-model="dataForm.originalIsDiscount" :toggleType="isDetail" />
             </el-form-item>
           </el-col>
         </el-row>
@@ -212,7 +255,7 @@
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
             <el-form-item label="床位号" prop="expectId">
-              <TgInput v-model="dataForm.bedName" :toggleType="isDetail"/>
+              <TgInput v-model="dataForm.bedName" :toggleType="isDetail" />
             </el-form-item>
           </el-col>
         </el-row>
@@ -223,8 +266,19 @@
             </el-form-item>
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
-            <el-form-item :label="(diffValueStr(dataForm)==0?'差额':diffValueStr(dataForm)>0?'需补缴':'需退款')" prop="actualAmount">
-              <el-text style="font-weight: bold;color: red">{{ Math.abs(diffValueStr(dataForm)).toFixed(2) }}</el-text>
+            <el-form-item
+              :label="
+                diffValueStr(dataForm) == 0
+                  ? '差额'
+                  : diffValueStr(dataForm) > 0
+                    ? '需补缴'
+                    : '需退款'
+              "
+              prop="actualAmount"
+            >
+              <el-text style="font-weight: bold; color: red">{{
+                Math.abs(diffValueStr(dataForm)).toFixed(2)
+              }}</el-text>
             </el-form-item>
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
@@ -247,10 +301,36 @@
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
             <el-form-item label="是否打折" prop="originalIsDiscount">
-              <TgSwitch v-model="dataForm.originalIsDiscount" :toggleType="isDetail"/>
+              <TgSwitch v-model="dataForm.originalIsDiscount" :toggleType="isDetail" />
             </el-form-item>
           </el-col>
-          <el-col :span="6" :xs="24" v-show="dataForm.isDiscount==1">
+          <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
+            <el-form-item label="是否滞后">
+              <TgSwitch
+                :model-value="dataForm.hysteresisMonth ? '1' : '0'"
+                active-value="1"
+                inactive-value="0"
+                :toggleType="isDetail"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col
+            :xs="24"
+            :sm="24"
+            :md="24"
+            :lg="processType == 2 ? 24 : 8"
+            v-if="dataForm.hysteresisMonth"
+          >
+            <el-form-item label="滞后年月" prop="hysteresisMonth">
+              <TgDatePicker
+                v-model="dataForm.hysteresisMonth"
+                type="month"
+                placeholder="滞后年月"
+                :toggleType="isDetail"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6" :xs="24" v-show="dataForm.isDiscount == 1">
             <el-form-item label="折后价格" prop="actualAmount">
               <span class="price">{{ formatNum(dataForm.actualAmount) }}</span>
             </el-form-item>
@@ -258,7 +338,7 @@
         </el-row>
         <el-col :span="24">
           <el-form-item label="变更原因" prop="reason">
-            <TgTextarea v-model="dataForm.reason" :toggleType="isDetail"/>
+            <TgTextarea v-model="dataForm.reason" :toggleType="isDetail" />
           </el-form-item>
         </el-col>
         <el-col :span="24">
@@ -283,14 +363,17 @@ import { formatTime, getParentNodesById } from '@/utils'
 import { getIntDictOptions, DICT_TYPE, getDictOptions, getDictLabel } from '@/utils/dict'
 import { formatNum } from '@/utils/formatter'
 import { getBusinessId } from '@/api/elderly/common'
-import {getBedChangeRecordById, getBedChangeRecordElderlyById} from '@/api/elderly/elder/bed-change'
+import {
+  getBedChangeRecordById,
+  getBedChangeRecordElderlyById
+} from '@/api/elderly/elder/bed-change'
 import { bedChangeFormType } from '../types'
 import { getTenantId } from '@/utils/auth'
 defineOptions({ name: 'BedChangeProcessForm' })
 
 const formRef = ref() // 表单 Ref
 const selectElderRef = ref() // 表单 Ref
-const state = reactive<bedChangeFormType>({
+const state = reactive({
   dataForm: {
     id: '',
     elderlyId: '',
@@ -309,26 +392,46 @@ const state = reactive<bedChangeFormType>({
     discount: undefined,
     actualAmount: 0,
     isDiscount: '',
+    isHysteresis: '0',
     categoryName: '',
     originalAmount: '',
     originalIsDiscount: '',
+    hysteresisMonth: '',
     changeFiles: [],
     reason: '',
     startTenantId: '',
     tenantId: undefined
-  },
-  dataRule: {
-    elderlyId: [{ required: true, message: '长者不能为空', trigger: 'blur' }],
-    changeDate: [{ required: true, message: '变更生效日期不能为空', trigger: 'blur' }],
-    expectId: [{ required: true, message: '新床位不能为空', trigger: 'blur' }],
-    expectOverheadChargeId: [{ required: true, message: '床位类型不能为空', trigger: 'blur' }],
-    isPrivateRoom: [{ required: true, message: '是否包房不能为空', trigger: 'blur' }],
-    discountAmount: [{ required: true, message: '折扣金额不能为空', trigger: 'blur' }],
-    discount: [{ required: true, message: '折扣率不能为空', trigger: 'blur' }]
-  }
+  } as unknown as bedChangeFormType['dataForm']
+})
+const dataForm = toRef(state, 'dataForm')
+
+const dataRule = reactive<bedChangeFormType['dataRule']>({
+  elderlyId: [{ required: true, message: '长者不能为空', trigger: 'blur' }],
+  changeDate: [{ required: true, message: '变更生效日期不能为空', trigger: 'blur' }],
+  expectId: [{ required: true, message: '新床位不能为空', trigger: 'blur' }],
+  expectOverheadChargeId: [{ required: true, message: '床位类型不能为空', trigger: 'blur' }],
+  isPrivateRoom: [{ required: true, message: '是否包房不能为空', trigger: 'blur' }],
+  discountAmount: [{ required: true, message: '折扣金额不能为空', trigger: 'blur' }],
+  discount: [{ required: true, message: '折扣率不能为空', trigger: 'blur' }],
+  hysteresisMonth: [
+    {
+      validator: (_rule, value, callback) => {
+        if (dataForm.value.isHysteresis === '1') {
+          if (value === '' || value == null) {
+            callback(new Error('请选择差额滞后月份'))
+          } else {
+            callback()
+          }
+        } else {
+          callback()
+        }
+      },
+      trigger: 'change'
+    }
+  ]
 })
-const { dataForm, dataRule } = toRefs(state)
-const resetFormField =  reactive({ ...dataForm.value })
+
+const resetFormField = reactive({ ...dataForm.value })
 const loading = ref(false)
 const discount = ref()
 const discountAmount = ref()
@@ -336,12 +439,16 @@ const processStatus = ref('')
 
 const isDetail = ref(false)
 /** 打开弹窗 */
-const init = async (id, detail, status,elderly=undefined) => {
+const init = async (id, detail, status, elderly = undefined) => {
   dataForm.value.startTenantId = getTenantId()
   dataForm.value.tenantId = getTenantId()
   getTreeData()
   isDetail.value = detail
-  if(elderly){
+  if (!id) {
+    dataForm.value.isHysteresis = '0'
+    dataForm.value.hysteresisMonth = ''
+  }
+  if (elderly) {
     //等新接口,查询后赋值
     const item = await getBedChangeRecordElderlyById(elderly.elderId)
     dataForm.value.elderlyId = item.id
@@ -355,15 +462,15 @@ const init = async (id, detail, status,elderly=undefined) => {
   }
   //http://192.168.100.21:48080/admin-api/build/getBedList?bedName=&status=0&tenantIds=0&orgType=1
   if (id) {
-    const res = await getBedChangeRecordById(id, status,isDetail.value)
+    const res = await getBedChangeRecordById(id, status, isDetail.value)
     dataForm.value = res
     dataForm.value.changeFiles = res.changeFiles ? JSON.parse(res.changeFiles) : []
     discount.value = formatNum(res.discount)
     discountAmount.value = formatNum(res.discountAmount)
-    if(!res.startTenantId){
+    if (!res.startTenantId) {
       dataForm.value.startTenantId = getTenantId()
       dataForm.value.tenantId = getTenantId()
-    }else {
+    } else {
       dataForm.value.tenantId = dataForm.value.startTenantId
     }
     try {
@@ -376,8 +483,9 @@ const init = async (id, detail, status,elderly=undefined) => {
       dataForm.value.originalName = item.bedName
       dataForm.value.originalAmount = item.actualAmount
       dataForm.value.oldActualAmount = item.actualAmount
-    }catch (_){}
+    } catch (_) {}
 
+    dataForm.value.isHysteresis = res.hysteresisMonth ? '1' : '0'
   }
   getOverheadList()
 }
@@ -388,21 +496,23 @@ const submitForm = async () => {
   if (!formRef.value) return
   const valid = await formRef.value.validate()
   if (!valid) return
-  // 提交请求
+  const { isHysteresis: _uiHysteresis, ...rest } = dataForm.value
+  // 提交请求(不落库「是否滞后」,仅 hysteresisMonth)
   return {
     valid,
     dataForm: {
-      ...dataForm.value,
+      ...rest,
       changeFiles: JSON.stringify(dataForm.value.changeFiles),
-      type: 4 // 床位变更
+      type: 4, // 床位变更
+      hysteresisMonth: dataForm.value.isHysteresis === '1' ? dataForm.value.hysteresisMonth : ''
     }
   }
 }
 
-const diffValueStr = (dataForm) =>{
+const diffValueStr = (dataForm) => {
   try {
     return parseFloat((dataForm.actualAmount - dataForm.originalAmount).toFixed(2))
-  }catch (_) {}
+  } catch (_) {}
   return 0
 }
 
@@ -418,7 +528,6 @@ const bedChange = () => {
   //     dataForm.value.originalAmount = item.price
   //   }
   // })
-
 }
 
 // 项目类别
@@ -443,20 +552,20 @@ const handleChange = () => {
   // 找到对应的名称
   const res = getParentNodesById(treeList.value, node.parentId, node.id)
   // 只保留最后两位
-  if(res.length - 2 > 0){
-    for(let i = 0; i <= res.length - 2; i++){
+  if (res.length - 2 > 0) {
+    for (let i = 0; i <= res.length - 2; i++) {
       res.pop()
     }
   }
   dataForm.value.categoryName = res.reverse().join('-')
   // 如果没有打折
-  if(dataForm.value.isDiscount!=1){
+  if (dataForm.value.isDiscount != 1) {
     dataForm.value.actualAmount = dataForm.value.amount
-  }else{
+  } else {
     handleBlur(dataForm.value, 1)
   }
-  for (const item of bedList.value){
-    if(item.id==dataForm.value.expectOverheadChargeId){
+  for (const item of bedList.value) {
+    if (item.id == dataForm.value.expectOverheadChargeId) {
       dataForm.value.expectName = item.chargeName
       break
     }
@@ -472,13 +581,21 @@ const handleSwitch = () => {
   discountAmount.value = ''
 }
 
+const handleHysteresisSwitch = () => {
+  if (dataForm.value.isHysteresis !== '1') {
+    dataForm.value.hysteresisMonth = ''
+  }
+}
+
 // 折扣和折扣率换算
 const handleBlur = (item, type = 0) => {
   if (type == 1) {
     // 折扣价格
     item.discountAmount = discountAmount.value
     item.actualAmount = item.amount - discountAmount.value
-    item.discount = item.discountAmount ? (1000 - (item.discountAmount / item.amount) * 1000) * 10 / 1000 : ''
+    item.discount = item.discountAmount
+      ? ((1000 - (item.discountAmount / item.amount) * 1000) * 10) / 1000
+      : ''
     discount.value = item.discount
   } else if (type == 2) {
     item.discount = discount.value
@@ -506,8 +623,8 @@ const handleSelectElder = (item) => {
 }
 
 const handleChangeBed = () => {
-  for (const item of bedList.value){
-    if(item.id==dataForm.value.expectOverheadChargeId){
+  for (const item of bedList.value) {
+    if (item.id == dataForm.value.expectOverheadChargeId) {
       dataForm.value.expectName = item.chargeName
       break
     }
@@ -516,11 +633,11 @@ const handleChangeBed = () => {
 
 /** 重置表单 */
 const resetForm = () => {
-  dataForm.value = {...resetFormField}
+  dataForm.value = { ...resetFormField }
   formRef.value?.resetFields()
 }
 
-const disabledDate = (time) =>{
+const disabledDate = (time) => {
   const now = new Date()
   const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1)
   const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0)

+ 144 - 39
src/views/elderly/elder/nurse-change/ProcessForm.vue

@@ -10,7 +10,12 @@
       <el-row :gutter="20">
         <el-col :span="12" :xs="24">
           <el-form-item label="长者姓名" prop="elderlyId">
-            <SelectElder v-model="dataForm.elderlyId" type="2" @elder="handleSelectElder" :tId="dataForm.tenantId"/>
+            <SelectElder
+              v-model="dataForm.elderlyId"
+              type="2"
+              @elder="handleSelectElder"
+              :tId="dataForm.tenantId"
+            />
           </el-form-item>
         </el-col>
         <el-col :span="12" :xs="24">
@@ -95,16 +100,45 @@
             />
           </el-form-item>
         </el-col>
-        <template v-if="dataForm.isDiscount==1">
+        <el-col :span="12" :xs="24">
+          <el-form-item label="是否滞后">
+            <el-switch
+              v-model="dataForm.isHysteresis"
+              inline-prompt
+              active-text="是"
+              inactive-text="否"
+              :active-value="1"
+              :inactive-value="0"
+              @change="handleHysteresisSwitch"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12" :xs="24" v-if="dataForm.isHysteresis == 1">
+          <el-form-item label="差额滞后至" prop="hysteresisMonth" required>
+            <TgDatePicker
+              v-model="dataForm.hysteresisMonth"
+              type="month"
+              placeholder="请选择差额滞后月份"
+            />
+          </el-form-item>
+        </el-col>
+        <template v-if="dataForm.isDiscount == 1">
           <el-col :span="12" :xs="24">
             <el-form-item label="折扣金额(元)" prop="discountAmount">
-              <TgInput v-model="discountAmount" append-text="¥" @blur="handleBlur(dataForm, 1)" style="width: 10vw;"/>
-              <el-text style="color: red;margin-left: 2vw">折后金额:{{dataForm.amount-discountAmount}}</el-text>
+              <TgInput
+                v-model="discountAmount"
+                append-text="¥"
+                @blur="handleBlur(dataForm, 1)"
+                style="width: 10vw"
+              />
+              <el-text style="color: red; margin-left: 2vw"
+                >折后金额:{{ dataForm.amount - discountAmount }}</el-text
+              >
             </el-form-item>
           </el-col>
           <el-col :span="12" :xs="24">
             <el-form-item label="折扣率" prop="discount">
-              <TgInputNumber v-model="discount" @blur="handleBlur(dataForm, 2)" disabled/>
+              <TgInputNumber v-model="discount" @blur="handleBlur(dataForm, 2)" disabled />
             </el-form-item>
           </el-col>
         </template>
@@ -222,8 +256,15 @@
             </el-form-item>
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
-            <el-form-item :label="(diffValueStr(dataForm)==0?'':diffValueStr(dataForm)>0?'需补缴':'需退款')" prop="actualAmount">
-              <el-text style="font-weight: bold;color: red">{{ Math.abs(diffValueStr(dataForm)).toFixed(2) }}</el-text>
+            <el-form-item
+              :label="
+                diffValueStr(dataForm) == 0 ? '' : diffValueStr(dataForm) > 0 ? '需补缴' : '需退款'
+              "
+              prop="actualAmount"
+            >
+              <el-text style="font-weight: bold; color: red">{{
+                Math.abs(diffValueStr(dataForm)).toFixed(2)
+              }}</el-text>
             </el-form-item>
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
@@ -231,7 +272,39 @@
               <TgSwitch v-model="dataForm.isDiscount" />
             </el-form-item>
           </el-col>
-          <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8" v-show="dataForm.isDiscount==1">
+          <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 8">
+            <el-form-item label="是否滞后">
+              <TgSwitch
+                :model-value="dataForm.hysteresisMonth ? '1' : '0'"
+                active-value="1"
+                inactive-value="0"
+                :toggleType="isDetail"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col
+            :xs="24"
+            :sm="24"
+            :md="24"
+            :lg="processType == 2 ? 24 : 8"
+            v-if="dataForm.hysteresisMonth"
+          >
+            <el-form-item label="差额滞后至" prop="hysteresisMonth">
+              <TgDatePicker
+                v-model="dataForm.hysteresisMonth"
+                type="month"
+                placeholder="请选择差额滞后月份"
+                :toggleType="isDetail"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col
+            :xs="24"
+            :sm="24"
+            :md="24"
+            :lg="processType == 2 ? 24 : 8"
+            v-show="dataForm.isDiscount == 1"
+          >
             <el-form-item label="折后价格" prop="actualAmount">
               {{ formatNum(dataForm.actualAmount) }}
             </el-form-item>
@@ -291,7 +364,10 @@ const state = reactive<nurseChangeFormType>({
     changeDate: formatTime(Date.now(), 'yyyy-MM-dd'),
     associateId: '',
     isDiscount: '',
+    isHysteresis: 0,
+    hysteresisMonth: '',
     amount: 0,
+    oldActualAmount: 0,
     discountAmount: '',
     discount: undefined,
     actualAmount: 0,
@@ -301,7 +377,7 @@ const state = reactive<nurseChangeFormType>({
     reason: '',
     changeFiles: [],
     startTenantId: '', // 流程租户id
-    tenantId: undefined,
+    tenantId: undefined
   },
   dataRule: {
     elderlyId: [{ required: true, message: '长者不能为空', trigger: 'blur' }],
@@ -310,11 +386,27 @@ const state = reactive<nurseChangeFormType>({
     expectOverheadChargeId: [{ required: true, message: '护理标准不能为空', trigger: 'blur' }],
     // associateId: [{ required: true, message: '阶段评估不能为空', trigger: 'blur' }],
     discountAmount: [{ required: true, message: '折扣金额不能为空', trigger: 'blur' }],
-    discount: [{ required: true, message: '折扣率不能为空', trigger: 'blur' }]
+    discount: [{ required: true, message: '折扣率不能为空', trigger: 'blur' }],
+    hysteresisMonth: [
+      {
+        validator: (_rule, value, callback) => {
+          if (state.dataForm.isHysteresis == 1) {
+            if (value === '' || value == null) {
+              callback(new Error('请选择差额滞后月份'))
+            } else {
+              callback()
+            }
+          } else {
+            callback()
+          }
+        },
+        trigger: 'change'
+      }
+    ]
   }
 })
 const { dataForm, dataRule } = toRefs(state)
-const resetFormField =  reactive({ ...dataForm.value })
+const resetFormField = reactive({ ...dataForm.value })
 const loading = ref(false)
 const discountAmount = ref()
 const discount = ref()
@@ -326,29 +418,31 @@ const init = async (id, detail, status) => {
   await getTreeData()
   await getNurseLevelList()
   isDetail.value = detail
+  if (!id) {
+    dataForm.value.isHysteresis = 0
+    dataForm.value.hysteresisMonth = ''
+  }
   if (id) {
-    const res = await getNurseChangeRecordById(id, status,isDetail.value)
+    const res = await getNurseChangeRecordById(id, status, isDetail.value)
     dataForm.value = res
     dataForm.value.changeFiles = res.changeFiles ? JSON.parse(res.changeFiles) : []
     dataForm.value.associateId = res.evaluationProcessId
+    dataForm.value.isHysteresis = res.hysteresisMonth ? 1 : 0
     discount.value = formatNum(res.discount)
     discountAmount.value = formatNum(res.discountAmount)
     syntheticAbilityId.value = res.syntheticAbilityId
     await getEvaluation()
     active.value = getSyntheticAbilityName(res.totalScore)
-    if(!res.startTenantId){
+    if (!res.startTenantId) {
       dataForm.value.startTenantId = getTenantId()
-    }else {
+    } else {
       dataForm.value.tenantId = dataForm.value.startTenantId
     }
-
   }
- await getOverheadList()
-  if(id){
+  await getOverheadList()
+  if (id) {
     handleChange(1)
-
   }
-
 }
 
 const submitForm = async () => {
@@ -356,12 +450,14 @@ const submitForm = async () => {
   if (!formRef.value) return
   const valid = await formRef.value.validate()
   if (!valid) return
+  const { isHysteresis: _uiHysteresis, ...rest } = dataForm.value
   return {
     valid,
     dataForm: {
-      ...dataForm.value,
+      ...rest,
       changeFiles: JSON.stringify(dataForm.value.changeFiles),
-      type: 5 // 护理变更
+      type: 5, // 护理变更
+      hysteresisMonth: dataForm.value.isHysteresis == 1 ? dataForm.value.hysteresisMonth ?? '' : ''
     }
   }
 }
@@ -394,10 +490,13 @@ const getEvaluation = async () => {
   evaluationList.value = res
 
   // 获取对应的分数段
-  const result = res[0] && res[0].evaluationProcessId ? await getEvaluationProcessConfigList({
-    evaluationProcessId: res[0].evaluationProcessId
-  }) : []
-  const arr = [...result, {propertiesName: '未评估'}]
+  const result =
+    res[0] && res[0].evaluationProcessId
+      ? await getEvaluationProcessConfigList({
+          evaluationProcessId: res[0].evaluationProcessId
+        })
+      : []
+  const arr = [...result, { propertiesName: '未评估' }]
   // 找到对应的分数段
   if (res.totalScore && res.totalScore >= 0 && res.syntheticAbilityInfoList.length) {
     for (let i = 0; i < arr.length; i++) {
@@ -411,10 +510,10 @@ const getEvaluation = async () => {
   }
 }
 
-const diffValueStr = (dataForm) =>{
+const diffValueStr = (dataForm) => {
   try {
     return parseFloat((dataForm.actualAmount - dataForm.originalAmount).toFixed(2))
-  }catch (_) {}
+  } catch (_) {}
   return 0
 }
 
@@ -440,7 +539,7 @@ const getTreeData = async () => {
 }
 
 // 护理标准
-const handleChange = (type=2) => {
+const handleChange = (type = 2) => {
   dataForm.value.expectOverheadChargeId = dataForm.value.expectId
   const item = nurseList.value.find((item) => item.id == dataForm.value.expectId)
   dataForm.value.expectName = item?.chargeName
@@ -450,17 +549,16 @@ const handleChange = (type=2) => {
   // 找到对应的名称
   const res = getParentNodesById(treeList.value, node.parentId, node.id)
   // 只保留最后两位
-  if(res.length - 2 > 0){
-    for(let i = 0; i <= res.length - 2; i++){
+  if (res.length - 2 > 0) {
+    for (let i = 0; i <= res.length - 2; i++) {
       res.pop()
     }
   }
   dataForm.value.categoryName = res.reverse().join('-')
-  if(type!=1){
+  if (type != 1) {
     handleSwicth()
   }
 
-
   // nurseList.value.map((item)=>{
   //   if(item.id==overheadChargeId){
   //     dataForm.value.originalAmount = item.price
@@ -468,21 +566,22 @@ const handleChange = (type=2) => {
   // })
 
   // 如果没有打折
-  if(dataForm.value.isDiscount!=1){
+  if (dataForm.value.isDiscount != 1) {
     dataForm.value.actualAmount = dataForm.value.amount
-  }else{
+  } else {
     handleBlur(dataForm.value, 1)
   }
 }
 
 // 折扣和折扣率换算
 const handleBlur = (item, type = 0) => {
-
   if (type == 1) {
     // 折扣价格
     item.discountAmount = discountAmount.value
     item.actualAmount = item.amount - discountAmount.value
-    item.discount = item.discountAmount ? (1000 - (item.discountAmount / item.amount) * 1000) * 10 / 1000 : ''
+    item.discount = item.discountAmount
+      ? ((1000 - (item.discountAmount / item.amount) * 1000) * 10) / 1000
+      : ''
     discount.value = item.discount
   } else if (type == 2) {
     item.discount = discount.value
@@ -499,14 +598,20 @@ const handleBlur = (item, type = 0) => {
 
 // 是否打折
 const handleSwicth = () => {
-  if(!isDetail.value){
+  if (!isDetail.value) {
     dataForm.value.discountAmount = ''
     dataForm.value.actualAmount = 0
     dataForm.value.discount = undefined
     discount.value = undefined
     discountAmount.value = ''
   }
+}
 
+const handleHysteresisSwitch = () => {
+  if (dataForm.value.isHysteresis != 1) {
+    dataForm.value.hysteresisMonth = ''
+    formRef.value?.clearValidate(['hysteresisMonth'])
+  }
 }
 
 //let overheadChargeId = 0
@@ -527,7 +632,7 @@ const handleSelectElder = (item) => {
 
 /** 重置表单 */
 const resetForm = () => {
-  dataForm.value = {...resetFormField}
+  dataForm.value = { ...resetFormField }
   formRef.value?.resetFields()
 }
 
@@ -556,7 +661,7 @@ const getProcess = async (id, type, status) => {
   processType.value = type
 }
 
-const disabledDate = (time) =>{
+const disabledDate = (time) => {
   const now = new Date()
   const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1)
   const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0)

+ 110 - 24
src/views/elderly/elder/price-change/ProcessForm.vue

@@ -11,28 +11,69 @@
       <el-row :gutter="20">
         <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 12">
           <el-form-item label="长者姓名" prop="elderlyId">
-            <SelectElder v-model="dataForm.elderlyId" type="2" @elder="handleSelectElder" :toggleType="isDetail" :tId="dataForm.tenantId"/>
+            <SelectElder
+              v-model="dataForm.elderlyId"
+              type="2"
+              @elder="handleSelectElder"
+              :toggleType="isDetail"
+              :tId="dataForm.tenantId"
+            />
           </el-form-item>
         </el-col>
         <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 12">
           <el-form-item label="身份证号" prop="idCard">
-            <TgInput v-model="dataForm.idCard" disabled :toggleType="isDetail"/>
+            <TgInput v-model="dataForm.idCard" disabled :toggleType="isDetail" />
           </el-form-item>
         </el-col>
         <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 12">
           <el-form-item label="变更生效日期" prop="changeDate">
             <!--  :disabledDate="(arg) => disabledDate(arg)" -->
-            <TgDatePicker v-model="dataForm.changeDate" type="date" placeholder="变更生效日期" :toggleType="isDetail"/>
+            <TgDatePicker
+              v-model="dataForm.changeDate"
+              type="date"
+              placeholder="变更生效日期"
+              :toggleType="isDetail"
+            />
           </el-form-item>
         </el-col>
         <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 12">
           <el-form-item label="床位号" prop="bedName">
-            <TgInput v-model="dataForm.bedName" disabled :toggleType="isDetail"/>
+            <TgInput v-model="dataForm.bedName" disabled :toggleType="isDetail" />
+          </el-form-item>
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="processType == 2 ? 24 : 12">
+          <el-form-item label="是否滞后">
+            <el-switch
+              v-model="dataForm.isHysteresis"
+              inline-prompt
+              active-text="是"
+              inactive-text="否"
+              :active-value="1"
+              :inactive-value="0"
+              :disabled="isDetail"
+              @change="handleHysteresisSwitch"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col
+          :xs="24"
+          :sm="24"
+          :md="24"
+          :lg="processType == 2 ? 24 : 12"
+          v-show="dataForm.isHysteresis == 1"
+        >
+          <el-form-item label="差额滞后至" prop="hysteresisMonth" required>
+            <TgDatePicker
+              v-model="dataForm.hysteresisMonth"
+              type="month"
+              placeholder="请选择差额滞后月份"
+              :toggleType="isDetail"
+            />
           </el-form-item>
         </el-col>
         <el-col :span="24">
           <el-form-item label="变更原因" prop="reason">
-            <TgTextarea v-model="dataForm.reason" :toggleType="isDetail"/>
+            <TgTextarea v-model="dataForm.reason" :toggleType="isDetail" />
           </el-form-item>
         </el-col>
         <el-col :span="24">
@@ -50,10 +91,22 @@
     <div class="info">
       <div class="info-title">变更项目</div>
       <span class="right">
-        <el-button type="primary" @click="handleAdd" link v-if="!isDetail" :disabled="!dataForm.elderlyId">
+        <el-button
+          type="primary"
+          @click="handleAdd"
+          link
+          v-if="!isDetail"
+          :disabled="!dataForm.elderlyId"
+        >
           <Icon icon="ep:zoom-in" class="mr-5px" />添加变更项
         </el-button>
-        <el-button type="warning" @click="handleDelAll" link v-if="!isDetail" :disabled="!dataForm.elderlyId">
+        <el-button
+          type="warning"
+          @click="handleDelAll"
+          link
+          v-if="!isDetail"
+          :disabled="!dataForm.elderlyId"
+        >
           <Icon icon="ep:delete" class="mr-5px" />全部移出
         </el-button>
       </span>
@@ -120,7 +173,7 @@
         </el-table-column>
         <el-table-column prop="amount" label="差额(元)">
           <template #default="scope">
-           <view>{{diffValueStr(scope.row)}}</view>
+            <view>{{ diffValueStr(scope.row) }}</view>
           </template>
         </el-table-column>
       </el-table>
@@ -136,7 +189,7 @@ import { getBusinessId } from '@/api/elderly/common'
 import { getPriceDetail } from '@/api/elderly/elder/price-change'
 import { priceChangeFormType } from '../types'
 import { tableHeaderColor } from '@/utils/table'
-import {View} from "@element-plus/icons-vue";
+import { View } from '@element-plus/icons-vue'
 defineOptions({ name: 'PriceChangeProcessForm' })
 
 const formRef = ref() // 表单 Ref
@@ -148,6 +201,8 @@ const state = reactive<priceChangeFormType>({
     idCard: '',
     bedName: '',
     changeDate: formatTime(Date.now(), 'yyyy-MM-dd'),
+    isHysteresis: 0,
+    hysteresisMonth: '',
     reason: '',
     changeFiles: [],
     priceChangeList: [],
@@ -155,21 +210,43 @@ const state = reactive<priceChangeFormType>({
   },
   dataRule: {
     elderlyId: [{ required: true, message: '长者不能为空', trigger: 'blur' }],
-    changeDate: [{ required: true, message: '变更日期不能为空', trigger: 'blur' }]
+    changeDate: [{ required: true, message: '变更日期不能为空', trigger: 'blur' }],
+    hysteresisMonth: [
+      {
+        validator: (_rule, value, callback) => {
+          if (state.dataForm.isHysteresis == 1) {
+            if (value === '' || value == null) {
+              callback(new Error('请选择差额滞后月份'))
+            } else {
+              callback()
+            }
+          } else {
+            callback()
+          }
+        },
+        trigger: 'change'
+      }
+    ]
   }
 })
 const { dataForm, dataRule } = toRefs(state)
-const resetFormField =  reactive({ ...dataForm.value })
+const resetFormField = reactive({ ...dataForm.value })
 const loading = ref(false)
 
 const isDetail = ref(false)
 /** 打开弹窗 */
 const init = async (id, detail, status) => {
   isDetail.value = detail
+  if (!id) {
+    dataForm.value.isHysteresis = 0
+    dataForm.value.hysteresisMonth = ''
+  }
   if (id) {
     const res = await getPriceDetail(id, status)
     dataForm.value = res
     dataForm.value.changeFiles = res.changeFiles ? JSON.parse(res.changeFiles) : []
+    dataForm.value.isHysteresis = res.hysteresisMonth ? 1 : 0
+    dataForm.value.hysteresisMonth = res.hysteresisMonth ?? ''
     await getTreeData()
     // 根据表格里的数据加list
     nextTick(() => {
@@ -182,14 +259,14 @@ const init = async (id, detail, status) => {
 
 const diffValueStr = (item) => {
   try {
-    let value =  parseFloat((item.amount - item.originalAmount).toFixed(2))
-    if(value>=0){
+    let value = parseFloat((item.amount - item.originalAmount).toFixed(2))
+    if (value >= 0) {
       return `${value}(补)`
-    }else {
+    } else {
       return `${value}(退)`
     }
-  }catch (_) {}
-  return "0"
+  } catch (_) {}
+  return '0'
 }
 
 /** 提交表单 */
@@ -199,16 +276,25 @@ const submitForm = async () => {
   if (!formRef.value) return
   const valid = await formRef.value.validate()
   if (!valid) return
+  const { isHysteresis: _isHysteresis, ...rest } = dataForm.value
   return {
     valid,
     dataForm: {
-      ...dataForm.value,
+      ...rest,
       changeFiles: JSON.stringify(dataForm.value.changeFiles),
-      type: 7
+      type: 7,
+      hysteresisMonth: dataForm.value.isHysteresis == 1 ? dataForm.value.hysteresisMonth ?? '' : ''
     }
   }
 }
 
+const handleHysteresisSwitch = () => {
+  if (dataForm.value.isHysteresis != 1) {
+    dataForm.value.hysteresisMonth = ''
+    formRef.value?.clearValidate(['hysteresisMonth'])
+  }
+}
+
 const handleAdd = () => {
   dataForm.value.priceChangeList.push({
     originalId: '',
@@ -232,7 +318,7 @@ const handleDelete = (index) => {
 const treeList = ref()
 const defaultProps = ref({
   label: 'name',
-  value: 'chargeCategoryId',
+  value: 'chargeCategoryId'
 })
 const getTreeData = async () => {
   try {
@@ -258,8 +344,8 @@ const handleChangeCategory = async (item, type: boolean = true) => {
 }
 const getNameList = async (item) => {
   try {
-    const obj = treeList.value.find(t=>t.chargeCategoryId == item.chargeCategoryId)
-    item.list = [{label: obj.chargeName, value: obj.overheadChargeId, price: obj.amount}]
+    const obj = treeList.value.find((t) => t.chargeCategoryId == item.chargeCategoryId)
+    item.list = [{ label: obj.chargeName, value: obj.overheadChargeId, price: obj.amount }]
   } finally {
   }
 }
@@ -269,7 +355,7 @@ const handleChange = (item: any) => {
   item.originalAmount = Number(obj?.price)
   item.originalName = obj.label
   // 在tree中找到这棵树的上一级
-  let node = treeList.value.find(t=>t.chargeCategoryId == item.chargeCategoryId)
+  let node = treeList.value.find((t) => t.chargeCategoryId == item.chargeCategoryId)
   // // 找到对应的名称
   item.categoryName = node.name + '-' + obj.label
 }
@@ -284,7 +370,7 @@ const handleSelectElder = (item) => {
 
 /** 重置表单 */
 const resetForm = () => {
-  dataForm.value = {...resetFormField}
+  dataForm.value = { ...resetFormField }
   formRef.value?.resetFields()
 }
 
@@ -295,7 +381,7 @@ const getProcess = async (id, type, status) => {
   processType.value = type
 }
 
-const disabledDate = (time) =>{
+const disabledDate = (time) => {
   const now = new Date()
   const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1)
   const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0)

+ 12 - 0
src/views/elderly/elder/types.ts

@@ -366,6 +366,10 @@ export interface priceChangeFormType {
     idCard: string
     bedName: string
     changeDate: string
+    /** 仅前端:与 el-switch 一致;提交不传,回显由 hysteresisMonth 推导 */
+    isHysteresis: number
+    /** 滞后年月 YYYY-MM;接口仅返回/提交该字段 */
+    hysteresisMonth?: string
     reason: string
     changeFiles: {
       fileUrl: string
@@ -402,6 +406,10 @@ export interface nurseChangeFormType {
     changeDate: string
     associateId: string
     isDiscount: string
+    /** 仅前端:是否滞后(与 el-switch 一致);提交不传后端,回显由 hysteresisMonth 推导 */
+    isHysteresis?: number | string
+    /** 滞后年月(YYYY-MM);接口仅返回/提交该字段 */
+    hysteresisMonth?: string
     amount: number
     oldActualAmount: number
     discountAmount: string
@@ -444,9 +452,13 @@ export interface bedChangeFormType {
     actualAmount: number
     oldActualAmount: number
     isDiscount: string
+    /** 仅前端:是否滞后(与 TgSwitch 一致);接口不落库,回显由 hysteresisMonth 推导 */
+    isHysteresis?: string
     categoryName: string
     originalAmount: string
     originalIsDiscount: string
+    /** 滞后年月(YYYY-MM),接口仅返回/提交该字段;“是否滞后”由是否有值推导 */
+    hysteresisMonth?: string
     changeFiles: {
       fileUrl: string
       fileName: string

+ 101 - 66
src/views/elderly/fee/bill-pay/unpay-preview.vue

@@ -9,7 +9,7 @@
   >
     <div class="first" id="printTab1">
       <div class="header">
-        <p class="title" style="font-size: 18px;">缴费通知单</p>
+        <p class="title" style="font-size: 18px">缴费通知单</p>
         <div class="info-wrap" style="margin-top: -4px">
           <span><b>机构:</b> {{ tenantName }}</span>
           <span><b>姓名:</b> {{ dataForm.elderName }}</span>
@@ -20,23 +20,27 @@
           <span><b>性别:</b> {{ getDictLabel(DICT_TYPE.SYSTEM_USER_SEX, dataForm.elderSex) }}</span>
           <span><b>经手人:</b> {{ dataForm.createdBy }}</span>
         </div>
-<!--        <div class="info-wrap">-->
-<!--          <span><b>账单月:</b> {{ dataForm.billingMonth }}</span>-->
-          <!-- <span><b>账单总额:</b> {{ billTotalPrice }}元</span> -->
-          <!-- <span><b>长护险:</b> {{ formatNum(longTermAmount) }}元</span> -->
-<!--          <span><b>应缴:</b> {{ formatNum(unPayTotal) }}元</span>-->
-<!--          <span><b>发票号:</b> {{ dataForm.invoiceNumber }}</span>-->
-<!--        </div>-->
-<!--        <div class="info-wrap">-->
-          <!-- <span><b>已缴费用:</b> {{ formatNum(payTotal) }}元</span> -->
-<!--          <span><b>打印时间:</b> {{ dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss') }}</span>-->
-<!--        </div>-->
+        <!--        <div class="info-wrap">-->
+        <!--          <span><b>账单月:</b> {{ dataForm.billingMonth }}</span>-->
+        <!-- <span><b>账单总额:</b> {{ billTotalPrice }}元</span> -->
+        <!-- <span><b>长护险:</b> {{ formatNum(longTermAmount) }}元</span> -->
+        <!--          <span><b>应缴:</b> {{ formatNum(unPayTotal) }}元</span>-->
+        <!--          <span><b>发票号:</b> {{ dataForm.invoiceNumber }}</span>-->
+        <!--        </div>-->
+        <!--        <div class="info-wrap">-->
+        <!-- <span><b>已缴费用:</b> {{ formatNum(payTotal) }}元</span> -->
+        <!--          <span><b>打印时间:</b> {{ dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss') }}</span>-->
+        <!--        </div>-->
       </div>
-      <el-divider style="margin-top: 0px"/>
+      <el-divider style="margin-top: 0px" />
       <div class="content">
-<!--        <p class="info">以下是账单明细</p>-->
+        <!--        <p class="info">以下是账单明细</p>-->
         <div class="flex">
-          <b>{{ dataForm.description ? tTitle + '(' + dataForm.description + ')' : tTitle + '(' + bTitle + ')' }}</b>
+          <b>{{
+            dataForm.description
+              ? tTitle + '(' + dataForm.description + ')'
+              : tTitle + '(' + bTitle + ')'
+          }}</b>
         </div>
         <table style="width: 100%" border="2">
           <tr align="center">
@@ -46,9 +50,11 @@
             <!-- <td>单价(元/月)</td>
             <td>数量</td> -->
             <td>金额(元)</td>
+            <td>缴费状态</td>
+            <td>已缴金额(元)</td>
             <td>费用发生时间</td>
-<!--            <td>缴费时间</td>-->
-<!--            <td>缴费状态</td>-->
+            <!--            <td>缴费时间</td>-->
+            <!--            <td>缴费状态</td>-->
             <td>备注</td>
           </tr>
           <tr v-for="(item, index) in dataForm.items" :key="index" align="center">
@@ -58,9 +64,11 @@
             <!-- <td>{{ calcActualPrice(item) }}</td>
             <td>{{ item.count }}</td> -->
             <td>{{ calcTotalPrice(item) }}</td>
+            <td>{{ getDictLabel(DICT_TYPE.PAY_TYPE, item.payStatus) }}</td>
+            <td>{{ item.payAmount ?? 0 }}元</td>
             <td>{{ formatStartDate(item) }}</td>
-<!--            <td>{{ formatTime(item.payTime, 'yyyy-MM-dd HH:mm:ss') }}</td>-->
-<!--            <td>{{ getDictLabel(DICT_TYPE.PAY_TYPE, item.payStatus) }}</td>-->
+            <!--            <td>{{ formatTime(item.payTime, 'yyyy-MM-dd HH:mm:ss') }}</td>-->
+            <!--            <td>{{ getDictLabel(DICT_TYPE.PAY_TYPE, item.payStatus) }}</td>-->
             <td>{{ item.description }}</td>
           </tr>
           <tr align="center">
@@ -125,21 +133,28 @@ const fixed2Num = computed(() => {
 const open = async (id) => {
   dialogVisible.value = true
   const res = await getExpenseOrderDetail(id)
-  res.items = res.items.filter(item=> (item.expenseSource == 'long_term_care_insurance' || item.payStatus == 0) && item.isShow == 1)
+  res.items = res.items.filter(
+    (item) =>
+      (item.expenseSource == 'long_term_care_insurance' ||
+        item.payStatus == 0 ||
+        item.payStatus == 1 ||
+        item.payStatus == 2) &&
+      item.isShow == 1
+  )
   let flag = false
   dataForm.value = res
   res.items.map((item) => {
-    if(item.expenseSource == 'long_term_care_insurance'){
+    if (item.expenseSource == 'long_term_care_insurance') {
       longTermAmount.value += item.actualPrice
       item.payStatus = 0
       flag = true
       // 遍历长护险
-      res.expenseSubsidyDO.map(d => {
-        if(Math.abs(d.id) ==  Math.abs(item.sourceExpenseItemId||0)){
+      res.expenseSubsidyDO.map((d) => {
+        if (Math.abs(d.id) == Math.abs(item.sourceExpenseItemId || 0)) {
           item.createdTime = d.month
           item.description = d.remarks
-          if(!item.itemCategoryName){
-            item.itemCategoryName="长护险"
+          if (!item.itemCategoryName) {
+            item.itemCategoryName = '长护险'
           }
         }
       })
@@ -148,13 +163,17 @@ const open = async (id) => {
     if (item.payStatus == 0) {
       // 入院账单且isMonthlyExpense=1且入院向上取整
       if (dataForm.value.type == '1' && item.isMonthlyExpense == 1) {
-        if(settingStore.getAdmissionBill == 2){ // 向上取整
+        if (settingStore.getAdmissionBill == 2) {
+          // 向上取整
           unPayTotal.value += Number(formatCeil(item.totalAmount))
-        }else if(settingStore.getAdmissionBill == 3){ // 四舍五入保留两位
+        } else if (settingStore.getAdmissionBill == 3) {
+          // 四舍五入保留两位
           unPayTotal.value += Number(item.roundTwoDecimalAmount)
-        }else if(settingStore.getAdmissionBill == 4){ // 四舍五入保留整数
+        } else if (settingStore.getAdmissionBill == 4) {
+          // 四舍五入保留整数
           unPayTotal.value += Number(item.roundAmount)
-        }else{ // 应收
+        } else {
+          // 应收
           unPayTotal.value += Number(formatNum(item.totalAmount))
         }
       } else {
@@ -170,16 +189,20 @@ const open = async (id) => {
     } else if (item.payStatus == 1) {
       // 判断入院账单且isMonthlyExpense=1且是否有做其他设置
       if (dataForm.value.type == '1' && item.isMonthlyExpense == 1) {
-        if(settingStore.getAdmissionBill == 2){ // 向上取整
+        if (settingStore.getAdmissionBill == 2) {
+          // 向上取整
           payTotal.value += Number(formatCeil(item.totalAmount))
-        }else if(settingStore.getAdmissionBill == 3){ // 四舍五入保留两位
+        } else if (settingStore.getAdmissionBill == 3) {
+          // 四舍五入保留两位
           payTotal.value += Number(item.roundTwoDecimalAmount)
-        }else if(settingStore.getAdmissionBill == 4){ // 四舍五入取整
+        } else if (settingStore.getAdmissionBill == 4) {
+          // 四舍五入取整
           payTotal.value += Number(item.roundAmount)
-        }else{ // 应收
+        } else {
+          // 应收
           payTotal.value += Number(formatNum(item.totalAmount))
         }
-      }else{
+      } else {
         if (rounding.value) {
           // 取整
           payTotal.value += item.roundAmount
@@ -195,17 +218,17 @@ const open = async (id) => {
   })
 
   // 有长护险
-  if(!flag){
+  if (!flag) {
     if (res.expenseSubsidyDO && res.expenseSubsidyDO.length) {
       let num = 0
-      res.expenseSubsidyDO.map(item=>{
+      res.expenseSubsidyDO.map((item) => {
         num += item.amount
 
         dataForm.value.items.push({
-          expenseSource:'long_term_care_insurance',
+          expenseSource: 'long_term_care_insurance',
           itemCategoryName: '长护险',
           itemName: '长护险抵扣',
-          description: item.remarks ? item.remarks :  item.month + '长护险抵扣',
+          description: item.remarks ? item.remarks : item.month + '长护险抵扣',
           roundAmount: -item.amount,
           roundTwoDecimalAmount: -item.amount,
           totalAmount: -item.amount,
@@ -279,24 +302,28 @@ const calcActualPrice = (item) => {
 }
 
 // 入院账单费用计算
-const caclAdminssionTotalPrice = computed(()=>{
+const caclAdminssionTotalPrice = computed(() => {
   let num = 0
-  dataForm.value.items.map(item=>{
-    if(item.isMonthlyExpense == 1){
-      if(settingStore.getAdmissionBill == 2){ // 向上取整
+  dataForm.value.items.map((item) => {
+    if (item.isMonthlyExpense == 1) {
+      if (settingStore.getAdmissionBill == 2) {
+        // 向上取整
         num += Number(formatCeil(item.totalAmount))
-      }else if(settingStore.getAdmissionBill == 3){ // 四舍五入保留两位
+      } else if (settingStore.getAdmissionBill == 3) {
+        // 四舍五入保留两位
         num += Number(formatNum(item.roundTwoDecimalAmount))
-      }else if(settingStore.getAdmissionBill == 4){ // 四舍五入去哼
+      } else if (settingStore.getAdmissionBill == 4) {
+        // 四舍五入去哼
         num += Number(formatNum(item.roundAmount))
-      }else{ // 应收
+      } else {
+        // 应收
         num += Number(formatNum(item.totalAmount))
       }
-    }else{
+    } else {
       if (rounding.value) {
         num += Number(formatNum(item.roundAmount))
       } else if (fixed2Num.value) {
-       num += Number(formatNum(item.roundTwoDecimalAmount))
+        num += Number(formatNum(item.roundTwoDecimalAmount))
       } else {
         num += Number(formatNum(item.totalAmount))
       }
@@ -308,16 +335,20 @@ const caclAdminssionTotalPrice = computed(()=>{
 // 总额
 const calcTotalPrice = (item) => {
   if (dataForm.value.type == '1' && item.isMonthlyExpense == 1) {
-    if(settingStore.getAdmissionBill == 2){ // 向上取整
+    if (settingStore.getAdmissionBill == 2) {
+      // 向上取整
       return formatCeil(item.totalAmount)
-    }else if(settingStore.getAdmissionBill == 3){ // 四舍五入保留两位
+    } else if (settingStore.getAdmissionBill == 3) {
+      // 四舍五入保留两位
       return formatNum(item.roundTwoDecimalAmount)
-    }else if(settingStore.getAdmissionBill == 4){ // 四舍五入保留整数
+    } else if (settingStore.getAdmissionBill == 4) {
+      // 四舍五入保留整数
       return formatNum(item.roundAmount)
-    }else{ // 应收
+    } else {
+      // 应收
       return formatNum(item.totalAmount)
     }
-  }else if(item.expenseSource == 'long_term_care_insurance'){
+  } else if (item.expenseSource == 'long_term_care_insurance') {
     return formatNum(item.totalAmount)
   } else if (rounding.value) {
     return formatRound(item.roundAmount)
@@ -332,7 +363,7 @@ const calcTotalPrice = (item) => {
 const billTotalPrice = computed(() => {
   if (dataForm.value.type == '1') {
     return formatNum(caclAdminssionTotalPrice.value)
-  }else{
+  } else {
     if (rounding.value) {
       return formatNum(total.value)
     } else if (fixed2Num.value) {
@@ -344,41 +375,45 @@ const billTotalPrice = computed(() => {
 })
 
 const formatStartDate = (item) => {
-  if(item.itemName == '长护险护理补贴费用' || item.expenseSource == 'long_term_care_insurance'){ // 长护险
-     return item.createdTime
+  if (item.itemName == '长护险护理补贴费用' || item.expenseSource == 'long_term_care_insurance') {
+    // 长护险
+    return item.createdTime
     // let dataStr = item.startDate??"--"
     // if(dataStr.length>=10){
     //   dataStr = dataStr.substring(0,7)
     // }
     // return dataStr
-  }else if(item.expenseSource == 'expense_item'){
+  } else if (item.expenseSource == 'expense_item') {
     // if(dataForm.value.description){
     //   return dataForm.value.description
     // }else{
     //   return bTitle
     // }
-    if(item.description && item.description.includes('的')){
+    if (item.description && item.description.includes('的')) {
       return item.description.split('的')[0]
-    }else if(item.startDate!=null && item.endDate!=null){
-
+    } else if (item.startDate != null && item.endDate != null) {
       return `${item.startDate}至${item.endDate}`
-    }else if(item.startDate==null && dataForm.value.description && dataForm.value.description.length>21){
-      return dataForm.value.description.toString().substring(0,21)
-    }else {
+    } else if (
+      item.startDate == null &&
+      dataForm.value.description &&
+      dataForm.value.description.length > 21
+    ) {
+      return dataForm.value.description.toString().substring(0, 21)
+    } else {
       return bTitle
     }
-  }else {
+  } else {
     return item.startDate + '至' + item.endDate
   }
 }
 
 const formatStr = (dateStr) => {
-  if(dateStr){
+  if (dateStr) {
     // 2. 按 "-" 拆分字符串,得到 [年, 月, 日] 数组
-    const [year, month, day] = dateStr.split("-");
+    const [year, month, day] = dateStr.split('-')
 
     // 3. 按目标格式拼接
-    return `${year}年${month}月${day}日`;
+    return `${year}年${month}月${day}日`
   }
   return ''
 }