Ver código fonte

添加居家服务项目

unknown 1 mês atrás
pai
commit
e52a954c3a

+ 54 - 45
src/api/living-home/elderly/index.ts

@@ -2,25 +2,40 @@ import request from '@/config/axios'
 
 // ==================== 长者档案管理接口 ====================
 
+// 获取长者列表
+export const getHomeElderlyList = (params) => {
+  return request.get({
+    url: '/home/elderly-info/page',
+    params
+  })
+}
+
+// 退住长者
+export const deleteOutElderly = (id) => {
+  return request.delete({
+    url: `/home/elderly-info/delete?id=${id}`
+  })
+}
+
 // 获取长者详情
 export const getElderDetail = (id: string | number) => {
   return request.get({
-    url: `elderlyInfo/findDetailById?id=${id}`
+    url: `/home/elderly-info/get?id=${id}`
   })
 }
 
 // 新增长者档案
 export const addElder = (data: any) => {
   return request.post({
-    url: 'elderlyInfo/addElder',
+    url: '/home/elderly-info/create',
     data
   })
 }
 
 // 编辑长者档案
 export const updateElder = (data: any) => {
-  return request.post({
-    url: 'elderlyInfo/update',
+  return request.put({
+    url: '/home/elderly-info/update',
     data
   })
 }
@@ -34,18 +49,12 @@ export const deleteElder = (id: string | number) => {
 
 // ==================== 服务人员接口 ====================
 
-// 获取服务人员列表(分页)
-export const getServicePersonPage = (params: any) => {
-  return request.get({
-    url: 'living-home/service-person/page',
-    params
-  })
-}
+
 
 // 获取服务人员列表(全部)
 export const getServicePersonList = (params?: any) => {
   return request.get({
-    url: 'living-home/service-person/list',
+    url: '/home/service-member/page',
     params
   })
 }
@@ -123,29 +132,29 @@ export const updateElderPassword = (data: { elderId: string | number; password:
 // 服务区域 VO
 export interface ServiceAreaVO {
   id?: number
-  areaCode: string | number[]
-  areaName: string
+  area?: string
   remark?: string
+  tenantId?: number
 }
 
 // 查询服务区域列表
 export const getServiceAreaList = () => {
   return request.get({
-    url: 'living-home/service-area/list'
+    url: '/home/service-area/page'
   })
 }
 
 // 查询服务区域详情
 export const getServiceArea = (id: number) => {
   return request.get({
-    url: `living-home/service-area/get?id=${id}`
+    url: `/home/service-area/get?id=${id}`
   })
 }
 
 // 新增服务区域
 export const createServiceArea = (data: ServiceAreaVO) => {
   return request.post({
-    url: 'living-home/service-area/create',
+    url: '/home/service-area/create',
     data
   })
 }
@@ -153,15 +162,15 @@ export const createServiceArea = (data: ServiceAreaVO) => {
 // 修改服务区域
 export const updateServiceArea = (data: ServiceAreaVO) => {
   return request.put({
-    url: 'living-home/service-area/update',
+    url: '/home/service-area/update',
     data
   })
 }
 
 // 删除服务区域
-export const deleteServiceArea = (ids: number[]) => {
+export const deleteServiceArea = (ids) => {
   return request.delete({
-    url: `living-home/service-area/delete?ids=${ids.join(',')}`
+    url: `/home/service-area/delete?id=${ids}`
   })
 }
 
@@ -191,14 +200,14 @@ export interface ServicePersonVO {
 // 查询服务人员详情
 export const getServicePerson = (id: number) => {
   return request.get({
-    url: `living-home/service-person/get?id=${id}`
+    url: `/home/service-member/get?id=${id}`
   })
 }
 
 // 新增服务人员
 export const createServicePerson = (data: ServicePersonVO) => {
   return request.post({
-    url: 'living-home/service-person/create',
+    url: '/home/service-member/create',
     data
   })
 }
@@ -206,15 +215,15 @@ export const createServicePerson = (data: ServicePersonVO) => {
 // 修改服务人员
 export const updateServicePerson = (data: ServicePersonVO) => {
   return request.put({
-    url: 'living-home/service-person/update',
+    url: '/home/service-member/update',
     data
   })
 }
 
 // 删除服务人员
-export const deleteServicePerson = (ids: number[]) => {
+export const deleteServicePerson = (ids) => {
   return request.delete({
-    url: `living-home/service-person/delete?ids=${ids.join(',')}`
+    url: `/home/service-member/delete?id=${ids}`
   })
 }
 
@@ -265,7 +274,7 @@ export interface ServiceTypeVO {
 // 查询服务类别列表
 export const getServiceTypeList = (params?: { name?: string }) => {
   return request.get({
-    url: 'living-home/service-type/list',
+    url: '/home/service-category/page',
     params
   })
 }
@@ -273,14 +282,14 @@ export const getServiceTypeList = (params?: { name?: string }) => {
 // 查询服务类别详情
 export const getServiceType = (id: number) => {
   return request.get({
-    url: `living-home/service-type/get?id=${id}`
+    url: `/home/service-category/get?id=${id}`
   })
 }
 
 // 新增服务类别
 export const createServiceType = (data: ServiceTypeVO) => {
   return request.post({
-    url: 'living-home/service-type/create',
+    url: '/home/service-category/create',
     data
   })
 }
@@ -288,15 +297,15 @@ export const createServiceType = (data: ServiceTypeVO) => {
 // 修改服务类别
 export const updateServiceType = (data: ServiceTypeVO) => {
   return request.put({
-    url: 'living-home/service-type/update',
+    url: '/home/service-category/update',
     data
   })
 }
 
 // 删除服务类别
-export const deleteServiceType = (ids: number[]) => {
+export const deleteServiceType = (ids) => {
   return request.delete({
-    url: `living-home/service-type/delete?ids=${ids.join(',')}`
+    url: `/home/service-category/delete?id=${ids}`
   })
 }
 
@@ -336,7 +345,7 @@ export interface ServiceItemVO {
 // 查询服务项目列表(分页)
 export const getServiceItemPage = (params: any) => {
   return request.get({
-    url: 'living-home/service-item/page',
+    url: '/home/service-item/page',
     params
   })
 }
@@ -344,7 +353,7 @@ export const getServiceItemPage = (params: any) => {
 // 查询服务项目列表(全部)
 export const getServiceItemList = (params?: any) => {
   return request.get({
-    url: 'living-home/service-item/list',
+    url: '/home/service-item/page',
     params
   })
 }
@@ -352,14 +361,14 @@ export const getServiceItemList = (params?: any) => {
 // 查询服务项目详情
 export const getServiceItem = (id: number) => {
   return request.get({
-    url: `living-home/service-item/get?id=${id}`
+    url: `/home/service-item/get?id=${id}`
   })
 }
 
 // 新增服务项目
 export const createServiceItem = (data: ServiceItemVO) => {
   return request.post({
-    url: 'living-home/service-item/create',
+    url: '/home/service-item/create',
     data
   })
 }
@@ -367,15 +376,15 @@ export const createServiceItem = (data: ServiceItemVO) => {
 // 修改服务项目
 export const updateServiceItem = (data: ServiceItemVO) => {
   return request.put({
-    url: 'living-home/service-item/update',
+    url: '/home/service-item/update',
     data
   })
 }
 
 // 删除服务项目
-export const deleteServiceItem = (ids: number[]) => {
+export const deleteServiceItem = (ids) => {
   return request.delete({
-    url: `living-home/service-item/delete?ids=${ids.join(',')}`
+    url: `/home/service-item/delete?id=${ids}`
   })
 }
 
@@ -429,7 +438,7 @@ export interface ServiceComboVO {
 // 查询服务套餐列表(分页)
 export const getServiceComboPage = (params: any) => {
   return request.get({
-    url: 'living-home/service-combo/page',
+    url: '/home/service-package/page',
     params
   })
 }
@@ -437,7 +446,7 @@ export const getServiceComboPage = (params: any) => {
 // 查询服务套餐列表(全部)
 export const getServiceComboList = (params?: any) => {
   return request.get({
-    url: 'living-home/service-combo/list',
+    url: '/home/service-package/page',
     params
   })
 }
@@ -445,14 +454,14 @@ export const getServiceComboList = (params?: any) => {
 // 查询服务套餐详情
 export const getServiceCombo = (id: number) => {
   return request.get({
-    url: `living-home/service-combo/get?id=${id}`
+    url: `/home/service-package/get?id=${id}`
   })
 }
 
 // 新增服务套餐
 export const createServiceCombo = (data: ServiceComboVO) => {
   return request.post({
-    url: 'living-home/service-combo/create',
+    url: '/home/service-package/create',
     data
   })
 }
@@ -460,15 +469,15 @@ export const createServiceCombo = (data: ServiceComboVO) => {
 // 修改服务套餐
 export const updateServiceCombo = (data: ServiceComboVO) => {
   return request.put({
-    url: 'living-home/service-combo/update',
+    url: '/home/service-package/update',
     data
   })
 }
 
 // 删除服务套餐
-export const deleteServiceCombo = (ids: number[]) => {
+export const deleteServiceCombo = (ids: string) => {
   return request.delete({
-    url: `living-home/service-combo/delete?ids=${ids.join(',')}`
+    url: `/home/service-package/delete?id=${ids}`
   })
 }
 

+ 37 - 0
src/api/system/user/index.ts

@@ -124,3 +124,40 @@ export const getGroupTenantByUser = () => {
 export const getUserListByTenantIds = (params) => {
   return request.get({ url: `/system/user/getUserListByTenantIds`, params })
 }
+
+
+
+
+// 服务部门 VO
+export interface ServiceDeptVO {
+  id?: number
+  name: string
+  responsiblePersonId?: number
+  phone?: string
+  email?: string
+}
+
+// 查询服务部门列表
+export const getServiceDeptList = async (params): Promise<ServiceDeptVO[]> => {
+  return await request.get({ url: '/home/service-department/page' ,params})
+}
+
+// 查询服务部门详情
+export const getServiceDept = async (id: number): Promise<ServiceDeptVO> => {
+  return await request.get({ url: `/home/service-department/get?id=${id}` })
+}
+
+// 新增服务部门
+export const createServiceDept = async (data: ServiceDeptVO) => {
+  return await request.post({ url: '/home/service-department/create', data })
+}
+
+// 修改服务部门
+export const updateServiceDept = async (data: ServiceDeptVO) => {
+  return await request.put({ url: '/home/service-department/update', data })
+}
+
+// 删除服务部门
+export const deleteServiceDept = async (id: number) => {
+  return await request.delete({ url: `/home/service-department/delete?id=${id}` })
+}

Diferenças do arquivo suprimidas por serem muito extensas
+ 270 - 237
src/views/living-home/elderlyManage/elderly-person-file-in/Form.vue


+ 10 - 9
src/views/living-home/elderlyManage/elderly-person-file-in/index.vue

@@ -22,12 +22,12 @@
         </el-form>
       </div>
     <el-divider style="margin-top: 0"/>
-      <view>
+      <div>
 <!--        <el-button :disabled="ids.length<=0" :loading="deleteBatchLoading" @click="handleDeleteBatch" type="warning">{{ids.length>0?`批量删除长者(已选:${ids.length})`:'批量删除长者'}}</el-button>-->
         <el-button type="primary" @click="add">新增</el-button>
         <el-button type="warning" @click="clickHandler">导入</el-button>
         <el-button type="success" @click="exportElderly">导出</el-button>
-      </view>
+      </div>
 
       <el-table
         v-loading="loading"
@@ -66,7 +66,7 @@
             <el-switch v-model="scope.row.isEnjoyService" active-value="1" inactive-value="0" disabled />
           </template>
         </el-table-column>
-        <el-table-column prop="serviceTimes" label="年享受服务次数" width="120" align="center" />
+        <el-table-column prop="serviceTimes" label="年享受服务次数" width="180" align="center" />
         <el-table-column prop="currentAddress" label="居住地址" width="200" show-overflow-tooltip />
         <el-table-column prop="registerTime" label="登记入住时间" width="180" />
 
@@ -109,7 +109,7 @@
     />
 
 
-    <Form ref="formRef"/>
+    <Form ref="formRef"  @success="getList"/>
 
 
   </div>
@@ -123,6 +123,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
 import Import from "@/components/ImportFile/index.vue";
 import Form from "./Form.vue";
 import {useUserStore} from "@/store/modules/user";
+import {deleteOutElderly, getHomeElderlyList} from "@/api/living-home/elderly";
 const router = useRouter()
 const userStore = useUserStore()
 const importRef = ref() //导入
@@ -256,7 +257,7 @@ const clickHandler = () => {
   importRef.value.open()
 }
 const add = () => {
-  formRef.value.open(1,false,1,queryParams.value.tenantIds)
+  formRef.value.open(undefined,false,queryParams.value.tenantIds)
 }
 
 // 处理日期范围变化
@@ -330,10 +331,10 @@ const getList = async () => {
     const params = {
       ...queryParams.value
     }
-    const res = await getElderlyList(params)
+    const res = await getHomeElderlyList(params)
     console.log('获取长者列表成功:', res)
     // 如果接口返回数据为空,使用默认假数据
-    elderlyList.value = res.list?.length > 0 ? res.list : defaultElderlyList
+    elderlyList.value = res.list?.length > 0 ? res.list : []
     total.value = res.total || elderlyList.value.length
   } catch (error) {
     console.error('获取长者列表失败:', error)
@@ -451,7 +452,7 @@ const exportElderly = async () => {
 
 // 编辑长者信息
 const handleEdit = async (row: any,detail:boolean) => {
-  formRef.value.open(row.id,detail,1,queryParams.value.tenantIds)
+  formRef.value.open(row.id,detail,queryParams.value.tenantIds)
 }
 
 
@@ -468,7 +469,7 @@ const handleDelete = async (row: any) => {
         type: 'warning'
       }
     )
-    await deleteElderly(row.id)
+    await deleteOutElderly(row.id)
 
     ElMessage.success('删除成功')
     await getList()

Diferenças do arquivo suprimidas por serem muito extensas
+ 270 - 238
src/views/living-home/elderlyManage/elderly-person-file-out/Form.vue


+ 51 - 143
src/views/living-home/elderlyManage/elderly-person-file-out/index.vue

@@ -22,12 +22,10 @@
         </el-form>
       </div>
     <el-divider style="margin-top: 0"/>
-      <view>
-<!--        <el-button :disabled="ids.length<=0" :loading="deleteBatchLoading" @click="handleDeleteBatch" type="warning">{{ids.length>0?`批量删除长者(已选:${ids.length})`:'批量删除长者'}}</el-button>-->
-
+      <div>
         <el-button type="warning" @click="clickHandler">导入</el-button>
         <el-button type="success" @click="exportElderly">导出</el-button>
-      </view>
+      </div>
 
       <el-table
         v-loading="loading"
@@ -66,13 +64,11 @@
             <el-switch v-model="scope.row.isEnjoyService" active-value="1" inactive-value="0" disabled />
           </template>
         </el-table-column>
-        <el-table-column prop="serviceTimes" label="年享受服务次数" width="120" align="center" />
+        <el-table-column prop="serviceTimes" label="年享受服务次数" width="180" align="center" />
         <el-table-column prop="currentAddress" label="居住地址" width="200" show-overflow-tooltip />
         <el-table-column prop="registerTime" label="登记入住时间" width="180" />
-        <el-table-column prop="checkoutTime" label="退住时间" width="180" />
-        <el-table-column prop="checkoutReason" label="退住原因" width="200" show-overflow-tooltip />
 
-        <el-table-column label="操作" width="220" fixed="right" align="center">
+        <el-table-column label="操作" width="200" fixed="right" align="center">
           <template #default="scope">
 
             <el-button type="text" @click="handleEdit(scope.row,false)">编辑</el-button>
@@ -111,7 +107,7 @@
     />
 
 
-    <Form ref="formRef"/>
+    <Form ref="formRef"  @success="getList"/>
 
 
   </div>
@@ -125,6 +121,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
 import Import from "@/components/ImportFile/index.vue";
 import Form from "./Form.vue";
 import {useUserStore} from "@/store/modules/user";
+import {deleteOutElderly, getHomeElderlyList} from "@/api/living-home/elderly";
 const router = useRouter()
 const userStore = useUserStore()
 const importRef = ref() //导入
@@ -163,6 +160,7 @@ const queryParams = ref({
   pageSize: 10,
   elderName: '',
   idCard: '',
+  checkIn: 0,
   personalPhone: '',
   //dateRange: currentMonthRange,
   // startDate: currentMonthRange[0],
@@ -182,21 +180,7 @@ const currentElderly = ref(null)
 
 
 
-// 表单验证规则
-const balanceRules = {
-  paymentType: [
-    { required: true, message: '请选择支付类型', trigger: 'change' }
-  ],
-  diningBalance: [
-    { required: true, message: '请输入堂食余额', trigger: 'blur' }
-  ],
-  deliveryBalance: [
-    { required: true, message: '请输入送餐余额', trigger: 'blur' }
-  ],
-  reason: [
-    { required: true, message: '请输入更新原因', trigger: 'blur' }
-  ]
-}
+
 
 
 
@@ -225,122 +209,64 @@ const handleDeleteBatch = async () => {
 
 
 
-// 编辑对话框
-const editVisible = ref(false)
-const editFormRef = ref()
-const editForm = ref({
-  id: '',
-  elderName: '',
-  idCard: '',
-  personalPhone: '',
-  emergencyContact: '',
-  emergencyContactPhone: '',
-  currentAddress: '',
-  status: '已失效',
-  tenantIds: userStore.orgTenantId
-})
-
-// 编辑表单验证规则
-const editRules = {
-  elderName: [
-    { required: true, message: '请输入姓名', trigger: 'blur' }
-  ],
-  gender: [],
-  age: [
-    { type: 'number', min: 1, max: 150, message: '年龄必须在1-150之间', trigger: 'blur' }
-  ],
-  idCard: [
-    { pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: '请输入正确的身份证号', trigger: 'blur' }
-  ],
-  personalPhone: [
-    { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
-  ],
-  emergencyContactPhone: [
-    { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
-  ],
-  status: [
-    { required: true, message: '请选择状态', trigger: 'change' }
-  ]
-}
-
-// 导航到指定页面
-const navigateTo = (path: string) => {
-  router.push(`/ykCenter/${path}`)
-}
-
 const clickHandler = () => {
   importRef.value.open()
 }
 const add = () => {
-  formRef.value.open(1,false,1,queryParams.value.tenantIds)
+  formRef.value.open(undefined,false,queryParams.value.tenantIds)
 }
 
-// 处理日期范围变化
-const handleDateChange = (value: any) => {
-  if (value && value.length === 2) {
-    queryParams.value.startDate = value[0]
-    queryParams.value.endDate = value[1]
-  } else {
-    queryParams.value.startDate = ''
-    queryParams.value.endDate = ''
-  }
-}
 
-// 默认假数据 - 退住长者
+
+// 默认假数据 - 在住长者
 const defaultElderlyList = [
   {
     id: '1',
-    elderName: '大爷',
+    elderName: '张大爷',
     gender: 1,
-    age: 80,
-    personalPhone: '13600136001',
-    homeTel: '0769-11112222',
-    selfCareStatus: '3',
-    liveSituation: '2',
-    voucherBalance: 200,
-    cashBalance: 800,
+    age: 78,
+    personalPhone: '13800138001',
+    homeTel: '0769-12345678',
+    selfCareStatus: '1',
+    liveSituation: '1',
+    voucherBalance: 500,
+    cashBalance: 1200,
     isEnjoyService: '1',
-    serviceTimes: 36,
-    currentAddress: '东莞市莞城区莞太路10号',
-    registerTime: '2022-05-15 10:30:00',
-    checkoutTime: '2024-06-20 15:00:00',
-    checkoutReason: '家属接回居家养老'
+    serviceTimes: 12,
+    currentAddress: '东莞市南城区宏图路1号',
+    registerTime: '2024-01-15 10:30:00'
   },
   {
     id: '2',
-    elderName: '奶奶',
+    elderName: '李奶奶',
     gender: 2,
-    age: 85,
-    personalPhone: '13500135002',
-    homeTel: '0769-33334444',
-    selfCareStatus: '4',
-    liveSituation: '3',
-    voucherBalance: 0,
-    cashBalance: 300,
-    isEnjoyService: '0',
-    serviceTimes: 48,
-    currentAddress: '东莞市厚街镇厚街大道20号',
-    registerTime: '2021-03-10 09:00:00',
-    checkoutTime: '2024-05-18 11:30:00',
-    checkoutReason: '转院至医疗机构'
+    age: 82,
+    personalPhone: '13900139002',
+    homeTel: '0769-87654321',
+    selfCareStatus: '2',
+    liveSituation: '2',
+    voucherBalance: 800,
+    cashBalance: 2500,
+    isEnjoyService: '1',
+    serviceTimes: 24,
+    currentAddress: '东莞市东城区东纵路2号',
+    registerTime: '2023-08-20 14:20:00'
   },
   {
     id: '3',
-    elderName: '爷爷',
+    elderName: '爷爷',
     gender: 1,
-    age: 77,
-    personalPhone: '13300133003',
-    homeTel: '0769-55556666',
-    selfCareStatus: '2',
+    age: 75,
+    personalPhone: '13700137003',
+    homeTel: '0769-11223344',
+    selfCareStatus: '1',
     liveSituation: '1',
-    voucherBalance: 100,
-    cashBalance: 600,
-    isEnjoyService: '1',
-    serviceTimes: 18,
-    currentAddress: '东莞市寮步镇寮步大道30号',
-    registerTime: '2023-01-20 14:00:00',
-    checkoutTime: '2024-04-25 16:45:00',
-    checkoutReason: '个人原因申请退住'
+    voucherBalance: 0,
+    cashBalance: 500,
+    isEnjoyService: '0',
+    serviceTimes: 0,
+    currentAddress: '东莞市万江区万道路3号',
+    registerTime: '2024-03-10 09:15:00'
   }
 ]
 
@@ -352,10 +278,10 @@ const getList = async () => {
     const params = {
       ...queryParams.value
     }
-    const res = await getElderlyList(params)
+    const res = await getHomeElderlyList(params)
     console.log('获取长者列表成功:', res)
     // 如果接口返回数据为空,使用默认假数据
-    elderlyList.value = res.list?.length > 0 ? res.list : defaultElderlyList
+    elderlyList.value = res.list?.length > 0 ? res.list : []
     total.value = res.total || elderlyList.value.length
   } catch (error) {
     console.error('获取长者列表失败:', error)
@@ -473,34 +399,16 @@ const exportElderly = async () => {
 
 // 编辑长者信息
 const handleEdit = async (row: any,detail:boolean) => {
-  formRef.value.open(row.id,detail,1,queryParams.value.tenantIds)
+  formRef.value.open(row.id,detail,queryParams.value.tenantIds)
 }
 
-// 提交编辑
-const submitEdit = async () => {
-  if (!editFormRef.value) return
 
-  await editFormRef.value.validate(async (valid: boolean) => {
-    if (valid) {
-      try {
-
-        await updateElderlyInfo(editForm.value)
-        ElMessage.success('长者信息更新成功')
-        editVisible.value = false
-        await getList()
-      } catch (error) {
-        console.error('更新长者信息失败:', error)
-        ElMessage.error('更新长者信息失败')
-      }
-    }
-  })
-}
 
 // 删除长者
 const handleDelete = async (row: any) => {
   try {
     await ElMessageBox.confirm(
-      `确定要恢复入住长者 "${row.elderName}" 吗?`,
+      `确定要退住长者 "${row.elderName}" 吗?`,
       '删除确认',
       {
         confirmButtonText: '确定',
@@ -508,9 +416,9 @@ const handleDelete = async (row: any) => {
         type: 'warning'
       }
     )
-    await deleteElderly(row.id)
+    //await deleteOutElderly(row.id)
 
-    ElMessage.success('删除成功')
+    //ElMessage.success('删除成功')
     await getList()
   } catch (error) {
     if (error !== 'cancel') {

+ 44 - 12
src/views/living-home/serviceItemManage/serviceCombo/addComboForm.vue

@@ -258,7 +258,8 @@ import { FormRules } from 'element-plus'
 import UploadImg from '@/components/UploadFile/src/UploadImg.vue'
 import UploadImgs from '@/components/UploadFile/src/UploadImgs.vue'
 import * as ServiceComboApi from '@/api/living-home/elderly'
-
+import {useUserStore} from "@/store/modules/user";
+const userStore = useUserStore()
 defineOptions({ name: 'ServiceComboForm' })
 
 const { t } = useI18n()
@@ -295,7 +296,8 @@ const formData = ref<ServiceComboApi.ServiceComboVO>({
   volunteerDeductFee: '否',
   servicePoints: undefined,
   staffCommissionType: '按单',
-  staffCommissionValue: undefined
+  staffCommissionValue: undefined,
+  tenantId: userStore.tenant.id
 })
 
 const formRules = reactive<FormRules>({
@@ -420,7 +422,7 @@ const handleCommissionTypeChange = (value: string) => {
 const open = async (type: string, id?: number) => {
   dialogVisible.value = true
   resetForm()
-  
+
   if (type === 'create') {
     dialogTitle.value = '新增服务套餐'
     formType.value = 'create'
@@ -431,17 +433,35 @@ const open = async (type: string, id?: number) => {
     dialogTitle.value = '服务套餐详情'
     formType.value = 'detail'
   }
-  
+
   if (id) {
     formLoading.value = true
     try {
       const data = await ServiceComboApi.getServiceCombo(id)
-      formData.value = data
-      if (data.comboItems) {
-        selectedItems.value = data.comboItems
+      // 回显时映射后端字段到前端表单
+      formData.value = {
+        id: data.id,
+        comboImage: data.icon || '',
+        serviceTypeId: data.categoryId,
+        comboName: data.packageName || '',
+        comboDetailIds: data.itemIds ? data.itemIds.split(',').map(Number) : [],
+        comboPrice: data.amount,
+        comboDescription: data.summarize || '',
+        comboDetailImages: data.detail || '',
+        isShelf: data.status === 1 ? '是' : '否',
+        volunteerDeductFee: data.isDeductVolunteerFee === 1 ? '是' : '否',
+        servicePoints: data.point,
+        staffCommissionType: data.commissionType === 1 ? '按比例' : '按单',
+        staffCommissionValue: data.commissionNumber,
+        tenantId: data.tenantId || userStore.tenant.id
+      }
+      if (data.itemIds) {
+        // 需要根据itemIds加载项目详情
+        const itemIds = data.itemIds.split(',').map(Number)
+        selectedItems.value = itemIds.map(id => ({ id }))
       }
-      if (data.comboDetailImages) {
-        comboDetailImages.value = data.comboDetailImages.split(',')
+      if (data.detail) {
+        comboDetailImages.value = data.detail.split(',')
       }
     } finally {
       formLoading.value = false
@@ -459,11 +479,23 @@ const submitForm = async () => {
 
   formLoading.value = true
   try {
+    // 构建后端需要的参数格式
     const submitData = {
-      ...formData.value,
-      comboDetailImages: comboDetailImages.value.join(',')
+      id: formData.value.id || 0,
+      categoryId: formData.value.serviceTypeId || 0,
+      packageName: formData.value.comboName || '',
+      itemIds: formData.value.comboDetailIds.join(','),
+      amount: formData.value.comboPrice || 0,
+      summarize: formData.value.comboDescription || '',
+      detail: comboDetailImages.value.join(','),
+      status: formData.value.isShelf === '是' ? 1 : 0,
+      commissionType: formData.value.staffCommissionType === '按比例' ? 1 : 0,
+      commissionNumber: formData.value.staffCommissionValue || 0,
+      isDeductVolunteerFee: formData.value.volunteerDeductFee === '是' ? 1 : 0,
+      point: formData.value.servicePoints || 0,
+      tenantId: formData.value.tenantId || userStore.tenant.id
     }
-    
+
     if (formType.value === 'create') {
       await ServiceComboApi.createServiceCombo(submitData)
       message.success(t('common.createSuccess'))

+ 1 - 86
src/views/living-home/serviceItemManage/serviceCombo/index.vue

@@ -28,83 +28,7 @@ const mockServiceTypes = [
   { id: 5, name: '文化娱乐' }
 ]
 
-/** 测试数据 - 服务套餐列表 */
-const mockCombos = [
-  {
-    id: 1,
-    comboName: '居家照护套餐',
-    serviceTypeName: '生活照料',
-    serviceTypeId: 1,
-    comboImage: '',
-    comboItems: [
-      { id: 1, serviceName: '居家清洁服务', servicePrice: 80, serviceDescription: '提供家庭日常清洁服务' },
-      { id: 2, serviceName: '助餐送餐服务', servicePrice: 25, serviceDescription: '提供营养配餐及送餐上门' }
-    ],
-    comboPrice: 105.00,
-    discountedPrice: 94.50,
-    billingMethod: '按次',
-    servicePoints: 13,
-    volunteerDeductFee: '否',
-    isShelf: '是',
-    staffCommissionType: '按单',
-    staffCommissionValue: 20
-  },
-  {
-    id: 2,
-    comboName: '医疗护理套餐',
-    serviceTypeName: '医疗护理',
-    serviceTypeId: 2,
-    comboImage: '',
-    comboItems: [
-      { id: 3, serviceName: '陪同就医服务', servicePrice: 120, serviceDescription: '陪同长者前往医院就诊' },
-      { id: 4, serviceName: '健康体检服务', servicePrice: 200, serviceDescription: '提供全面健康检查' }
-    ],
-    comboPrice: 320.00,
-    discountedPrice: 288.00,
-    billingMethod: '按次',
-    servicePoints: 35,
-    volunteerDeductFee: '否',
-    isShelf: '是',
-    staffCommissionType: '按比例',
-    staffCommissionValue: 8
-  },
-  {
-    id: 3,
-    comboName: '康复保健套餐',
-    serviceTypeName: '康复保健',
-    serviceTypeId: 3,
-    comboImage: '',
-    comboItems: [
-      { id: 5, serviceName: '康复训练指导', servicePrice: 150, serviceDescription: '专业康复师一对一指导' }
-    ],
-    comboPrice: 150.00,
-    discountedPrice: 135.00,
-    billingMethod: '按时',
-    servicePoints: 18,
-    volunteerDeductFee: '否',
-    isShelf: '否',
-    staffCommissionType: '按单',
-    staffCommissionValue: 30
-  },
-  {
-    id: 4,
-    comboName: '精神关怀套餐',
-    serviceTypeName: '精神慰藉',
-    serviceTypeId: 4,
-    comboImage: '',
-    comboItems: [
-      { id: 6, serviceName: '心理疏导服务', servicePrice: 100, serviceDescription: '专业心理咨询师服务' }
-    ],
-    comboPrice: 100.00,
-    discountedPrice: 90.00,
-    billingMethod: '按时',
-    servicePoints: 12,
-    volunteerDeductFee: '是',
-    isShelf: '是',
-    staffCommissionType: '按比例',
-    staffCommissionValue: 12
-  }
-]
+
 
 /** 获取服务类别列表 */
 const getServiceTypeList = async () => {
@@ -125,15 +49,6 @@ const getList = async () => {
     list.value = data.list || data || []
   } catch (error) {
     console.log('获取服务套餐列表失败,使用测试数据')
-    let filteredData = [...mockCombos]
-    if (queryParams.serviceTypeId) {
-      filteredData = filteredData.filter(item => item.serviceTypeId === queryParams.serviceTypeId)
-    }
-    if (queryParams.comboName) {
-      filteredData = filteredData.filter(item => 
-        item.comboName.includes(queryParams.comboName)
-      )
-    }
     list.value = filteredData
   } finally {
     loading.value = false

+ 48 - 10
src/views/living-home/serviceItemManage/serviceItem/addItemForm.vue

@@ -236,7 +236,8 @@ import { FormRules } from 'element-plus'
 import UploadImg from '@/components/UploadFile/src/UploadImg.vue'
 import UploadImgs from '@/components/UploadFile/src/UploadImgs.vue'
 import * as ServiceItemApi from '@/api/living-home/elderly'
-
+import {useUserStore} from "@/store/modules/user";
+const userStore = useUserStore()
 defineOptions({ name: 'ServiceItemForm' })
 
 const { t } = useI18n()
@@ -266,7 +267,8 @@ const formData = ref<ServiceItemApi.ServiceItemVO>({
   servicePoints: undefined,
   needVisit: '是',
   checkMedicationTaboo: '否',
-  serviceContentStandard: ''
+  serviceContentStandard: '',
+  tenantId: userStore.tenant.id
 })
 
 const formRules = reactive<FormRules>({
@@ -299,7 +301,7 @@ const handleCommissionTypeChange = (value: string) => {
 const open = async (type: string, id?: number) => {
   dialogVisible.value = true
   resetForm()
-  
+
   if (type === 'create') {
     dialogTitle.value = '新增服务'
     formType.value = 'create'
@@ -310,14 +312,33 @@ const open = async (type: string, id?: number) => {
     dialogTitle.value = '服务详情'
     formType.value = 'detail'
   }
-  
+
   if (id) {
     formLoading.value = true
     try {
       const data = await ServiceItemApi.getServiceItem(id)
-      formData.value = data
-      if (data.serviceDetail) {
-        serviceDetailImages.value = data.serviceDetail.split(',')
+      // 回显时映射后端字段到前端表单
+      formData.value = {
+        id: data.id,
+        serviceImage: data.icon || '',
+        serviceTypeId: data.categoryId,
+        serviceName: data.itemName || '',
+        servicePrice: data.amount,
+        serviceDescription: data.summarize || '',
+        serviceDetail: data.detail || '',
+        isShelf: data.status === 1 ? '是' : '否',
+        billingMethod: data.costType === 1 ? '按时' : '按次',
+        deductElderFee: data.isDeductElderFee === 1 ? '是' : '否',
+        staffCommissionType: data.commissionType === 1 ? '按比例' : '按单',
+        staffCommissionValue: data.commissionNumber,
+        volunteerDeductFee: data.isDeductVolunteerFee === 1 ? '是' : '否',
+        servicePoints: data.point,
+        needVisit: data.isFollowUpVisit === 1 ? '是' : '否',
+        checkMedicationTaboo: data.isCheckDrugContraindications === 1 ? '是' : '否',
+        serviceContentStandard: data.content || ''
+      }
+      if (data.detail) {
+        serviceDetailImages.value = data.detail.split(',')
       }
     } finally {
       formLoading.value = false
@@ -335,11 +356,28 @@ const submitForm = async () => {
 
   formLoading.value = true
   try {
+    // 构建后端需要的参数格式
     const submitData = {
-      ...formData.value,
-      serviceDetail: serviceDetailImages.value.join(',')
+      id: formData.value.id || 0,
+      categoryId: formData.value.serviceTypeId || 0,
+      itemName: formData.value.serviceName || '',
+      icon: formData.value.serviceImage || '',
+      summarize: formData.value.serviceDescription || '',
+      detail: serviceDetailImages.value.join(','),
+      amount: formData.value.servicePrice || 0,
+      status: formData.value.isShelf === '是' ? 1 : 0,
+      costType: formData.value.billingMethod === '按时' ? 1 : 0,
+      isDeductElderFee: formData.value.deductElderFee === '是' ? 1 : 0,
+      commissionType: formData.value.staffCommissionType === '按比例' ? 1 : 0,
+      commissionNumber: formData.value.staffCommissionValue || 0,
+      isDeductVolunteerFee: formData.value.volunteerDeductFee === '是' ? 1 : 0,
+      point: formData.value.servicePoints || 0,
+      isFollowUpVisit: formData.value.needVisit === '是' ? 1 : 0,
+      isCheckDrugContraindications: formData.value.checkMedicationTaboo === '是' ? 1 : 0,
+      content: formData.value.serviceContentStandard || '',
+      tenantId: userStore.tenant.id // 租户ID,根据实际业务需求设置
     }
-    
+
     if (formType.value === 'create') {
       await ServiceItemApi.createServiceItem(submitData)
       message.success(t('common.createSuccess'))

+ 21 - 9
src/views/living-home/serviceItemManage/serviceType/ServiceTypeForm.vue

@@ -32,7 +32,8 @@
 <script lang="ts" setup>
 import { FormRules } from 'element-plus'
 import * as ServiceTypeApi from '@/api/living-home/elderly'
-
+import {useUserStore} from "@/store/modules/user";
+const userStore = useUserStore()
 defineOptions({ name: 'ServiceTypeForm' })
 
 const { t } = useI18n()
@@ -45,12 +46,11 @@ const formType = ref('')
 const formData = ref<ServiceTypeApi.ServiceTypeVO>({
   id: undefined,
   name: '',
-  selfCareSituation: [],
-  remark: ''
+  remark: '',
+  tenantId: userStore.tenant.id
 })
 const formRules = reactive<FormRules>({
-  name: [{ required: true, message: '服务类别不能为空', trigger: 'blur' }],
-  selfCareSituation: [{ required: true, message: '请选择关联自理情况', trigger: 'change', type: 'array' }]
+  name: [{ required: true, message: '服务类别不能为空', trigger: 'blur' }]
 })
 const formRef = ref()
 
@@ -64,7 +64,12 @@ const open = async (type: string, id?: number) => {
     formLoading.value = true
     try {
       const data = await ServiceTypeApi.getServiceType(id)
-      formData.value = data
+      // 回显时映射后端字段到前端表单
+      formData.value = {
+        id: data.id,
+        name: data.name,
+        remark: data.remark
+      }
     } finally {
       formLoading.value = false
     }
@@ -81,11 +86,19 @@ const submitForm = async () => {
 
   formLoading.value = true
   try {
+    // 构建后端需要的参数格式
+    const submitData = {
+      id: formData.value.id || 0,
+      superiorId: 0,
+      name: formData.value.name,
+      remark: formData.value.remark || '',
+      tenantId: userStore.tenant.id // 租户ID,根据实际业务需求设置
+    }
     if (formType.value === 'create') {
-      await ServiceTypeApi.createServiceType(formData.value)
+      await ServiceTypeApi.createServiceType(submitData)
       message.success(t('common.createSuccess'))
     } else {
-      await ServiceTypeApi.updateServiceType(formData.value)
+      await ServiceTypeApi.updateServiceType(submitData)
       message.success(t('common.updateSuccess'))
     }
     dialogVisible.value = false
@@ -100,7 +113,6 @@ const resetForm = () => {
   formData.value = {
     id: undefined,
     name: '',
-    selfCareSituation: [],
     remark: ''
   }
   formRef.value?.resetFields()

+ 56 - 22
src/views/living-home/serviceTeam/districtManagement/ServiceAreaForm.vue

@@ -40,9 +40,9 @@ import * as ServiceAreaApi from '@/api/living-home/elderly'
 import * as AreaApi from '@/api/system/area'
 import { FormRules } from 'element-plus'
 import {defaultProps} from "@/utils/tree";
-
+import { useUserStore } from '@/store/modules/user'
 defineOptions({ name: 'ServiceAreaForm' })
-
+const userStore = useUserStore()
 const { t } = useI18n() // 国际化
 const message = useMessage() // 消息弹窗
 
@@ -50,11 +50,12 @@ const dialogVisible = ref(false) // 弹窗的是否展示
 const dialogTitle = ref('') // 弹窗的标题
 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
 const formType = ref('') // 表单的类型:create - 新增;update - 修改
-const formData = ref<ServiceAreaApi.ServiceAreaVO>({
+const formData = ref<any>({
   id: undefined,
   areaCode: [],
-  areaName: '',
-  remark: ''
+  area: '',
+  remark: '',
+  tenantId: userStore.orgTenantId && userStore.orgTenantId.length ? userStore.orgTenantId[0] : [],
 })
 const formRules = reactive<FormRules>({
   areaCode: [{ required: true, message: '服务区域不能为空', trigger: 'change' }]
@@ -78,9 +79,21 @@ const open = async (type: string, id?: number) => {
     formLoading.value = true
     try {
       const data = await ServiceAreaApi.getServiceArea(id)
+      // area 存储的是区域代码字符串,可能是单个代码 "130304" 或完整路径 "120000,120100,120102"
+      let areaCodeArr: number[] = []
+      if (data.area) {
+        const codes = data.area.split(',').map(Number)
+        if (codes.length === 1) {
+          // 单个代码,查找完整路径
+          areaCodeArr = findFullPath(areaTree.value, codes[0])
+        } else {
+          // 已经是完整路径
+          areaCodeArr = codes
+        }
+      }
       formData.value = {
         ...data,
-        areaCode: data.areaCode ? data.areaCode.split(',').map(Number) : []
+        areaCode: areaCodeArr
       }
     } finally {
       formLoading.value = false
@@ -95,6 +108,23 @@ const open = async (type: string, id?: number) => {
 }
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 
+/** 根据最后一个code查找完整路径 */
+const findFullPath = (tree: any[], targetCode: number): number[] => {
+  for (const node of tree) {
+    const nodeId = node.id || node.value
+    if (nodeId === targetCode) {
+      return [targetCode]
+    }
+    if (node.children && node.children.length > 0) {
+      const path = findFullPath(node.children, targetCode)
+      if (path.length > 0) {
+        return [nodeId, ...path]
+      }
+    }
+  }
+  return []
+}
+
 /** 提交表单 */
 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
 const submitForm = async () => {
@@ -105,9 +135,23 @@ const submitForm = async () => {
   // 提交请求
   formLoading.value = true
   try {
-    const data = { ...formData.value } as ServiceAreaApi.ServiceAreaVO
+    const areaCodeVal = formData.value.areaCode
+    
+    // 处理级联选择器的值:可能是数组 [110000,110100,110101] 或单个值 150823
+    let areaCodeStr = ''
+    if (Array.isArray(areaCodeVal)) {
+      areaCodeStr = areaCodeVal.join(',')
+    } else if (areaCodeVal !== undefined && areaCodeVal !== null && areaCodeVal !== '') {
+      // 单个值,直接转为字符串
+      areaCodeStr = String(areaCodeVal)
+    }
 
-    // 获取区域名称
+    const data: ServiceAreaApi.ServiceAreaVO = {
+      id: formData.value.id,
+      area: areaCodeStr,  // 存储区域代码字符串
+      remark: formData.value.remark,
+      tenantId: formData.value.tenantId
+    }
 
     if (formType.value === 'create') {
       await ServiceAreaApi.createServiceArea(data)
@@ -124,26 +168,16 @@ const submitForm = async () => {
   }
 }
 
-/** 根据区域代码获取区域名称 */
-const getAreaNameByCode = async (areaCode: string): Promise<string> => {
-  const codes = areaCode.split(',').map(Number)
-  const names: string[] = []
-  for (const code of codes) {
-    const area = await AreaApi.getArea(code)
-    if (area) {
-      names.push(area.name)
-    }
-  }
-  return names.join('/')
-}
+
 
 /** 重置表单 */
 const resetForm = () => {
   formData.value = {
     id: undefined,
     areaCode: [],
-    areaName: '',
-    remark: ''
+    area: '',
+    remark: '',
+    tenantId: userStore.orgTenantId && userStore.orgTenantId.length ? userStore.orgTenantId[0] : [],
   }
   formRef.value?.resetFields()
 }

+ 80 - 57
src/views/living-home/serviceTeam/districtManagement/index.vue

@@ -7,21 +7,20 @@
         <el-button type="primary" @click="openForm('create')">
           <Icon icon="ep:plus" class="mr-5px" /> 新增
         </el-button>
-        <el-button type="danger" @click="handleBatchDelete" :disabled="!selectedIds.length">
-          <Icon icon="ep:delete" class="mr-5px" /> 删除
-        </el-button>
       </div>
     </div>
     <el-table
       v-loading="loading"
       :data="list"
-      @selection-change="handleSelectionChange"
     >
-      <el-table-column type="selection" width="55" />
       <el-table-column type="index" label="序号" width="80" />
-      <el-table-column prop="areaName" label="服务区域" />
-      <el-table-column prop="areaName" label="备注" />
-      <el-table-column label="操作" align="center" width="120">
+      <el-table-column label="服务区域">
+        <template #default="scope">
+          {{ getAreaNameByCode(scope.row.area) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="remark" label="备注" />
+      <el-table-column label="操作" align="center" width="180">
         <template #default="scope">
           <el-button
             link
@@ -30,6 +29,13 @@
           >
             <Icon icon="ep:edit" class="mr-5px" /> 编辑
           </el-button>
+          <el-button
+            link
+            type="danger"
+            @click="handleDelete(scope.row.id)"
+          >
+            <Icon icon="ep:delete" class="mr-5px" /> 删除
+          </el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -40,8 +46,10 @@
 </template>
 <script lang="ts" setup>
 import * as ServiceAreaApi from '@/api/living-home/elderly'
+import * as AreaApi from '@/api/system/area'
 import ServiceAreaForm from './ServiceAreaForm.vue'
-
+import {useUserStore} from "@/store/modules/user";
+const userStore = useUserStore()
 defineOptions({ name: 'ServiceArea' })
 
 const message = useMessage() // 消息弹窗
@@ -49,81 +57,96 @@ const { t } = useI18n() // 国际化
 
 const loading = ref(true) // 列表的加载中
 const list = ref<ServiceAreaApi.ServiceAreaVO[]>([]) // 列表的数据
-const selectedIds = ref<number[]>([]) // 选中的ID列表
+const areaTree = ref<any[]>([]) // 区域树数据
 
-// 默认测试数据
-const defaultData: ServiceAreaApi.ServiceAreaVO[] = [
-  {
-    id: 1,
-    areaCode: '441900',
-    areaName: '东莞市/茶山镇',
-    remark: '服务人员、应急人员、志愿者可选择此区域提供服务'
-  },
-  {
-    id: 2,
-    areaCode: '341600,341621,341621100',
-    areaName: '亳州市/涡阳县/陈大镇',
-    remark: '主要服务区域,覆盖多个社区'
-  },
-  {
-    id: 3,
-    areaCode: '440300,440305',
-    areaName: '深圳市/南山区',
-    remark: '南山区全部街道'
-  },
-  {
-    id: 4,
-    areaCode: '440100,440106',
-    areaName: '广州市/天河区',
-    remark: '天河区核心服务区域'
-  },
-  {
-    id: 5,
-    areaCode: '440600,440604',
-    areaName: '佛山市/禅城区',
-    remark: '禅城区志愿者服务范围'
+/** 根据区域代码字符串获取区域名称 */
+const getAreaNameByCode = (areaCodeStr: string): string => {
+  if (!areaCodeStr) return ''
+  
+  // 可能是单个代码 "130304" 或多个代码 "120000,120100,120102"
+  const codes = areaCodeStr.split(',').map(Number)
+  
+  // 如果只有一个代码,需要查找完整路径
+  if (codes.length === 1) {
+    const fullPath = findFullPath(areaTree.value, codes[0])
+    if (fullPath.length > 0) {
+      return getNamesFromPath(areaTree.value, fullPath)
+    }
   }
-]
+  
+  // 多个代码,直接按路径查找
+  return getNamesFromPath(areaTree.value, codes)
+}
 
+/** 根据最后一个code查找完整路径 */
+const findFullPath = (tree: any[], targetCode: number): number[] => {
+  for (const node of tree) {
+    const nodeId = node.id || node.value
+    if (nodeId === targetCode) {
+      return [targetCode]
+    }
+    if (node.children && node.children.length > 0) {
+      const path = findFullPath(node.children, targetCode)
+      if (path.length > 0) {
+        return [nodeId, ...path]
+      }
+    }
+  }
+  return []
+}
+
+/** 根据路径获取名称 */
+const getNamesFromPath = (tree: any[], codes: number[]): string => {
+  const names: string[] = []
+  let currentTree = tree
+  
+  for (const code of codes) {
+    const node = currentTree.find((item: any) => (item.id || item.value) === code)
+    if (node) {
+      names.push(node.name || node.label)
+      currentTree = node.children || []
+    } else {
+      break
+    }
+  }
+  
+  return names.join('/')
+}
 /** 查询服务区域列表 */
 const getList = async () => {
   loading.value = true
   try {
-    // 先尝试从接口获取数据
+    // 先加载区域树数据(用于转换代码为名称)
+    if (areaTree.value.length === 0) {
+      areaTree.value = await AreaApi.getAreaTree()
+    }
+    
+    // 获取服务区域列表
     const data = await ServiceAreaApi.getServiceAreaList()
     // 如果接口返回数据为空,则使用默认数据
-    list.value = data && data.length > 0 ? data : defaultData
+    list.value = data.list && data.list.length > 0 ? data.list : []
   } catch (error) {
     // 接口调用失败时,使用默认数据
     console.log('使用默认数据')
-    list.value = defaultData
+
   } finally {
     loading.value = false
   }
 }
 
-/** 多选框选中数据 */
-const handleSelectionChange = (selection: ServiceAreaApi.ServiceAreaVO[]) => {
-  selectedIds.value = selection.map((item) => item.id)
-}
-
 /** 添加/修改操作 */
 const formRef = ref()
 const openForm = (type: string, id?: number) => {
   formRef.value.open(type, id)
 }
 
-/** 批量删除按钮操作 */
-const handleBatchDelete = async () => {
-  if (selectedIds.value.length === 0) {
-    message.warning('请选择要删除的数据')
-    return
-  }
+/** 删除按钮操作 */
+const handleDelete = async (id: number) => {
   try {
     // 删除的二次确认
     await message.delConfirm()
     // 发起删除
-    await ServiceAreaApi.deleteServiceArea(selectedIds.value)
+    await ServiceAreaApi.deleteServiceArea(id)
     message.success(t('common.delSuccess'))
     // 刷新列表
     await getList()

+ 40 - 56
src/views/living-home/serviceTeam/serviceDepartment/DeptForm.vue

@@ -5,27 +5,25 @@
       v-loading="formLoading"
       :model="formData"
       :rules="formRules"
-      label-width="80px"
+      label-width="100px"
     >
-      <el-form-item label="上级部门" prop="parentId">
+      <el-form-item label="上级部门" prop="superiorId">
         <el-tree-select
-          v-model="formData.parentId"
+          v-model="formData.superiorId"
           :data="deptTree"
           :props="defaultProps"
           check-strictly
           default-expand-all
           placeholder="请选择上级部门"
-          value-key="deptId"
+          value-key="id"
         />
       </el-form-item>
       <el-form-item label="部门名称" prop="name">
         <el-input v-model="formData.name" placeholder="请输入部门名称" />
       </el-form-item>
-      <el-form-item label="显示排序" prop="sort">
-        <el-input-number v-model="formData.sort" :min="0" controls-position="right" />
-      </el-form-item>
-      <el-form-item label="负责人" prop="leaderUserId">
-        <el-select v-model="formData.leaderUserId" clearable placeholder="请输入负责人">
+
+      <el-form-item label="负责人" prop="responsiblePersonId">
+        <el-select v-model="formData.responsiblePersonId" clearable placeholder="请选择负责人">
           <el-option
             v-for="item in userList"
             :key="item.id"
@@ -40,16 +38,7 @@
       <el-form-item label="邮箱" prop="email">
         <el-input v-model="formData.email" maxlength="50" placeholder="请输入邮箱" />
       </el-form-item>
-      <el-form-item label="状态" prop="status">
-        <el-select v-model="formData.status" clearable placeholder="请选择状态">
-          <el-option
-            v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
+
     </el-form>
     <template #footer>
       <el-button type="primary" @click="submitForm">确 定</el-button>
@@ -58,11 +47,9 @@
   </Dialog>
 </template>
 <script lang="ts" setup>
-import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 import { defaultProps, handleTree } from '@/utils/tree'
-import * as DeptApi from '@/api/system/dept'
+import * as DeptApi from '@/api/system/user'
 import * as UserApi from '@/api/system/user'
-import { CommonStatusEnum } from '@/utils/constants'
 import { FormRules } from 'element-plus'
 
 defineOptions({ name: 'SystemDeptForm' })
@@ -74,30 +61,27 @@ const dialogVisible = ref(false) // 弹窗的是否展示
 const dialogTitle = ref('') // 弹窗的标题
 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
 const formType = ref('') // 表单的类型:create - 新增;update - 修改
-const formData = ref({
+const formData = ref<DeptApi.ServiceDeptVO>({
   id: undefined,
-  title: '',
-  parentId: undefined,
-  name: undefined,
-  sort: undefined,
-  leaderUserId: undefined,
-  phone: undefined,
-  email: undefined,
-  status: CommonStatusEnum.ENABLE
+  superiorId: 0,
+  name: '',
+  responsiblePersonId: undefined,
+  phone: '',
+  email: '',
+  tenantId: undefined
 })
 const formRules = reactive<FormRules>({
-  parentId: [{ required: true, message: '上级部门不能为空', trigger: 'blur' }],
+  superiorId: [{ required: true, message: '上级部门不能为空', trigger: 'blur' }],
   name: [{ required: true, message: '部门名称不能为空', trigger: 'blur' }],
-  sort: [{ required: true, message: '显示排序不能为空', trigger: 'blur' }],
   email: [{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }],
   phone: [
     { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' }
-  ],
-  status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
+  ]
 })
 const formRef = ref() // 表单 Ref
-const deptTree = ref() // 树形结构
+
 const userList = ref<UserApi.UserVO[]>([]) // 用户列表
+const deptTree = ref() // 树形结构
 
 /** 打开弹窗 */
 const open = async (type: string, id?: number) => {
@@ -109,7 +93,7 @@ const open = async (type: string, id?: number) => {
   if (id) {
     formLoading.value = true
     try {
-      formData.value = await DeptApi.getDept(id)
+      formData.value = await DeptApi.getServiceDept(id)
     } finally {
       formLoading.value = false
     }
@@ -121,6 +105,15 @@ const open = async (type: string, id?: number) => {
 }
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 
+/** 获得部门树 */
+const getTree = async () => {
+  deptTree.value = []
+  const data = await DeptApi.getServiceDeptList()
+  let dept: Tree = { id: 0, name: '顶级部门', children: [] }
+  dept.children = handleTree(data)
+  deptTree.value.push(dept)
+}
+
 /** 提交表单 */
 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
 const submitForm = async () => {
@@ -131,12 +124,12 @@ const submitForm = async () => {
   // 提交请求
   formLoading.value = true
   try {
-    const data = formData.value as unknown as DeptApi.DeptVO
+    const data = formData.value
     if (formType.value === 'create') {
-      await DeptApi.createDept(data)
+      await DeptApi.createServiceDept(data)
       message.success(t('common.createSuccess'))
     } else {
-      await DeptApi.updateDept(data)
+      await DeptApi.updateServiceDept(data)
       message.success(t('common.updateSuccess'))
     }
     dialogVisible.value = false
@@ -151,24 +144,15 @@ const submitForm = async () => {
 const resetForm = () => {
   formData.value = {
     id: undefined,
-    title: '',
-    parentId: undefined,
-    name: undefined,
-    sort: undefined,
-    leaderUserId: undefined,
-    phone: undefined,
-    email: undefined,
-    status: CommonStatusEnum.ENABLE
+    superiorId: 0,
+    name: '',
+    responsiblePersonId: undefined,
+    phone: '',
+    email: '',
+    tenantId: undefined
   }
   formRef.value?.resetFields()
 }
 
-/** 获得部门树 */
-const getTree = async () => {
-  deptTree.value = []
-  const data = await DeptApi.getSimpleDeptList()
-  let dept: Tree = { id: 0, name: '顶级部门', children: [] }
-  dept.children = handleTree(data)
-  deptTree.value.push(dept)
-}
+
 </script>

+ 18 - 30
src/views/living-home/serviceTeam/serviceDepartment/index.vue

@@ -17,21 +17,7 @@
           class="!w-240px"
         />
       </el-form-item>
-      <el-form-item label="部门状态" prop="status">
-        <el-select
-          v-model="queryParams.status"
-          placeholder="请选择部门状态"
-          clearable
-          class="!w-240px"
-        >
-          <el-option
-            v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
+
       <el-form-item>
         <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
         <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
@@ -46,6 +32,7 @@
         <el-button type="danger" plain @click="toggleExpandAll">
           <Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
         </el-button>
+    
       </el-form-item>
     </el-form>
   </ContentWrap>
@@ -59,18 +46,14 @@
       :default-expand-all="isExpandAll"
       v-if="refreshTable"
     >
+
       <el-table-column prop="name" label="部门名称" />
       <el-table-column prop="leader" label="负责人">
         <template #default="scope">
-          {{ userList.find((user) => user.id === scope.row.leaderUserId)?.nickname }}
-        </template>
-      </el-table-column>
-      <el-table-column prop="sort" label="排序" />
-      <el-table-column prop="status" label="状态">
-        <template #default="scope">
-          <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
+          {{ userList.find((user) => user.id === scope.row.responsiblePersonId)?.nickname }}
         </template>
       </el-table-column>
+
       <el-table-column
         label="创建时间"
         align="center"
@@ -105,13 +88,13 @@
   <DeptForm ref="formRef" @success="getList" />
 </template>
 <script lang="ts" setup>
-import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 import { dateFormatter } from '@/utils/formatTime'
 import { handleTree } from '@/utils/tree'
-import * as DeptApi from '@/api/system/dept'
+import * as DeptApi from '@/api/system/user'
 import DeptForm from './DeptForm.vue'
 import * as UserApi from '@/api/system/user'
-
+import {useUserStore} from "@/store/modules/user";
+const userStore = useUserStore()
 defineOptions({ name: 'SystemDept' })
 
 const message = useMessage() // 消息弹窗
@@ -123,18 +106,21 @@ const queryParams = reactive({
   pageNo: 1,
   pageSize: 100,
   name: undefined,
-  status: undefined
+  status: undefined,
+  tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref() // 搜索的表单
+
+const userList = ref<UserApi.UserVO[]>([]) // 用户列表
+
 const isExpandAll = ref(true) // 是否展开,默认全部展开
 const refreshTable = ref(true) // 重新渲染表格状态
-const userList = ref<UserApi.UserVO[]>([]) // 用户列表
 
 /** 查询部门列表 */
 const getList = async () => {
   loading.value = true
   try {
-    const data = await DeptApi.getDeptPage(queryParams)
+    const data = await DeptApi.getServiceDeptList(queryParams)
     list.value = handleTree(data)
   } finally {
     loading.value = false
@@ -150,6 +136,8 @@ const toggleExpandAll = () => {
   })
 }
 
+
+
 /** 搜索按钮操作 */
 const handleQuery = () => {
   getList()
@@ -174,7 +162,7 @@ const handleDelete = async (id: number) => {
     // 删除的二次确认
     await message.delConfirm()
     // 发起删除
-    await DeptApi.deleteDept(id)
+    await DeptApi.deleteServiceDept(id)
     message.success(t('common.delSuccess'))
     // 刷新列表
     await getList()
@@ -185,6 +173,6 @@ const handleDelete = async (id: number) => {
 onMounted(async () => {
   await getList()
   // 获取用户列表
-  userList.value = await UserApi.getSimpleUserList()
+  //userList.value = await UserApi.getSimpleUserList()
 })
 </script>

+ 95 - 12
src/views/living-home/serviceTeam/servicePersonnelManage/ServicePersonForm.vue

@@ -60,14 +60,27 @@
       <el-row :gutter="20">
         <el-col :span="12">
           <el-form-item label="服务区域:" prop="serviceAreaId">
-            <el-select v-model="formData.serviceAreaId" placeholder="请选择" class="!w-full" :disabled="isReadonly">
+            <!-- 编辑/新增模式:使用下拉选择器 -->
+            <el-select
+              v-if="!isReadonly"
+              v-model="formData.serviceAreaId"
+              placeholder="请选择"
+              class="!w-full"
+            >
               <el-option
                 v-for="item in serviceAreaList"
                 :key="item.id"
-                :label="item.areaName"
+                :label="getServiceAreaName(item.area)"
                 :value="item.id"
               />
             </el-select>
+            <!-- 详情模式:直接显示中文名称 -->
+            <el-input
+              v-else
+              :model-value="getServiceAreaNameById(formData.serviceAreaId)"
+              disabled
+              class="!w-full"
+            />
             <div v-if="!isReadonly" class="text-red-500 text-xs mt-1">
               提示:请先在"服务团队管理-服务区域设置"中添加服务区域。
             </div>
@@ -92,7 +105,9 @@
       <el-form-item label="居住地址:" prop="address" style="width: 100%;">
         <el-row :gutter="10" style="width: 100%;">
           <el-col :span="12">
+            <!-- 编辑/新增模式:使用级联选择器 -->
             <el-cascader
+              v-if="!isReadonly"
               v-model="formData.areaCode"
               :options="areaTree"
               :props="defaultProps"
@@ -100,7 +115,13 @@
               clearable
               filterable
               class="!w-full"
-              :disabled="isReadonly"
+            />
+            <!-- 详情模式:直接显示中文地址 -->
+            <el-input
+              v-else
+              :model-value="getAreaName(formData.areaCode)"
+              disabled
+              class="!w-full"
             />
           </el-col>
           <el-col :span="12">
@@ -190,6 +211,59 @@ const loadAreaTree = async () => {
   }
 }
 
+/** 根据区域代码数组获取中文地址名称 */
+const getAreaName = (areaCode: number[]): string => {
+  if (!areaCode || areaCode.length === 0) return ''
+  
+  const names: string[] = []
+  let currentList = areaTree.value
+  
+  for (const code of areaCode) {
+    const found = currentList.find((item: any) => item.id === code)
+    if (found) {
+      names.push(found.name)
+      currentList = found.children || []
+    } else {
+      break
+    }
+  }
+  
+  return names.join(' / ')
+}
+
+/** 根据区域码(如150523)从areaTree中查找完整中文路径(省/市/区) */
+const getServiceAreaName = (areaCode: string | number): string => {
+  if (!areaCode) return ''
+  const code = String(areaCode)
+  
+  // 递归查找区域及其完整路径
+  const findAreaPath = (list: any[], parentPath: string[] = []): string => {
+    for (const item of list) {
+      const currentPath = [...parentPath, item.name]
+      if (String(item.id) === code) {
+        return currentPath.join(' / ')
+      }
+      if (item.children && item.children.length > 0) {
+        const found = findAreaPath(item.children, currentPath)
+        if (found) return found
+      }
+    }
+    return ''
+  }
+  
+  return findAreaPath(areaTree.value) || code
+}
+
+/** 根据服务区域ID查找对应的中文名称 */
+const getServiceAreaNameById = (serviceAreaId: number | undefined): string => {
+  if (!serviceAreaId) return ''
+  const item = serviceAreaList.value.find((area: any) => area.id === serviceAreaId)
+  if (item && item.area) {
+    return getServiceAreaName(item.area)
+  }
+  return ''
+}
+
 /** 打开弹窗 */
 const open = async (type: string, id?: number) => {
   dialogVisible.value = true
@@ -219,6 +293,10 @@ const open = async (type: string, id?: number) => {
       const data = await ServicePersonApi.getServicePerson(id)
       formData.value = {
         ...data,
+        // 字段映射:后端字段 -> 表单字段
+        gender: data.sex, // sex -> gender
+        deptId: data.serviceDeptId, // serviceDeptId -> deptId
+        serviceAreaId: data.serviceAreaId ? Number(data.serviceAreaId) : undefined,
         areaCode: data.areaCode ? data.areaCode.split(',').map(Number) : []
       }
     } finally {
@@ -232,7 +310,7 @@ defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 const loadServiceAreaList = async () => {
   try {
     const data = await ServicePersonApi.getServiceAreaList()
-    serviceAreaList.value = data || []
+    serviceAreaList.value = data.list || []
   } catch (error) {
     console.error('加载服务区域失败:', error)
   }
@@ -256,20 +334,25 @@ const submitForm = async () => {
   if (!formRef) return
   const valid = await formRef.value.validate()
   if (!valid) return
-  
+
   formLoading.value = true
   try {
-    const data = { ...formData.value } as any
-    // 将级联选择的数组转换为字符串
-    if (Array.isArray(data.areaCode)) {
-      data.areaCode = data.areaCode.join(',')
+    // 字段映射:将表单字段转换为后端需要的字段
+    const submitData = {
+      id: formData.value.id,
+      name: formData.value.name,
+      idCard: formData.value.idCard,
+      sex: formData.value.gender, // gender -> sex
+      phone: formData.value.phone,
+      serviceAreaId: formData.value.serviceAreaId,
+      serviceDeptId: formData.value.deptId // deptId -> serviceDeptId
     }
-    
+
     if (formType.value === 'create') {
-      await ServicePersonApi.createServicePerson(data)
+      await ServicePersonApi.createServicePerson(submitData)
       message.success(t('common.createSuccess'))
     } else {
-      await ServicePersonApi.updateServicePerson(data)
+      await ServicePersonApi.updateServicePerson(submitData)
       message.success(t('common.updateSuccess'))
     }
     dialogVisible.value = false

+ 29 - 94
src/views/living-home/serviceTeam/servicePersonnelManage/index.vue

@@ -125,7 +125,8 @@
 import * as ServicePersonApi from '@/api/living-home/elderly'
 import ServicePersonForm from './ServicePersonForm.vue'
 import RelateElderDialog from './RelateElderDialog.vue'
-
+import {useUserStore} from "@/store/modules/user";
+const userStore = useUserStore()
 defineOptions({ name: 'ServicePersonnelManage' })
 
 const message = useMessage() // 消息弹窗
@@ -141,83 +142,34 @@ const queryParams = reactive({
   name: '',
   phone: '',
   serviceArea: '',
-  status: ''
+  status: '',
+  tenantIds: userStore.orgTenantId
 })
 
 // 服务区域选项(从默认数据中提取)
-const serviceAreaOptions = computed(() => {
-  const areas = new Set(defaultData.map(item => item.serviceArea))
-  return Array.from(areas)
-})
+const serviceAreaOptions = ref([])
+/** 查询服务区域列表 */
+const getServiceAreaOptionsList = async () => {
+  loading.value = true
+  try {
+    // 先加载区域树数据(用于转换代码为名称)
+    if (areaTree.value.length === 0) {
+      areaTree.value = await AreaApi.getAreaTree()
+    }
+
+    // 获取服务区域列表
+    const data = await ServiceAreaApi.getServiceAreaList()
+    // 如果接口返回数据为空,则使用默认数据
+    list.value = data.list && data.list.length > 0 ? data.list : []
+  } catch (error) {
+    // 接口调用失败时,使用默认数据
+    console.log('使用默认数据')
 
-// 默认数据
-const defaultData: ServicePersonApi.ServicePersonVO[] = [
-  {
-    id: 1,
-    name: '张磊',
-    idCard: '43********30',
-    gender: '男',
-    age: '36',
-    phone: '198****9999',
-    personType: '服务人员',
-    elderCount: 0,
-    serviceArea: '东莞市/茶山镇',
-    organization: '客服部',
-    status: '在职'
-  },
-  {
-    id: 2,
-    name: '李华',
-    idCard: '44********21',
-    gender: '女',
-    age: '32',
-    phone: '139****8888',
-    personType: '服务人员',
-    elderCount: 3,
-    serviceArea: '深圳市/南山区',
-    organization: '护理部',
-    status: '在职'
-  },
-  {
-    id: 3,
-    name: '王强',
-    idCard: '11********55',
-    gender: '男',
-    age: '45',
-    phone: '136****6666',
-    personType: '应急人员',
-    elderCount: 5,
-    serviceArea: '广州市/天河区',
-    organization: '应急部',
-    status: '在职'
-  },
-  {
-    id: 4,
-    name: '赵敏',
-    idCard: '31********88',
-    gender: '女',
-    age: '28',
-    phone: '158****7777',
-    personType: '志愿者',
-    elderCount: 2,
-    serviceArea: '佛山市/禅城区',
-    organization: '志愿者协会',
-    status: '在职'
-  },
-  {
-    id: 5,
-    name: '刘洋',
-    idCard: '22********99',
-    gender: '男',
-    age: '38',
-    phone: '137****5555',
-    personType: '服务人员',
-    elderCount: 1,
-    serviceArea: '中山市/石岐区',
-    organization: '服务部',
-    status: '在职'
+  } finally {
+    loading.value = false
   }
-]
+}
+
 
 /** 查询服务人员列表 */
 const getList = async () => {
@@ -226,30 +178,11 @@ const getList = async () => {
     // 先尝试从接口获取数据
     const data = await ServicePersonApi.getServicePersonList(queryParams)
     // 如果接口返回数据为空,则使用默认数据
-    let result = data && data.length > 0 ? data : defaultData
-    
-    // 前端筛选(如果使用默认数据)
-    if (result === defaultData) {
-      result = result.filter(item => {
-        const matchName = !queryParams.name || item.name.includes(queryParams.name)
-        const matchPhone = !queryParams.phone || item.phone.includes(queryParams.phone)
-        const matchArea = !queryParams.serviceArea || item.serviceArea === queryParams.serviceArea
-        const matchStatus = !queryParams.status || item.status === queryParams.status
-        return matchName && matchPhone && matchArea && matchStatus
-      })
-    }
-    
-    list.value = result
+    let result = data && data.length > 0 ? data : []
+    list.value = result.list
   } catch (error) {
     // 接口调用失败时,使用默认数据并筛选
     console.log('使用默认数据')
-    list.value = defaultData.filter(item => {
-      const matchName = !queryParams.name || item.name.includes(queryParams.name)
-      const matchPhone = !queryParams.phone || item.phone.includes(queryParams.phone)
-      const matchArea = !queryParams.serviceArea || item.serviceArea === queryParams.serviceArea
-      const matchStatus = !queryParams.status || item.status === queryParams.status
-      return matchName && matchPhone && matchArea && matchStatus
-    })
   } finally {
     loading.value = false
   }
@@ -268,6 +201,7 @@ const resetQuery = () => {
   queryParams.serviceArea = ''
   queryParams.status = ''
   getList()
+  getServiceAreaOptionsList()
 }
 
 /** 多选框选中数据 */
@@ -337,5 +271,6 @@ const handleResign = async (row: ServicePersonApi.ServicePersonVO) => {
 /** 初始化 **/
 onMounted(async () => {
   await getList()
+  getServiceAreaOptionsList()
 })
 </script>

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff