浏览代码

修改居家上门服务页面

unknown 3 周之前
父节点
当前提交
9ce6cf698b

+ 16 - 3
src/views/elderly/elder/outward-registration/ReturnHospitalForm.vue

@@ -103,7 +103,7 @@
         <el-form-item label="附件">
           <SelectUpload
             fun-name="返院登记附件"
-            v-model="dataForm.otherFiles"
+            v-model="dataForm.extraFile"
             :elder="{ elderId: dataForm.elderId, elderName: dataForm.elderName }"
           />
         </el-form-item>
@@ -148,6 +148,7 @@ let dataForm = ref({
   // 表单字段
   id: undefined,
   tenantId: undefined,
+  extraFile: [],
   outboundRefundConfigId: undefined,
   typeShow: undefined,
   elderName: undefined,
@@ -220,6 +221,12 @@ const open = async (tId, id?: any, detail: boolean = false) => {
       dataForm.value.outboundRefundConfigId = res.outboundRefundConfigId
       //dataForm.value.bedName = res.elderlyInfo.bedName
       dataForm.value.idCard = res.elderlyInfo.idCard
+      // 将字符串转换为数组
+      if (res.extraFile && typeof res.extraFile === 'string') {
+        dataForm.value.extraFile = JSON.parse(res.extraFile)
+      } else {
+        dataForm.value.extraFile = []
+      }
 
       getOutboundRefundConfigListFun()
     } catch (err) {}
@@ -272,8 +279,14 @@ const submitForm = async () => {
       message.success('实际返院时间不能小于离院时间')
       return
     }
-
-    const res = await editAskLeave(dataForm.value)
+    if(dataForm.value.tenantId==211 && (!dataForm.value.extraFile || dataForm.value.extraFile.length==0)){
+      message.warning('需要上传附件')
+      return
+    }
+    // 将数组转换为字符串后提交
+    const submitData = { ...dataForm.value }
+    submitData.extraFile = JSON.stringify(dataForm.value.extraFile || [])
+    const res = await editAskLeave(submitData)
     if (res) {
       message.success(t('common.updateSuccess'))
       dialogVisible.value = false

+ 220 - 0
src/views/living-home/consumer-catalogue/expense-calendar/index.vue

@@ -0,0 +1,220 @@
+<template>
+  <!-- 搜索工作栏 -->
+  <ContentWrap>
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="100px"
+    >
+      <el-form-item label="长者姓名:" prop="elderName">
+        <el-input
+          v-model="queryParams.elderName"
+          placeholder="请输入长者姓名"
+          clearable
+          @keyup.enter="handleQuery"
+          class="!w-180px"
+        />
+      </el-form-item>
+      <el-form-item label="手机号码:" prop="phone">
+        <el-input
+          v-model="queryParams.phone"
+          placeholder="请输入手机号码"
+          clearable
+          @keyup.enter="handleQuery"
+          class="!w-180px"
+        />
+      </el-form-item>
+      <el-form-item label="消费券归属月" prop="belongMonth">
+        <el-date-picker
+          v-model="queryParams.belongMonth"
+          type="month"
+          placeholder="请选择月份"
+          class="!w-full"
+          value-format="YYYY-MM"
+          format="YYYY-MM"
+        />
+      </el-form-item>
+      <el-form-item label="消费时间:" prop="consumeTimeRange">
+        <el-date-picker
+          v-model="queryParams.consumeTimeRange"
+          type="daterange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          class="!w-240px"
+          value-format="YYYY-MM-DD"
+        />
+      </el-form-item>
+      <el-form-item class="!ml-auto">
+        <el-button type="primary" @click="handleQuery">
+          <Icon icon="ep:search" class="mr-5px" /> 搜索
+        </el-button>
+        <el-button @click="resetQuery">
+          <Icon icon="ep:refresh" class="mr-5px" /> 重置
+        </el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <div class="flex items-center justify-between mb-15px">
+      <span class="font-bold text-base">消费券消费记录</span>
+      <div class="flex gap-10px">
+      
+        <el-button type="success" @click="handleImport">
+          <Icon icon="ep:upload" class="mr-5px" /> 导出
+        </el-button>
+      </div>
+    </div>
+    <el-table
+      v-loading="loading"
+      :data="list"
+      row-key="id"
+    >
+      <el-table-column label="编号" type="index" width="80" align="center" />
+      <el-table-column prop="elderName" label="长者姓名" align="center" min-width="120" />
+      <el-table-column prop="elderName" label="手机号码" align="phone" min-width="120" />
+      <el-table-column prop="elderName" label="归属月份" align="phone" min-width="120" />
+      <el-table-column prop="elderName" label="消费时间" align="phone" min-width="120" />
+      <el-table-column prop="amount" label="消费前金额" align="center" min-width="120">
+        <template #default="scope">
+          <span>¥{{ scope.row.amount }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="amount" label="消费金额" align="center" min-width="120">
+        <template #default="scope">
+          <span>¥{{ scope.row.amount }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="amount" label="消费后余额" align="center" min-width="120">
+        <template #default="scope">
+          <span>¥{{ scope.row.amount }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" width="200" fixed="right">
+        <template #default="scope">
+          <el-button link type="primary" @click="handleDetail(scope.row)">
+            <Icon icon="ep:view" class="mr-5px" /> 详情
+          </el-button>
+          <el-button link type="warning" @click="handleEdit(scope.row)">
+            <Icon icon="ep:edit" class="mr-5px" /> 编辑
+          </el-button>
+          <el-button link type="danger" @click="handleDelete(scope.row)">
+            <Icon icon="ep:delete" class="mr-5px" /> 删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页 -->
+    <Pagination
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      :total="total"
+      @pagination="getList"
+      class="mt-15px"
+    />
+  </ContentWrap>
+
+  <!-- 新增/编辑/详情弹窗 -->
+  <Form ref="formRef" @success="getList" />
+</template>
+
+<script lang="ts" setup>
+import * as ConsumerVouchersApi from '@/api/elderly/fee/consumpotion-coupon'
+import q from "../../../../../dist-prod/assets/index-CKntuPv2";
+
+
+defineOptions({ name: 'ConsumerList' })
+
+const message = useMessage()
+const { t } = useI18n()
+
+const loading = ref(false)
+const list = ref<any[]>([])
+const total = ref(0)
+const queryFormRef = ref()
+const formRef = ref()
+
+// 查询参数
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  elderName: '',
+  phone: '',
+  status: ''
+})
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await ConsumerVouchersApi.getConsumerVouchersPage(queryParams)
+    list.value = data.list || []
+    total.value = data.total || 0
+  } catch (error) {
+    console.log('获取消费券列表失败', error)
+    // 使用模拟数据
+    list.value = []
+    total.value = 0
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields()
+  queryParams.elderName = ''
+  queryParams.phone = ''
+  queryParams.status = ''
+  handleQuery()
+}
+
+/** 新增 */
+const handleAdd = () => {
+  formRef.value?.open(undefined, undefined, false)
+}
+
+/** 导入 */
+const handleImport = () => {
+  message.info('导入功能开发中...')
+}
+
+/** 详情 */
+const handleDetail = (row: any) => {
+  formRef.value?.open(undefined, row.id, true)
+}
+
+/** 编辑 */
+const handleEdit = (row: any) => {
+  formRef.value?.open(undefined, row.id, false)
+}
+
+/** 删除 */
+const handleDelete = async (row: any) => {
+  try {
+    await message.delConfirm()
+    await ConsumerVouchersApi.consumerVouchersDelete(row.id)
+    message.success(t('common.delSuccess'))
+    getList()
+  } catch {}
+}
+
+/** 初始化 */
+onMounted(() => {
+  getList()
+})
+</script>
+
+<style scoped lang="scss">
+</style>

+ 16 - 12
src/views/living-home/visiting-service/consumer-list/Form.vue → src/views/living-home/consumer-catalogue/subsidy-list/Form.vue

@@ -44,16 +44,20 @@
           </el-form-item>
         </el-col>
         <el-col :span="12" :xs="24">
-          <el-form-item label="消费券类型" prop="voucherType">
-            <el-select v-model="dataForm.voucherType" placeholder="请选择" class="!w-full">
-              <el-option label="按实际金额" value="fixed" />
-              <el-option label="按百分比" value="percentage" />
-            </el-select>
+          <el-form-item label="消费券归属月" prop="belongMonth">
+            <el-date-picker
+              v-model="dataForm.belongMonth"
+              type="month"
+              placeholder="请选择月份"
+              class="!w-full"
+              value-format="YYYY-MM"
+              format="YYYY-MM"
+            />
           </el-form-item>
         </el-col>
         <el-col :span="12" :xs="24">
-          <el-form-item :label="dataForm.voucherType === 'percentage' ? '百分比值' : '消费券金额'" prop="amount">
-            <TgInput v-model="dataForm.amount" :appendText="dataForm.voucherType === 'percentage' ? '%' : '¥'" input-type="number"/>
+          <el-form-item label="消费券金额" prop="amount">
+            <TgInput v-model="dataForm.amount" appendText="¥" input-type="number"/>
           </el-form-item>
         </el-col>
 
@@ -95,8 +99,8 @@ const state = reactive({
     id: '',
     elderId: '',
     idCard: '',
-    voucherType: 'fixed',
-    amount: '',
+    belongMonth: '',
+    amount: '800',
     remarks: '',
     tenantId: undefined
   },
@@ -109,10 +113,10 @@ const state = reactive({
         trigger: 'blur'
       }
     ],
-    voucherType: [
+    belongMonth: [
       {
         required: true,
-        message: '消费券类型不能为空',
+        message: '消费券归属月不能为空',
         trigger: ['blur', 'change']
       }
     ],
@@ -213,7 +217,7 @@ const handleClosed = () => {
     elderId: '',
     idCard: '',
     voucherType: 'fixed',
-    amount: '',
+    amount: '800',
     remarks: '',
     tenantId: undefined
   }

+ 17 - 19
src/views/living-home/visiting-service/consumer-list/index.vue → src/views/living-home/consumer-catalogue/subsidy-list/index.vue

@@ -17,27 +17,24 @@
           class="!w-180px"
         />
       </el-form-item>
-      <el-form-item label="缴费单号:" prop="paymentOrderNo">
+      <el-form-item label="手机号码:" prop="phone">
         <el-input
-          v-model="queryParams.paymentOrderNo"
-          placeholder="请输入缴费单号"
+          v-model="queryParams.phone"
+          placeholder="请输入手机号码"
           clearable
           @keyup.enter="handleQuery"
           class="!w-180px"
         />
       </el-form-item>
-      <el-form-item label="使用状态:" prop="status">
-        <el-select
-          v-model="queryParams.status"
-          placeholder="请选择"
-          clearable
-          class="!w-180px"
-        >
-          <el-option label="全部" value="" />
-          <el-option label="未使用" value="未使用" />
-          <el-option label="已使用" value="已使用" />
-          <el-option label="已过期" value="已过期" />
-        </el-select>
+      <el-form-item label="消费券归属月" prop="belongMonth">
+        <el-date-picker
+          v-model="queryParams.belongMonth"
+          type="month"
+          placeholder="请选择月份"
+          class="!w-full"
+          value-format="YYYY-MM"
+          format="YYYY-MM"
+        />
       </el-form-item>
       <el-form-item class="!ml-auto">
         <el-button type="primary" @click="handleQuery">
@@ -70,12 +67,13 @@
     >
       <el-table-column label="编号" type="index" width="80" align="center" />
       <el-table-column prop="elderName" label="长者姓名" align="center" min-width="120" />
+      <el-table-column prop="elderName" label="手机号码" align="phone" min-width="120" />
+      <el-table-column prop="elderName" label="归属月份" align="phone" min-width="120" />
       <el-table-column prop="amount" label="消费券金额" align="center" min-width="120">
         <template #default="scope">
           <span>¥{{ scope.row.amount }}</span>
         </template>
       </el-table-column>
-      <el-table-column prop="paymentOrderNo" label="缴费单号" align="center" min-width="150" />
       <el-table-column prop="remarks" label="备注" align="center" min-width="200" show-overflow-tooltip />
       <el-table-column label="操作" align="center" width="200" fixed="right">
         <template #default="scope">
@@ -126,7 +124,7 @@ const queryParams = reactive({
   pageNo: 1,
   pageSize: 10,
   elderName: '',
-  paymentOrderNo: '',
+  phone: '',
   status: ''
 })
 
@@ -157,7 +155,7 @@ const handleQuery = () => {
 const resetQuery = () => {
   queryFormRef.value?.resetFields()
   queryParams.elderName = ''
-  queryParams.paymentOrderNo = ''
+  queryParams.phone = ''
   queryParams.status = ''
   handleQuery()
 }
@@ -199,4 +197,4 @@ onMounted(() => {
 </script>
 
 <style scoped lang="scss">
-</style>
+</style>

+ 190 - 326
src/views/living-home/visiting-service/appointment-list/OrderByElderDialog.vue

@@ -1,5 +1,5 @@
 <template>
-  <Dialog v-model="dialogVisible" :title="dialogTitle" width="72vw">
+  <Dialog v-model="dialogVisible" scroll :title="dialogTitle" width="72vw">
     <el-form
       ref="formRef"
       :model="formData"
@@ -142,44 +142,7 @@
         </div>
       </el-form-item>
       
-      <!-- 消费券选择 -->
-      <el-form-item label="消费券" prop="consumerVoucherId">
-        <el-select
-          v-model="formData.consumerVoucherId"
-          placeholder="请选择消费券"
-          class="w-full"
-          clearable
 
-          @change="handleVoucherChange"
-        >
-          <el-option
-            v-for="item in consumerVoucherList"
-            :key="item.id"
-            :label="`${item.voucherType === 'percentage' ? '百分比' : '固定金额'} - ${item.amount}${item.voucherType === 'percentage' ? '%' : '元'}`"
-            :value="item.id"
-          />
-        </el-select>
-      </el-form-item>
-      
-      <!-- 消费券金额/百分比编辑 -->
-      <el-form-item 
-        v-if="selectedVoucher" 
-        :label="selectedVoucher.voucherType === 'percentage' ? '百分比值' : '使用金额'" 
-        prop="voucherValue"
-        :rules="voucherValueRules"
-      >
-        <el-input
-          v-model="formData.voucherValue"
-          :placeholder="selectedVoucher.voucherType === 'percentage' ? '请输入1-100之间的百分比' : '请输入使用金额'"
-          :disabled="isDetailMode"
-          class="w-full"
-        >
-          <template #append>{{ selectedVoucher.voucherType === 'percentage' ? '%' : '元' }}</template>
-        </el-input>
-        <div class="tip-text" v-if="selectedVoucher">
-          消费券总额:{{ selectedVoucher.amount }}{{ selectedVoucher.voucherType === 'percentage' ? '%' : '元' }}
-        </div>
-      </el-form-item>
       
 
       
@@ -260,85 +223,100 @@
         </div>
       </el-form-item>
       
-      <!-- 需求明细 - 使用 Transfer 穿梭框 -->
-      <el-form-item label="需求明细" prop="serviceItems" required style="margin-top: 40px">
-        <div class="transfer-wrapper">
-          <div class="transfer-header" v-if="!isDetailMode">
-            <el-button type="primary" size="small" @click="addToRight" :disabled="leftSelected.length === 0">
-              添加项目 &gt;
-            </el-button>
-            <el-button type="primary" size="small" @click="addToLeft" :disabled="rightSelected.length === 0">
-              &lt; 移除项目
-            </el-button>
-          </div>
-          <div class="transfer-header" v-else>
-            <span style="color: #909399; font-size: 14px;">已选服务项目</span>
-          </div>
-          <div class="transfer-content">
-            <div class="transfer-panel">
-              <div class="transfer-panel__header">
-                <el-checkbox v-model="leftCheckAll" :indeterminate="leftIsIndeterminate" @change="handleLeftCheckAllChange" label="可选服务项目"/>
-                <span>{{ leftSelected.length }}/{{ serviceItemTransferData.length }}</span>
-              </div>
-              <div class="transfer-panel__filter">
-                <el-input v-model="leftFilter" placeholder="请输入搜索内容" clearable prefix-icon="Search" />
-              </div>
-              <div class="transfer-panel__list">
-                <el-checkbox-group v-model="leftSelected">
-                  <el-checkbox 
-                    v-for="item in filteredLeftItems" 
-                    :key="item.key" 
-                    :label="item.key"
-                    class="transfer-item"
-                  >
-                    {{ item.label }}
-                  </el-checkbox>
-                </el-checkbox-group>
-              </div>
-            </div>
-            <div style="width: 20px;background-color: #e4e7ed"></div>
-            <div class="transfer-panel">
-              <div class="transfer-panel__header">
-                <el-checkbox v-model="rightCheckAll" :indeterminate="rightIsIndeterminate" @change="handleRightCheckAllChange" label="已选服务项目"/>
-                <span>{{ rightSelected.length }}/{{ rightItems.length }}</span>
-              </div>
-              <div class="transfer-panel__filter">
-                <el-input v-model="rightFilter" placeholder="请输入搜索内容" clearable prefix-icon="Search" />
-              </div>
-              <div class="transfer-panel__list">
-                <el-checkbox-group v-model="rightSelected">
-                  <el-checkbox 
-                    v-for="item in filteredRightItems" 
-                    :key="item.key" 
-                    :label="item.key"
-                    class="transfer-item"
-                  >
-                    {{ item.label }}
-                  </el-checkbox>
-                </el-checkbox-group>
-              </div>
-            </div>
-          </div>
+      <!-- 需求明细 - 使用远程搜索多选输入框 -->
+      <el-form-item label="项目明细" prop="serviceItems" required style="margin-top: 40px">
+        <el-select
+          v-model="formData.serviceItems"
+          placeholder="请输入服务项目名称搜索"
+          class="w-full service-item-select"
+          filterable
+          remote
+          multiple
+          clearable
+          :disabled="isDetailMode"
+          :remote-method="searchServiceItemRemote"
+          :loading="serviceItemSearchLoading"
+          @change="handleServiceItemChange"
+        >
+          <el-option
+            v-for="item in serviceItemSearchOptions"
+            :key="item.id"
+            :label="`${item.serviceName || item.itemName || item.name} (${item.amount}元)`"
+            :value="item.id"
+          />
+        </el-select>
+      </el-form-item>
+
+      <!-- 消费券选择 -->
+      <el-row :gutter="20" style="margin-top: 40px">
+        <el-col :span="10">
+          <el-form-item label="消费券" prop="consumerVoucherId">
+            <el-select
+              v-model="formData.consumerVoucherId"
+              placeholder="请选择消费券"
+              class="w-full"
+              clearable
+              @change="handleVoucherChange"
+            >
+              <el-option
+                v-for="item in consumerVoucherList"
+                :key="item.id"
+                :label="`${item.amount}元`"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+
+        <el-col :span="14">
+          <el-form-item
+            label="抵扣方式"
+            prop="voucherValue"
+            :rules="voucherValueRules"
+          >
+            <el-input
+              v-model="formData.voucherValue"
+              placeholder="请输入抵扣金额"
+              :disabled="isDetailMode||!formData.consumerVoucherId"
+              class="w-full"
+            >
+              <template #prepend>
+                <el-select  v-model="formData.voucherType" placeholder="选择方式" style="width: 115px" :disabled="isDetailMode || !formData.consumerVoucherId">
+                  <el-option label="按金额" value="amount" />
+                  <el-option label="按百分比" value="percentage" />
+                </el-select>
+              </template>
+              <template #append>{{ formData.voucherType === 'percentage' ? '%' : '元' }}</template>
+            </el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <!-- 消费券提示信息 -->
+      <el-form-item v-if="selectedVoucher">
+        <div class="tip-text">
+          消费券总额:{{ selectedVoucher.amount }}元({{ formData.voucherType === 'percentage' ? '按百分比抵扣,输入' + formData.voucherValue + '%可抵扣' + discountAmount + '元' : '按固定金额抵扣' }})
         </div>
       </el-form-item>
+
       <!-- 此处为金额板块 -->
-      <el-divider content-position="left">金额明细</el-divider>
+      <el-divider content-position="left" style="margin-top: 50px">金额明细</el-divider>
       <el-row :gutter="20">
         <el-col :span="8" :xs="24">
           <el-form-item label="总金额">
-            <el-input v-model="totalAmount" disabled class="w-full">
-              <template #append>元</template>
-            </el-input>
+            <div class="amount-display">
+              <span class="amount-value">¥{{ totalAmount }}</span>
+            </div>
           </el-form-item>
         </el-col>
         <el-col :span="8" :xs="24">
           <el-form-item label="优惠金额">
-            <el-input v-model="discountAmount" disabled class="w-full">
-              <template #append>元</template>
-            </el-input>
+            <div class="amount-display">
+              <span class="amount-value">¥{{ discountAmount }}</span>
+            </div>
             <div class="tip-text" v-if="selectedVoucher">
-              消费券类型:{{ selectedVoucher.voucherType === 'percentage' ? '百分比' : '固定金额' }}
-              <span v-if="selectedVoucher.voucherType === 'percentage'">
+              抵扣方式:{{ formData.voucherType === 'percentage' ? '按百分比' : '按固定金额' }}
+              <span v-if="formData.voucherType === 'percentage' && formData.voucherValue">
                 ({{ formData.voucherValue }}%)
               </span>
             </div>
@@ -346,9 +324,9 @@
         </el-col>
         <el-col :span="8" :xs="24">
           <el-form-item label="自费金额">
-            <el-input v-model="selfPayAmount" disabled class="w-full" type="number">
-              <template #append>元</template>
-            </el-input>
+            <div class="amount-display">
+              <span class="amount-value">¥{{ selfPayAmount }}</span>
+            </div>
           </el-form-item>
         </el-col>
       </el-row>
@@ -502,13 +480,9 @@ const serviceAreaFilter = ref('')
 const servicePersonKeyword = ref('')
 const selectedServicePerson = ref<any>(null)
 
-// 自定义穿梭框相关
-const leftSelected = ref<number[]>([])
-const rightSelected = ref<number[]>([])
-const leftFilter = ref('')
-const rightFilter = ref('')
-const leftCheckAll = ref(false)
-const rightCheckAll = ref(false)
+// 服务项目远程搜索相关
+const serviceItemSearchLoading = ref(false)
+const serviceItemSearchOptions = ref<any[]>([])
 
 const formData = reactive({
   elderId: undefined as number | undefined,
@@ -524,7 +498,8 @@ const formData = reactive({
   serviceItems: [] as number[],
   remark: '',
   consumerVoucherId: undefined as number | undefined,
-  voucherValue: ''
+  voucherValue: '',
+  voucherType: 'amount' as 'amount' | 'percentage'
 })
 
 // 消费券列表
@@ -547,16 +522,20 @@ const totalAmount = computed(() => {
 // 优惠金额(消费券抵扣金额)
 const discountAmount = computed(() => {
   if (!selectedVoucher.value || !formData.voucherValue) return '0.00'
+
   const total = parseFloat(totalAmount.value)
-  if (selectedVoucher.value.voucherType === 'percentage') {
-    // 百分比类型:总金额 × 百分比
-    const percentage = parseFloat(formData.voucherValue) || 0
-    return (total * percentage / 100).toFixed(2)
+  const maxAmount = parseFloat(selectedVoucher.value.amount) || 0
+  const voucherVal = parseFloat(formData.voucherValue) || 0
+
+  if (formData.voucherType === 'percentage') {
+    // 百分比抵扣:总价 × 百分比
+    let discount = total * voucherVal / 100
+    // 不能超过消费券总额
+    discount = Math.min(discount, maxAmount)
+    return discount.toFixed(2)
   } else {
-    // 固定金额类型:直接使用 voucherValue
-    const voucherVal = parseFloat(formData.voucherValue) || 0
-    // 优惠金额不能超过总金额
-    return Math.min(voucherVal, total).toFixed(2)
+    // 固定金额抵扣
+    return Math.min(voucherVal, total, maxAmount).toFixed(2)
   }
 })
 
@@ -567,31 +546,26 @@ const selfPayAmount = computed(() => {
   return (total - discount).toFixed(2)
 })
 
-// 消费券金额/百分比校验规则
+// 消费券金额校验规则
 const voucherValueRules = computed(() => {
   if (!selectedVoucher.value) return []
-  
-  if (selectedVoucher.value.voucherType === 'percentage') {
-    return [
-      { required: true, message: '请输入百分比值', trigger: 'blur' },
-      { 
-        validator: (rule: any, value: any, callback: any) => {
-          const num = Number(value)
+  return [
+    {
+      validator: (rule: any, value: any, callback: any) => {
+        if (!value || Number(value) <= 0) {
+          callback(new Error(formData.voucherType === 'percentage' ? '请输入百分比' : '请输入抵扣金额'))
+          return
+        }
+        const num = Number(value)
+        if (formData.voucherType === 'percentage') {
+          // 百分比校验
           if (isNaN(num) || num < 1 || num > 100) {
             callback(new Error('百分比值必须在1-100之间'))
           } else {
             callback()
           }
-        },
-        trigger: 'blur'
-      }
-    ]
-  } else {
-    return [
-      { required: true, message: '请输入使用金额', trigger: 'blur' },
-      {
-        validator: (rule: any, value: any, callback: any) => {
-          const num = Number(value)
+        } else {
+          // 金额校验
           if (isNaN(num) || num <= 0) {
             callback(new Error('金额必须大于0'))
           } else if (num > Number(selectedVoucher.value.amount)) {
@@ -599,11 +573,11 @@ const voucherValueRules = computed(() => {
           } else {
             callback()
           }
-        },
-        trigger: 'blur'
-      }
-    ]
-  }
+        }
+      },
+      trigger: 'blur'
+    }
+  ]
 })
 
 const formRules = {
@@ -634,95 +608,32 @@ const formRules = {
   serviceItems: [{ required: true, message: '请选择服务项目', trigger: 'change', type: 'array' }]
 }
 
-// 服务项目穿梭框数据
-const serviceItemTransferData = computed(() => {
-  return serviceItemList.value.map(item => ({
-    key: item.id,
-    label: `${item.serviceName || item.itemName || item.name} - (${item.amount}元)`,
-    disabled: false
-  }))
-})
-
-// 右侧已选项(已选服务项目)
-const rightItems = computed(() => {
-  return serviceItemTransferData.value.filter(item => formData.serviceItems.includes(item.key))
-})
-
-// 左侧可选项目(过滤掉已选的)
-const leftItems = computed(() => {
-  return serviceItemTransferData.value.filter(item => !formData.serviceItems.includes(item.key))
-})
-
-// 过滤后的左侧项目
-const filteredLeftItems = computed(() => {
-  if (!leftFilter.value) return leftItems.value
-  return leftItems.value.filter(item => 
-    item.label.toLowerCase().includes(leftFilter.value.toLowerCase())
-  )
-})
-
-// 过滤后的右侧项目
-const filteredRightItems = computed(() => {
-  if (!rightFilter.value) return rightItems.value
-  return rightItems.value.filter(item => 
-    item.label.toLowerCase().includes(rightFilter.value.toLowerCase())
-  )
-})
-
-// 左侧全选状态
-const leftIsIndeterminate = computed(() => {
-  return leftSelected.value.length > 0 && leftSelected.value.length < filteredLeftItems.value.length
-})
-
-// 右侧全选状态
-const rightIsIndeterminate = computed(() => {
-  return rightSelected.value.length > 0 && rightSelected.value.length < filteredRightItems.value.length
-})
-
-// 监听左侧选择变化
-watch(leftSelected, (val) => {
-  leftCheckAll.value = val.length === filteredLeftItems.value.length && val.length > 0
-})
-
-// 监听右侧选择变化
-watch(rightSelected, (val) => {
-  rightCheckAll.value = val.length === filteredRightItems.value.length && val.length > 0
-})
-
-// 监听左侧过滤变化,清空选择
-watch(leftFilter, () => {
-  leftSelected.value = []
-  leftCheckAll.value = false
-})
-
-// 监听右侧过滤变化,清空选择
-watch(rightFilter, () => {
-  rightSelected.value = []
-  rightCheckAll.value = false
-})
-
-// 左侧全选
-const handleLeftCheckAllChange = (val: boolean) => {
-  leftSelected.value = val ? filteredLeftItems.value.map(item => item.key) : []
-}
-
-// 右侧全选
-const handleRightCheckAllChange = (val: boolean) => {
-  rightSelected.value = val ? filteredRightItems.value.map(item => item.key) : []
-}
-
-// 添加到右侧
-const addToRight = () => {
-  formData.serviceItems.push(...leftSelected.value)
-  leftSelected.value = []
-  leftCheckAll.value = false
+// 远程搜索服务项目
+const searchServiceItemRemote = async (query: string) => {
+  if (query) {
+    serviceItemSearchLoading.value = true
+    try {
+      const params = {
+        pageNo: 1,
+        pageSize: 50,
+        name: query
+      }
+      const data = await ElderApi.getServiceItemList(params)
+      serviceItemSearchOptions.value = data.list || []
+    } catch (error) {
+      console.log('搜索服务项目失败', error)
+    } finally {
+      serviceItemSearchLoading.value = false
+    }
+  } else {
+    serviceItemSearchOptions.value = []
+  }
 }
 
-// 添加到左侧(移除)
-const addToLeft = () => {
-  formData.serviceItems = formData.serviceItems.filter(key => !rightSelected.value.includes(key))
-  rightSelected.value = []
-  rightCheckAll.value = false
+// 服务项目选择变化
+const handleServiceItemChange = (val: number[]) => {
+  // 选择变化时更新金额计算
+  console.log('服务项目选择变化:', val)
 }
 
 // 过滤后的服务人员列表
@@ -810,6 +721,7 @@ const resetForm = () => {
   formData.remark = ''
   formData.consumerVoucherId = undefined
   formData.voucherValue = ''
+  formData.voucherType = 'amount'
   selectedServicePerson.value = null
   serviceAreaFilter.value = ''
   servicePersonKeyword.value = ''
@@ -993,10 +905,12 @@ const loadConsumerVouchers = async (elderId: number) => {
 const handleVoucherChange = (val: number) => {
   const voucher = consumerVoucherList.value.find(item => item.id === val)
   if (voucher) {
-    // 默认填充最大可用金额/百分比
+    // 默认填充消费券总额作为使用金额
     formData.voucherValue = voucher.amount
+    formData.voucherType = 'amount'
   } else {
     formData.voucherValue = ''
+    formData.voucherType = 'amount'
   }
 }
 
@@ -1102,6 +1016,24 @@ defineExpose({ open })
   line-height: 1.5;
 }
 
+.amount-display {
+  display: flex;
+  align-items: center;
+  height: 32px;
+
+  .amount-label {
+    color: #333;
+    font-size: 14px;
+    margin-right: 8px;
+  }
+
+  .amount-value {
+    color: #f56c6c;
+    font-size: 16px;
+    font-weight: bold;
+  }
+}
+
 .empty-text {
   color: #909399;
   padding: 20px 0;
@@ -1198,104 +1130,36 @@ defineExpose({ open })
   align-items: center;
 }
 
-.transfer-wrapper {
-  width: 100%;
-  border: 1px solid #e4e7ed;
-  border-radius: 4px;
+// 详情模式下服务人员列表不可点击
+.service-person-list.detail-mode {
+  .service-person-card {
+    cursor: default;
 
-  .transfer-header {
-      display: flex;
-      justify-content: center;
-      align-items: center;
-      min-height: 40px;
+    &:hover {
+      box-shadow: none;
     }
 
-    // 详情模式下服务人员列表不可点击
-    .service-person-list.detail-mode {
-      .service-person-card {
-        cursor: default;
-
-        &:hover {
-          box-shadow: none;
-        }
-
-        &.selected {
-          border-color: #409eff;
-          box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
-        }
-      }
-    };
-    gap: 20px;
-    padding: 10px;
-    background-color: #f5f7fa;
-    border-bottom: 1px solid #e4e7ed;
-  }
-
-  .transfer-content {
-    display: flex;
-    height: 400px;
-  }
-
-  .transfer-panel {
-    flex: 1;
-    display: flex;
-    flex-direction: column;
-    overflow: hidden;
-
-    &:first-child {
-      border-right: 1px solid #e4e7ed;
-    }
-
-    &__header {
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      padding: 10px 15px;
-      background-color: #f5f7fa;
-      border-bottom: 1px solid #e4e7ed;
-      font-size: 14px;
-      color: #606266;
-
-      span {
-        color: #909399;
-        font-size: 12px;
-      }
-    }
-
-    &__filter {
-      padding: 10px 15px;
-      border-bottom: 1px solid #e4e7ed;
+    &.selected {
+      border-color: #409eff;
+      box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
     }
+  }
+}
 
-    &__list {
-      flex: 1;
-      overflow-y: auto;
-      padding: 10px 15px;
-
-      &::-webkit-scrollbar {
-        width: 6px;
-      }
-
-      &::-webkit-scrollbar-thumb {
-        background-color: #c0c4cc;
-        border-radius: 3px;
-      }
-    }
+// 服务项目多选输入框样式
+.service-item-select {
+  :deep(.el-select__wrapper) {
+    min-height: 80px;
+    align-items: flex-start;
+    padding-top: 4px;
+    padding-bottom: 4px;
   }
 
-  .transfer-item {
-    display: flex;
-    align-items: center;
-    padding: 8px 0;
-    width: 100%;
-
-    :deep(.el-checkbox__label) {
-      flex: 1;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-    }
+  :deep(.el-select__selection) {
+    flex-wrap: wrap;
+    gap: 4px;
   }
+}
 
 
 // 数据库字段说明样式

+ 0 - 378
src/views/living-home/visiting-service/consumer-list/column.ts

@@ -1,378 +0,0 @@
-import { DICT_TYPE } from '@/utils/dict'
-// =================收费分类=====================
-export const ChargeCategoryColumns = reactive([
-  {
-    label: '所属机构',
-    field: 'tenantName',
-    type: '99'
-  },
-  {
-    label: '类别名称',
-    field: 'name'
-  },
-  {
-    label: '级别',
-    field: 'parentId',
-    dictArr: DICT_TYPE.LEVEL_ARR,
-    type: '1'
-  },
-  {
-    label: '状态',
-    field: 'status',
-    type: '2',
-    dictArr: DICT_TYPE.COMMON_STATUS2
-  },
-  {
-    label: '备注',
-    field: 'remark'
-  }
-])
-// =================收费项目=====================
-export const OverheadChargeColumns = reactive([
-  {
-    label: '所属机构',
-    field: 'tenantName',
-    type: '99'
-  },
-  {
-    label: '项目名称',
-    field: 'chargeName',
-    align: 'left'
-  },
-  {
-    label: '价格(元)',
-    field: 'price'
-  },
-  {
-    label: '单位',
-    field: 'chargeType',
-    type: '1',
-    dictArr: DICT_TYPE.FEE_CHARGE_TYPE
-  },
-  {
-    label: '状态',
-    field: 'status',
-    type: '2',
-    dictArr: DICT_TYPE.COMMON_STATUS2
-  },
-  {
-    label: '金蝶编码',
-    field: 'kingdeeCostid',
-  },
-])
-
-// ======================账单缴费=====================
-export const BillPayColumns = reactive([
-  {
-    label: '所属机构',
-    field: 'tenantName',
-    type: '99',
-    fixed: true,
-    width: 180
-  },
-  {
-    label: '长者姓名',
-    field: 'elderName',
-    width: 120,
-    fixed: true
-  },
-  {
-    label: '床位号',
-    field: 'bedName',
-    width: 180,
-    fixed: true
-  },
-  {
-    label: '账单月',
-    field: 'billingMonth',
-    width: 120,
-    fixed: true
-  },
-  // {
-  //   label: '推送状态',
-  //   field: 'pushStatus',
-  //   dictArr: DICT_TYPE.PUSH_STATUS,
-  //   type: '1',
-  //   width: 120
-  // },
-  {
-    label: '缴费状态',
-    field: 'payStatus',
-    dictArr: DICT_TYPE.PAY_TYPE,
-    type: '2',
-    width: 100
-  },
-  {
-    label: '缴费时间',
-    field: 'payTime',
-    type: '9',
-    format: true,
-    width: 180
-  },
-  {
-    label: '出纳',
-    field: 'payeeName',
-    width: 120
-  },
-  // {
-  //   label: '已缴费用',
-  //   field: 'actualAmount',
-  //   type: '14',
-  //   width: 120
-  // },
-  {
-    label: '本月账单应收',
-    field: 'actualAmount',
-    type: '14',
-    width: 120
-  },
-  {
-    label: '床位费',
-    field: 'bedAmount',
-    type: '15',
-    width: 120
-  },
-  {
-    label: '护理费',
-    field: 'nurseAmount',
-    type: '15',
-    width: 120
-  },
-  {
-    label: '餐饮费',
-    field: 'mealAmount',
-    type: '15',
-    width: 120
-  },
-  {
-    label: '其他',
-    field: 'otherAmount',
-    otherField: 'otherRoundAmount',
-    type: '13',
-    width: 120
-  },
-  {
-    label: '医保',
-    field: 'insuranceAmount',
-    type: '3',
-    width: 120
-  },
-  {
-    label: '已缴费用',
-    field: 'payableAmount',
-    type: '17',
-    width: 120
-  }
-])
-
-// ======================日常费用=====================
-export const DailyFeeColumns = reactive([
-  {
-    label: '所属机构',
-    field: 'tenantName',
-    type: '99',
-  },
-  {
-    label: '长者姓名',
-    field: 'elderName',
-    width: 120
-  },
-  {
-    label: '床位号',
-    field: 'bedName',
-    width: 180
-  },
-  {
-    label: '账单归属月',
-    field: 'attributionBillTime',
-  },
-  {
-    label: '费用来源',
-    field: 'type',
-    type: '1',
-    dictArr: DICT_TYPE.COST_FROM_TYPE,
-  },
-  {
-    label: '收费项目',
-    field: 'itemName',
-    width: 180
-  },
-  {
-    label: '费用(元)',
-    field: 'amount',
-    type: '3'
-  },
-  {
-    label: '缴费状态',
-    field: 'status',
-    dictArr: DICT_TYPE.PAYMENT_STATUS,
-    type: '1'
-  },
-  {
-    label: '费用产生时间',
-    field: 'createdTime',
-    format: true,
-    type: '9',
-    width: 180
-  },
-  {
-    label: '缴费单号',
-    field: 'expenseBillCode'
-  },
-  {
-    label: '记账人',
-    field: 'createdBy'
-  },
-  {
-    label: '备注',
-    field: 'remarks'
-  }
-])
-
-// ==============入住押金====================
-export const depositColumn = [
-  {
-    label: '所属机构',
-    field: 'tenantName',
-    type: '99',
-  },
-  {
-    label: '长者姓名',
-    field: 'elderName'
-  },
-  {
-    label: '床位号',
-    field: 'bedName'
-  },
-  {
-    label: '长者状态',
-    field: 'inStatus',
-    type: '1',
-    dictArr: DICT_TYPE.IN_STATUS_ARR
-  },
-  {
-    label: '押金金额(元)',
-    field: 'amount',
-    type: '3'
-  }
-]
-
-// ==============退住结算====================
-export const levelSettleColumn = [
-  {
-    label: '所属机构',
-    field: 'tenantName',
-    type: '99',
-  },
-  {
-    label: '长者姓名',
-    field: 'elderName'
-  },
-  {
-    label: '床位号',
-    field: 'bedName'
-  },
-  {
-    label: '结算状态',
-    field: 'status',
-    dictArr: DICT_TYPE.SETTLEMENT_STATUS,
-    type: '1'
-  },
-  {
-    label: '结算时间',
-    field: 'settlementTime',
-    format: true
-  },
-  {
-    label: '结算人',
-    field: 'settlementPersonName'
-  }
-]
-
-// =================长护险===================
-export const expenseAllowanceColumn = [
-  {
-    label: '所属机构',
-    field: 'tenantName',
-    type: '99',
-  },
-  {
-    label: '长者姓名',
-    field: 'elderName'
-  },
-  {
-    label: '账单归属月',
-    field: 'billingMonth'
-  },
-  {
-    label: '消费券金额',
-    field: 'amount',
-    type: '3'
-  },
-  {
-    label: '缴费单号',
-    field: 'orderNumber'
-  },
-  {
-    label: '备注',
-    field: 'remarks'
-  }
-]
-
-// ==================余额预存===================
-export const balanceColumn = [
-  {
-    label: '长者姓名',
-    field: 'elderName'
-  },
-  {
-    label: '床位号',
-    field: 'bedName'
-  },
-  {
-    label: '入住状态',
-    field: 'inStatus',
-    dictArr: DICT_TYPE.IN_STATUS_ARR,
-    type: '1'
-  },
-  {
-    label: '预存金额(元)',
-    field: 'amount',
-    type: '3'
-  }
-]
-
-// ===================外出费用配置=========================
-export const outRefundColumn = [
-  {
-    label: '所属机构',
-    field: 'tenantName',
-    type: '99'
-  },
-  {
-    label: '类型名称',
-    field: 'name'
-  },
-  {
-    label: '是否退费',
-    field: 'isRefund',
-    dictArr: DICT_TYPE.COMMON_STATUS6,
-    type: '1'
-  },
-  {
-    label: '返院当日退费',
-    field: 'isSameDayRefund',
-    dictArr: DICT_TYPE.REFUND_TERMS_TYPE,
-    type: '1'
-  },
-  {
-    label: '状态',
-    field: 'status',
-    dictArr: DICT_TYPE.COMMON_STATUS2,
-    type: '1'
-  },
-  {
-    label: '备注',
-    field: 'remarks'
-  }
-]

+ 4 - 3
src/views/ykCenter/delivery-staff/index.vue

@@ -128,7 +128,7 @@
             <el-option
               v-for="elderly in elderlyOptions"
               :key="elderly.id"
-              :label="elderly.elderName"
+              :label="(`${elderly.elderName} (${elderly.phone}-${elderly.currentLiveAddress})`)"
               :value="elderly.id"
             />
           </el-select>
@@ -175,7 +175,7 @@
             <el-option
               v-for="elderly in elderlyOptions"
               :key="elderly.id"
-              :label="(`${elderly.elderName}-(${elderly.idCard})`)"
+              :label="(`${elderly.elderName}-(${elderly.phone}-${elderly.currentLiveAddress})`)"
               :value="elderly.id"
             />
           </el-select>
@@ -195,6 +195,7 @@ import {
   deleteDeliveryStaff, getDeliveryStaffManageList, getElderlyList
 } from '@/api/ykCenter'
 import {useUserStore} from "@/store/modules/user";
+import {getHomeElderlyList} from "@/api/living-home/elderly";
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance
 const router = useRouter()
@@ -308,7 +309,7 @@ const getElderlyOptions = async (query: string) => {
         pageSize: 3000,
         elderName: query=='-1'?'':query,
       }
-      const res = await getElderlyList(queryParams)
+      const res = await getHomeElderlyList(queryParams)
       elderlyOptions.value = res.list || []
     }else {
       elderlyOptions.value=[]

+ 17 - 0
src/views/ykCenter/proceeds/index.vue

@@ -12,6 +12,21 @@
           <el-form-item label="长者姓名">
             <el-input @keyup.enter="handleQuery" v-model="queryParams.elderlyName" placeholder="请输入长者姓名" clearable />
           </el-form-item>
+          <el-form-item label="身份证号">
+            <el-input @keyup.enter="handleQuery" v-model="queryParams.idCard" placeholder="请输入长者身份证号" clearable />
+          </el-form-item>
+          <el-form-item label="支付方式:" prop="orderType">
+            <el-select
+              v-model="queryParams.orderType"
+              placeholder="全部"
+              clearable
+              class="!w-180px"
+            >
+              <el-option label="全部" value="" />
+              <el-option label="微信" value="wechat" />
+              <el-option label="现金" value="cash" />
+            </el-select>
+          </el-form-item>
           <el-form-item label="收款日期">
             <el-date-picker
               v-model="queryParams.dateRange"
@@ -192,6 +207,7 @@ const queryParams = ref({
   pageNo: 1,
   pageSize: 10,
   elderlyName: '',
+  idCard: '',
   dateRange: getCurrentMonthRange(),
   tenantIds: userStore.orgTenantId
 })
@@ -216,6 +232,7 @@ const editForm = ref({
   paymentDateTime: '',
   operator: '',
   remarks: '',
+  idCard: '',
   tenantIds: userStore.orgTenantId
 })