Ver código fonte

Merge branch 'master' of http://47.107.245.0:3000/xiongxing/kyj-yanglao-web-new

xiongxing 3 semanas atrás
pai
commit
73deed5ca8
33 arquivos alterados com 1283 adições e 686 exclusões
  1. 4 0
      src/views/elderly/apply/nine-precautions/MMSE/AddForm.vue
  2. 40 16
      src/views/elderly/apply/nine-precautions/MMSE/index.vue
  3. 4 0
      src/views/elderly/apply/nine-precautions/anti-entertainment/AddForm.vue
  4. 41 16
      src/views/elderly/apply/nine-precautions/anti-entertainment/index.vue
  5. 4 0
      src/views/elderly/apply/nine-precautions/asphyxiation-by-choking/AddForm.vue
  6. 39 14
      src/views/elderly/apply/nine-precautions/asphyxiation-by-choking/index.vue
  7. 4 0
      src/views/elderly/apply/nine-precautions/attack/AddForm.vue
  8. 40 16
      src/views/elderly/apply/nine-precautions/attack/index.vue
  9. 4 0
      src/views/elderly/apply/nine-precautions/commit-suicide/AddForm.vue
  10. 85 18
      src/views/elderly/apply/nine-precautions/commit-suicide/index.vue
  11. 4 0
      src/views/elderly/apply/nine-precautions/communication/AddForm.vue
  12. 40 18
      src/views/elderly/apply/nine-precautions/communication/index.vue
  13. 4 0
      src/views/elderly/apply/nine-precautions/daily-life/AddForm.vue
  14. 0 1
      src/views/elderly/apply/nine-precautions/daily-life/index.vue
  15. 4 0
      src/views/elderly/apply/nine-precautions/empyrosis/AddForm.vue
  16. 41 16
      src/views/elderly/apply/nine-precautions/empyrosis/index.vue
  17. 356 414
      src/views/elderly/apply/nine-precautions/equilibrium/AddForm.vue
  18. 41 16
      src/views/elderly/apply/nine-precautions/equilibrium/index.vue
  19. 4 0
      src/views/elderly/apply/nine-precautions/fall-down/AddForm.vue
  20. 41 16
      src/views/elderly/apply/nine-precautions/fall-down/index.vue
  21. 4 0
      src/views/elderly/apply/nine-precautions/fall-prevention-measures/AddForm.vue
  22. 41 16
      src/views/elderly/apply/nine-precautions/fall-prevention-measures/index.vue
  23. 5 1
      src/views/elderly/apply/nine-precautions/nutritional-risk/AddForm.vue
  24. 4 0
      src/views/elderly/apply/nine-precautions/pressure-sores/AddForm.vue
  25. 41 16
      src/views/elderly/apply/nine-precautions/pressure-sores/index.vue
  26. 1 1
      src/views/elderly/apply/nine-precautions/risk-disclosure-statement/Form.vue
  27. 4 0
      src/views/elderly/apply/nine-precautions/wander-away/AddForm.vue
  28. 86 18
      src/views/elderly/apply/nine-precautions/wander-away/index.vue
  29. 65 0
      src/views/elderly/elder/elder-file/index.vue
  30. 110 48
      src/views/elderly/elder/family-appointment/time-setting/index.vue
  31. 46 0
      src/views/elderly/fee/bill-pay/index.vue
  32. 1 1
      src/views/elderly/fee/daily-fee/index.vue
  33. 75 24
      src/views/elderly/fee/leave-settle/index.vue

+ 4 - 0
src/views/elderly/apply/nine-precautions/MMSE/AddForm.vue

@@ -347,9 +347,11 @@
 import { computed, ref } from 'vue'
 
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
 
 import {mmseCreate, mmseGetById, mmseUpdate} from "@/api/social-work";
 const message = useMessage() // 消息弹窗
+const userStore = useUserStore()
 const { t } = useI18n() // 国际化
 const title = ref('')
 const dialogVisible = ref(false) // 弹窗
@@ -740,6 +742,7 @@ const handleExport = () => {
   const getNamingMark = (score) => score === 1 ? '☑ 正确 (1分)' : '☐ 错误 (0分)'
 
   // 构建打印内容
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
   const printContent = `
     <!DOCTYPE html>
     <html>
@@ -942,6 +945,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <h1>简易精神状态评价量表(MMSE)</h1>
         <div class="sub-title">Mini-Mental State Examination</div>

+ 40 - 16
src/views/elderly/apply/nine-precautions/MMSE/index.vue

@@ -18,6 +18,23 @@
         />
       </el-form-item>
 
+      <el-form-item label="风险等级">
+        <el-select v-model="queryParams.risk" class="!w-240px">
+          <el-option
+            v-for="(item, index) in [
+              { label: '无风险', value: 'none' },
+              { label: '低风险', value: 'low' },
+              { label: '中风险', value: 'medium' },
+              { label: '高风险', value: 'high' }
+            ]"
+            :key="index"
+            placeholder="请选择"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+
       <el-form-item label="楼栋">
         <el-select
           v-model="queryParams.buildId"
@@ -84,7 +101,7 @@
       <ButtonAdd @click="openForm(undefined)" />
       <ButtonImport @click="handleImportCard" />
       <!--      <el-button @click="inputH" type="success"><Icon icon="fa:cloud-upload" :size="16" class="mr-1"/>导入</el-button>-->
-</div>
+    </div>
     <el-table v-loading="loading" :data="list" :header-cell-style="tableHeaderColor">
       <el-table-column header-align="center" align="center" label="序号" width="60">
         <template #default="scope">
@@ -218,6 +235,7 @@ let queryParams = reactive({
   elderName: '',
   assessor: '',
   floorId: '',
+  risk: '',
   // assessorDate: getCurrentMonthRange(),
   assessDate: [],
   tenantIds: userStore.orgTenantId
@@ -232,6 +250,7 @@ const handleImportCard = async () => {
       pageNo: 1,
       pageSize: 9999,
       elderName: queryParams.elderName,
+      risk: queryParams.risk,
       assessor: queryParams.assessor,
       assessDate: queryParams.assessDate,
       tenantIds: queryParams.tenantIds
@@ -260,32 +279,37 @@ const handleImportCard = async () => {
 
     const headers = [
       {
-            'key': 'orgName',
-            'title': '机构名称'
+        key: 'orgName',
+        title: '机构名称'
       },
       {
-            'key': 'elderName',
-            'title': '长者姓名'
+        key: 'elderName',
+        title: '长者姓名'
       },
       {
-            'key': 'assessor',
-            'title': '评估人'
+        key: 'assessor',
+        title: '评估人'
       },
       {
-            'key': 'assessDate',
-            'title': '记录日期'
+        key: 'assessDate',
+        title: '记录日期'
       },
       {
-            'key': 'riskLevelText',
-            'title': '风险等级'
+        key: 'riskLevelText',
+        title: '风险等级'
       },
       {
-            'key': 'creator',
-            'title': '记录人'
+        key: 'creator',
+        title: '记录人'
       }
-]
+    ]
 
-    exportWithExpandedObjectArrays(processedData, headers, `MMSE认知评估_${new Date().getTime()}.xlsx`, 'MMSE认知评估')
+    await exportWithExpandedObjectArrays(
+      processedData,
+      headers,
+      `MMSE认知评估_${new Date().getTime()}.xlsx`,
+      'MMSE认知评估'
+    )
     message.success('导出成功')
   } catch (error) {
     console.error('导出失败:', error)
@@ -295,7 +319,6 @@ const handleImportCard = async () => {
   }
 }
 
-
 const inputH = () => {
   importRef.value.open(queryParams.tenantIds[0])
 }
@@ -326,6 +349,7 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.floorId = ''
+  queryParams.risk = ''
   queryParams.tenantIds = userStore.orgTenantId
   // queryParams.assessorDate= getCurrentMonthRange()
   queryParams.assessDate = []

+ 4 - 0
src/views/elderly/apply/nine-precautions/anti-entertainment/AddForm.vue

@@ -242,12 +242,14 @@
 <script lang="ts" setup>
 import { computed, ref, reactive } from 'vue'
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
 import {
   entertainmentCreate, entertainmentGetById, entertainmentUpdate,
   fallDownPage, wanderAwayPage, ngasrPage,
 } from "@/api/social-work";
 
 const message = useMessage()
+const userStore = useUserStore()
 const { t } = useI18n()
 const title = ref('')
 const dialogVisible = ref(false)
@@ -637,6 +639,7 @@ const handleExport = () => {
   ]
 
   // 构建打印内容
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
   const printContent = `
     <!DOCTYPE html>
     <html>
@@ -796,6 +799,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <h1>防文娱活动意外评估表</h1>
       </div>

+ 41 - 16
src/views/elderly/apply/nine-precautions/anti-entertainment/index.vue

@@ -18,6 +18,23 @@
         />
       </el-form-item>
 
+      <el-form-item label="风险等级">
+        <el-select v-model="queryParams.risk" class="!w-240px">
+          <el-option
+            v-for="(item, index) in [
+              { label: '无风险', value: 'none' },
+              { label: '低风险', value: 'low' },
+              { label: '中风险', value: 'medium' },
+              { label: '高风险', value: 'high' }
+            ]"
+            :key="index"
+            placeholder="请选择"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+
       <el-form-item label="楼栋">
         <el-select
           v-model="queryParams.buildId"
@@ -209,6 +226,7 @@ let queryParams = reactive({
   assessor: '',
   floorId: '',
   buildId: '',
+  risk: '',
   // assessDate: getCurrentMonthRange(),
   assessDate: [],
   tenantIds: userStore.orgTenantId
@@ -223,6 +241,7 @@ const handleImportCard = async () => {
       pageNo: 1,
       pageSize: 9999,
       elderName: queryParams.elderName,
+      risk: queryParams.risk,
       assessor: queryParams.assessor,
       assessDate: queryParams.assessDate,
       tenantIds: queryParams.tenantIds
@@ -250,36 +269,41 @@ const handleImportCard = async () => {
 
     const headers = [
       {
-            'key': 'orgName',
-            'title': '机构名称'
+        key: 'orgName',
+        title: '机构名称'
       },
       {
-            'key': 'elderName',
-            'title': '长者姓名'
+        key: 'elderName',
+        title: '长者姓名'
       },
       {
-            'key': 'assessor',
-            'title': '评估人'
+        key: 'assessor',
+        title: '评估人'
       },
       {
-            'key': 'assessDate',
-            'title': '记录日期'
+        key: 'assessDate',
+        title: '记录日期'
       },
       {
-            'key': 'assessScore',
-            'title': '评估总得分'
+        key: 'assessScore',
+        title: '评估总得分'
       },
       {
-            'key': 'riskLevelText',
-            'title': '风险等级'
+        key: 'riskLevelText',
+        title: '风险等级'
       },
       {
-            'key': 'creator',
-            'title': '记录人'
+        key: 'creator',
+        title: '记录人'
       }
-]
+    ]
 
-    exportWithExpandedObjectArrays(processedData, headers, `防文娱活动意外评估_${new Date().getTime()}.xlsx`, '防文娱活动意外评估')
+    await exportWithExpandedObjectArrays(
+      processedData,
+      headers,
+      `防文娱活动意外评估_${new Date().getTime()}.xlsx`,
+      '防文娱活动意外评估'
+    )
     message.success('导出成功')
   } catch (error) {
     console.error('导出失败:', error)
@@ -316,6 +340,7 @@ const resetQuery = () => {
   queryParams.assessor = ''
   queryParams.floorId = ''
   queryParams.buildId = ''
+  queryParams.risk = ''
   queryParams.tenantIds = userStore.orgTenantId
   // queryParams.assessDate = getCurrentMonthRange()
   queryParams.assessDate = []

+ 4 - 0
src/views/elderly/apply/nine-precautions/asphyxiation-by-choking/AddForm.vue

@@ -165,6 +165,7 @@
 <script lang="ts" setup>
 import { ref, reactive } from 'vue'
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
 import {
   asphyxiationCreate,
   asphyxiationGetById,
@@ -172,6 +173,7 @@ import {
 } from "@/api/social-work";
 
 const message = useMessage()
+const userStore = useUserStore()
 const { t } = useI18n()
 const title = ref('')
 const dialogVisible = ref(false)
@@ -467,6 +469,7 @@ const handleExport = () => {
     return `<div class="prevention-item">${checked}${option}</div>`
   }).join('')
 
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
   const printContent = `
     <!DOCTYPE html>
     <html>
@@ -561,6 +564,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <div class="title">防噎食评估表</div>
       </div>

+ 39 - 14
src/views/elderly/apply/nine-precautions/asphyxiation-by-choking/index.vue

@@ -18,6 +18,23 @@
         />
       </el-form-item>
 
+      <el-form-item label="风险等级">
+        <el-select v-model="queryParams.risk" class="!w-240px">
+          <el-option
+            v-for="(item, index) in [
+              { label: '无风险', value: 'none' },
+              { label: '低风险', value: 'low' },
+              { label: '中风险', value: 'medium' },
+              { label: '高风险', value: 'high' }
+            ]"
+            :key="index"
+            placeholder="请选择"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+
       <el-form-item label="评估人">
         <el-input v-model="queryParams.assessor" placeholder="评估人" class="!w-240px" clearable />
       </el-form-item>
@@ -166,6 +183,7 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
+  risk: '',
   // assessDate: getCurrentMonthRange(),
   assessDate: [],
   tenantIds: userStore.orgTenantId
@@ -181,6 +199,7 @@ const handleImportCard = async () => {
       pageSize: 9999,
       elderName: queryParams.elderName,
       assessor: queryParams.assessor,
+      risk: queryParams.risk,
       assessDate: queryParams.assessDate,
       tenantIds: queryParams.tenantIds
     }
@@ -207,32 +226,37 @@ const handleImportCard = async () => {
 
     const headers = [
       {
-            'key': 'orgName',
-            'title': '机构名称'
+        key: 'orgName',
+        title: '机构名称'
       },
       {
-            'key': 'elderName',
-            'title': '长者姓名'
+        key: 'elderName',
+        title: '长者姓名'
       },
       {
-            'key': 'assessor',
-            'title': '评估人'
+        key: 'assessor',
+        title: '评估人'
       },
       {
-            'key': 'assessDate',
-            'title': '记录日期'
+        key: 'assessDate',
+        title: '记录日期'
       },
       {
-            'key': 'riskLevelText',
-            'title': '风险等级'
+        key: 'riskLevelText',
+        title: '风险等级'
       },
       {
-            'key': 'creator',
-            'title': '记录人'
+        key: 'creator',
+        title: '记录人'
       }
-]
+    ]
 
-    exportWithExpandedObjectArrays(processedData, headers, `防噎食评估_${new Date().getTime()}.xlsx`, '防噎食评估')
+    await exportWithExpandedObjectArrays(
+      processedData,
+      headers,
+      `防噎食评估_${new Date().getTime()}.xlsx`,
+      '防噎食评估'
+    )
     message.success('导出成功')
   } catch (error) {
     console.error('导出失败:', error)
@@ -267,6 +291,7 @@ const handleQuery = async () => {
 const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
+  queryParams.risk = ''
   queryParams.tenantIds = userStore.orgTenantId
   // queryParams.assessDate = getCurrentMonthRange()
   queryParams.assessDate = []

+ 4 - 0
src/views/elderly/apply/nine-precautions/attack/AddForm.vue

@@ -242,9 +242,11 @@
 import { computed, ref, watch } from 'vue'
 
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
 
 import { attackRiskCreate, attackRiskGetById, attackRiskUpdate, attackRiskGetByElderId } from "@/api/social-work";
 const message = useMessage() // 消息弹窗
+const userStore = useUserStore()
 const { t } = useI18n() // 国际化
 const title = ref('')
 const dialogVisible = ref(false) // 弹窗
@@ -588,6 +590,7 @@ const handleExport = () => {
   }
 
   // 构建打印内容
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
   const printContent = `
     <!DOCTYPE html>
     <html>
@@ -791,6 +794,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <h1>攻击风险因素评估量表</h1>
       </div>

+ 40 - 16
src/views/elderly/apply/nine-precautions/attack/index.vue

@@ -18,6 +18,23 @@
         />
       </el-form-item>
 
+      <el-form-item label="风险等级">
+        <el-select v-model="queryParams.risk" class="!w-240px">
+          <el-option
+            v-for="(item, index) in [
+              { label: '无风险', value: 'none' },
+              { label: '低风险', value: 'low' },
+              { label: '中风险', value: 'medium' },
+              { label: '高风险', value: 'high' }
+            ]"
+            :key="index"
+            placeholder="请选择"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+
       <el-form-item label="楼栋">
         <el-select
           v-model="queryParams.buildId"
@@ -84,7 +101,7 @@
       <ButtonAdd @click="openForm(undefined)" />
       <ButtonImport @click="handleImportCard" />
       <!--      <el-button @click="inputH" type="success"><Icon icon="fa:cloud-upload" :size="16" class="mr-1"/>导入</el-button>-->
-</div>
+    </div>
     <el-table v-loading="loading" :data="list" :header-cell-style="tableHeaderColor">
       <el-table-column header-align="center" align="center" label="序号" width="60">
         <template #default="scope">
@@ -221,6 +238,7 @@ let queryParams = reactive({
   assessor: '',
   floorId: '',
   buildId: '',
+  risk: '',
   // assessDate: getCurrentMonthRange(),
   assessDate: [],
   tenantIds: userStore.orgTenantId
@@ -235,6 +253,7 @@ const handleImportCard = async () => {
       pageNo: 1,
       pageSize: 9999,
       elderName: queryParams.elderName,
+      risk: queryParams.risk,
       assessor: queryParams.assessor,
       assessDate: queryParams.assessDate,
       tenantIds: queryParams.tenantIds
@@ -263,32 +282,37 @@ const handleImportCard = async () => {
 
     const headers = [
       {
-            'key': 'orgName',
-            'title': '机构名称'
+        key: 'orgName',
+        title: '机构名称'
       },
       {
-            'key': 'elderName',
-            'title': '长者姓名'
+        key: 'elderName',
+        title: '长者姓名'
       },
       {
-            'key': 'assessor',
-            'title': '评估人'
+        key: 'assessor',
+        title: '评估人'
       },
       {
-            'key': 'riskLevelText',
-            'title': '风险等级'
+        key: 'riskLevelText',
+        title: '风险等级'
       },
       {
-            'key': 'assessDate',
-            'title': '记录日期'
+        key: 'assessDate',
+        title: '记录日期'
       },
       {
-            'key': 'creator',
-            'title': '记录人'
+        key: 'creator',
+        title: '记录人'
       }
-]
+    ]
 
-    exportWithExpandedObjectArrays(processedData, headers, `攻击风险评估_${new Date().getTime()}.xlsx`, '攻击风险评估')
+    await exportWithExpandedObjectArrays(
+      processedData,
+      headers,
+      `攻击风险评估_${new Date().getTime()}.xlsx`,
+      '攻击风险评估'
+    )
     message.success('导出成功')
   } catch (error) {
     console.error('导出失败:', error)
@@ -298,7 +322,6 @@ const handleImportCard = async () => {
   }
 }
 
-
 /** 查询列表 */
 const getList = async () => {
   loading.value = true
@@ -327,6 +350,7 @@ const resetQuery = () => {
   queryParams.assessor = ''
   queryParams.floorId = ''
   queryParams.buildId = ''
+  queryParams.risk = ''
   queryParams.tenantIds = userStore.orgTenantId
   // queryParams.assessDate= getCurrentMonthRange()
   queryParams.assessDate = []

+ 4 - 0
src/views/elderly/apply/nine-precautions/commit-suicide/AddForm.vue

@@ -168,9 +168,11 @@
 import { computed, ref, watch } from 'vue'
 
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
 
 import { ngasrCreate, ngasrGetById, ngasrUpdate, ngasrGetByElderId } from "@/api/social-work";
 const message = useMessage() // 消息弹窗
+const userStore = useUserStore()
 const { t } = useI18n() // 国际化
 const title = ref('')
 const dialogVisible = ref(false) // 弹窗
@@ -510,6 +512,7 @@ const handleExport = () => {
   }).join('')
 
   // 构建打印内容
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
   const printContent = `
     <!DOCTYPE html>
     <html>
@@ -714,6 +717,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <h1>自杀风险评估量表(NGASR)</h1>
       </div>

+ 85 - 18
src/views/elderly/apply/nine-precautions/commit-suicide/index.vue

@@ -18,6 +18,49 @@
         />
       </el-form-item>
 
+      <el-form-item label="风险等级">
+        <el-select v-model="queryParams.risk" class="!w-240px">
+          <el-option
+            v-for="(item, index) in [
+              { label: '无风险', value: 'none' },
+              { label: '低风险', value: 'low' },
+              { label: '中风险', value: 'medium' },
+              { label: '高风险', value: 'high' }
+            ]"
+            :key="index"
+            placeholder="请选择"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+
+      <el-form-item label="楼栋">
+        <el-select
+          v-model="queryParams.buildId"
+          placeholder="选择楼栋"
+          style="width: 180px"
+          @change="handleBuildChange"
+        >
+          <el-option
+            v-for="(item, index) in buildList"
+            :key="index"
+            :label="item.buildName"
+            :value="item.id"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="楼层">
+        <el-select v-model="queryParams.floorId" placeholder="选择楼层" style="width: 180px">
+          <el-option
+            v-for="(item, index) in floorList"
+            :key="index"
+            :label="item.floorName"
+            :value="item.id"
+          />
+        </el-select>
+      </el-form-item>
+
       <el-form-item label="评估人">
         <el-input
           v-model="queryParams.assessor"
@@ -58,7 +101,7 @@
       <ButtonAdd @click="openForm(undefined)" />
       <ButtonImport @click="handleImportCard" />
       <!--      <el-button @click="inputH" type="success"><Icon icon="fa:cloud-upload" :size="16" class="mr-1"/>导入</el-button>-->
-</div>
+    </div>
     <el-table v-loading="loading" :data="list" :header-cell-style="tableHeaderColor">
       <el-table-column header-align="center" align="center" label="序号" width="60">
         <template #default="scope">
@@ -174,6 +217,8 @@ import { ngasrDelete, ngasrPage } from '@/api/social-work'
 import { exportWithExpandedObjectArrays } from '@/utils/excel-export'
 import { getRiskLevelInfo } from '@/utils/risk-assessment'
 import { findLabelById } from '@/utils/dict'
+import { ref } from 'vue'
+import { getBuildList } from '@/api/system/badManage'
 const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
 const userStore = useUserStore()
@@ -189,6 +234,7 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
+  risk: '',
   // assessDate: getCurrentMonthRange(),
   assessDate: [],
   tenantIds: userStore.orgTenantId
@@ -203,6 +249,7 @@ const handleImportCard = async () => {
       pageNo: 1,
       pageSize: 9999,
       elderName: queryParams.elderName,
+      risk: queryParams.risk,
       assessor: queryParams.assessor,
       assessDate: queryParams.assessDate,
       tenantIds: queryParams.tenantIds
@@ -231,32 +278,37 @@ const handleImportCard = async () => {
 
     const headers = [
       {
-            'key': 'orgName',
-            'title': '机构名称'
+        key: 'orgName',
+        title: '机构名称'
       },
       {
-            'key': 'elderName',
-            'title': '长者姓名'
+        key: 'elderName',
+        title: '长者姓名'
       },
       {
-            'key': 'assessor',
-            'title': '评估人'
+        key: 'assessor',
+        title: '评估人'
       },
       {
-            'key': 'assessDate',
-            'title': '记录日期'
+        key: 'assessDate',
+        title: '记录日期'
       },
       {
-            'key': 'riskLevelText',
-            'title': '风险等级'
+        key: 'riskLevelText',
+        title: '风险等级'
       },
       {
-            'key': 'creator',
-            'title': '记录人'
+        key: 'creator',
+        title: '记录人'
       }
-]
+    ]
 
-    exportWithExpandedObjectArrays(processedData, headers, `自伤自杀风险评估_${new Date().getTime()}.xlsx`, '自伤自杀风险评估')
+    await exportWithExpandedObjectArrays(
+      processedData,
+      headers,
+      `自伤自杀风险评估_${new Date().getTime()}.xlsx`,
+      '自伤自杀风险评估'
+    )
     message.success('导出成功')
   } catch (error) {
     console.error('导出失败:', error)
@@ -266,7 +318,6 @@ const handleImportCard = async () => {
   }
 }
 
-
 /** 查询列表 */
 const getList = async () => {
   loading.value = true
@@ -293,6 +344,9 @@ const handleQuery = async () => {
 const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
+  queryParams.floorId = ''
+  queryParams.buildId = ''
+  queryParams.risk = ''
   queryParams.tenantIds = userStore.orgTenantId
   // queryParams.assessDate= getCurrentMonthRange()
   queryParams.assessDate = []
@@ -350,13 +404,26 @@ const cancelDelete = async (id: number) => {
   } catch {}
 }
 
+const floorList = ref([])
+const buildList = ref([])
+const handleBuildChange = (buildId: any) => {
+  const selectedBuild = buildList.value.find((item: any) => item.id === buildId)
+  if (selectedBuild) {
+    floorList.value = selectedBuild.floorList || []
+  }
+}
+
 const route = useRoute()
 /** 初始化 **/
-onMounted(() => {
+onMounted(async () => {
   if (route.query && route.query.elderName) {
     queryParams.elderName = route.query.elderName as string
   }
-  getList()
+  await getList()
+
+  try {
+    buildList.value = await getBuildList({ tenantIds: queryParams.tenantIds[0] })
+  } catch (e) {}
 })
 
 // 表头格式

+ 4 - 0
src/views/elderly/apply/nine-precautions/communication/AddForm.vue

@@ -207,9 +207,11 @@
 import { computed, ref } from 'vue'
 
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
 
 import { perceptionCreate, perceptionGetById, perceptionUpdate, perceptionGetByElderId } from "@/api/social-work";
 const message = useMessage() // 消息弹窗
+const userStore = useUserStore()
 const { t } = useI18n() // 国际化
 const title = ref('')
 const dialogVisible = ref(false) // 弹窗
@@ -509,6 +511,7 @@ const handleExport = () => {
   }
 
   // 构建打印内容
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
   const printContent = `
     <!DOCTYPE html>
     <html>
@@ -722,6 +725,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <h1>感知觉与沟通评估表</h1>
       </div>

+ 40 - 18
src/views/elderly/apply/nine-precautions/communication/index.vue

@@ -18,6 +18,23 @@
         />
       </el-form-item>
 
+      <el-form-item label="风险等级">
+        <el-select v-model="queryParams.risk" class="!w-240px">
+          <el-option
+            v-for="(item, index) in [
+              { label: '无风险', value: 'none' },
+              { label: '低风险', value: 'low' },
+              { label: '中风险', value: 'medium' },
+              { label: '高风险', value: 'high' }
+            ]"
+            :key="index"
+            placeholder="请选择"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+
       <el-form-item label="楼栋">
         <el-select
           v-model="queryParams.buildId"
@@ -84,7 +101,7 @@
       <ButtonAdd @click="openForm(undefined)" />
       <ButtonImport @click="handleImportCard" />
       <!--      <el-button @click="inputH" type="success"><Icon icon="fa:cloud-upload" :size="16" class="mr-1"/>导入</el-button>-->
-</div>
+    </div>
     <el-table v-loading="loading" :data="list" :header-cell-style="tableHeaderColor">
       <el-table-column header-align="center" align="center" label="序号" width="60">
         <template #default="scope">
@@ -218,6 +235,7 @@ let queryParams = reactive({
   elderName: '',
   assessor: '',
   floorId: '',
+  risk: '',
   // assessDate: getCurrentMonthRange(),
   assessDate: [],
   tenantIds: userStore.orgTenantId
@@ -232,6 +250,7 @@ const handleImportCard = async () => {
       pageNo: 1,
       pageSize: 9999,
       elderName: queryParams.elderName,
+      risk: queryParams.risk,
       assessor: queryParams.assessor,
       assessDate: queryParams.assessDate,
       tenantIds: queryParams.tenantIds
@@ -260,32 +279,37 @@ const handleImportCard = async () => {
 
     const headers = [
       {
-            'key': 'orgName',
-            'title': '机构名称'
+        key: 'orgName',
+        title: '机构名称'
       },
       {
-            'key': 'elderName',
-            'title': '长者姓名'
+        key: 'elderName',
+        title: '长者姓名'
       },
       {
-            'key': 'assessor',
-            'title': '评估人'
+        key: 'assessor',
+        title: '评估人'
       },
       {
-            'key': 'assessDate',
-            'title': '记录日期'
+        key: 'assessDate',
+        title: '记录日期'
       },
       {
-            'key': 'riskLevelText',
-            'title': '风险等级'
+        key: 'riskLevelText',
+        title: '风险等级'
       },
       {
-            'key': 'creator',
-            'title': '记录人'
+        key: 'creator',
+        title: '记录人'
       }
-]
+    ]
 
-    exportWithExpandedObjectArrays(processedData, headers, `感知沟通评估_${new Date().getTime()}.xlsx`, '感知沟通评估')
+    await exportWithExpandedObjectArrays(
+      processedData,
+      headers,
+      `感知沟通评估_${new Date().getTime()}.xlsx`,
+      '感知沟通评估'
+    )
     message.success('导出成功')
   } catch (error) {
     console.error('导出失败:', error)
@@ -296,9 +320,6 @@ const handleImportCard = async () => {
 }
 
 
-const inputH = () => {
-  importRef.value.open(queryParams.tenantIds[0])
-}
 /** 查询列表 */
 const getList = async () => {
   loading.value = true
@@ -326,6 +347,7 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.floorId = ''
+  queryParams.risk = ''
   queryParams.tenantIds = userStore.orgTenantId
   // queryParams.assessDate= getCurrentMonthRange()
   queryParams.assessDate = []

+ 4 - 0
src/views/elderly/apply/nine-precautions/daily-life/AddForm.vue

@@ -349,6 +349,7 @@
 <script lang="ts" setup>
 import { computed, ref, reactive } from 'vue'
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
 import {
   dailyLifeCreate,
   dailyLifeGetById,
@@ -356,6 +357,7 @@ import {
 } from "@/api/social-work";
 
 const message = useMessage()
+const userStore = useUserStore()
 const { t } = useI18n()
 const title = ref('')
 const dialogVisible = ref(false)
@@ -583,6 +585,7 @@ const handleExport = () => {
   ]
 
   // 构建打印内容
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
   const printContent = `
     <!DOCTYPE html>
     <html>
@@ -738,6 +741,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <h1>日常生活活动能力评估表(Barthel指数评分标准)</h1>
       </div>

+ 0 - 1
src/views/elderly/apply/nine-precautions/daily-life/index.vue

@@ -156,7 +156,6 @@ import AddForm from './AddForm.vue'
 import ButtonAdd from '@/components/ButtonAdd/src/ButtonAdd.vue'
 import ButtonImport from '@/components/ButtonImport/src/ButtonImport.vue'
 import { useUserStore } from '@/store/modules/user'
-import { getCurrentMonthRange } from '@/utils/dateUtil'
 import { dailyLifeDelete, dailyLifePage } from '@/api/social-work'
 import { exportWithExpandedObjectArrays } from '@/utils/excel-export'
 import { findLabelById } from '@/utils/dict'

+ 4 - 0
src/views/elderly/apply/nine-precautions/empyrosis/AddForm.vue

@@ -152,6 +152,7 @@
 <script lang="ts" setup>
 import { ref, reactive } from 'vue'
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
 import {
   burnPreventionCreate,
   burnPreventionGetById,
@@ -159,6 +160,7 @@ import {
 } from "@/api/social-work";
 
 const message = useMessage()
+const userStore = useUserStore()
 const { t } = useI18n()
 const title = ref('')
 const dialogVisible = ref(false)
@@ -397,6 +399,7 @@ const handleExport = () => {
   }
 
   // 构建打印内容
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
   const printContent = `
     <!DOCTYPE html>
     <html>
@@ -554,6 +557,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <h1>防烫伤评估表</h1>
       </div>

+ 41 - 16
src/views/elderly/apply/nine-precautions/empyrosis/index.vue

@@ -18,6 +18,23 @@
         />
       </el-form-item>
 
+      <el-form-item label="风险等级">
+        <el-select v-model="queryParams.risk" class="!w-240px">
+          <el-option
+            v-for="(item, index) in [
+              { label: '无风险', value: 'none' },
+              { label: '低风险', value: 'low' },
+              { label: '中风险', value: 'medium' },
+              { label: '高风险', value: 'high' }
+            ]"
+            :key="index"
+            placeholder="请选择"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+
       <el-form-item label="评估人">
         <el-input v-model="queryParams.assessor" placeholder="评估人" class="!w-240px" clearable />
       </el-form-item>
@@ -174,6 +191,7 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
+  risk: '',
   // assessDate: getCurrentMonthRange(),
   assessDate: [],
   tenantIds: userStore.orgTenantId
@@ -188,6 +206,7 @@ const handleImportCard = async () => {
       pageNo: 1,
       pageSize: 9999,
       elderName: queryParams.elderName,
+      risk: queryParams.risk,
       assessor: queryParams.assessor,
       assessDate: queryParams.assessDate,
       tenantIds: queryParams.tenantIds
@@ -215,36 +234,41 @@ const handleImportCard = async () => {
 
     const headers = [
       {
-            'key': 'orgName',
-            'title': '机构名称'
+        key: 'orgName',
+        title: '机构名称'
       },
       {
-            'key': 'elderName',
-            'title': '长者姓名'
+        key: 'elderName',
+        title: '长者姓名'
       },
       {
-            'key': 'assessor',
-            'title': '评估人'
+        key: 'assessor',
+        title: '评估人'
       },
       {
-            'key': 'assessDate',
-            'title': '记录日期'
+        key: 'assessDate',
+        title: '记录日期'
       },
       {
-            'key': 'riskLevelText',
-            'title': '风险等级'
+        key: 'riskLevelText',
+        title: '风险等级'
       },
       {
-            'key': 'assessScore',
-            'title': '评估总得分'
+        key: 'assessScore',
+        title: '评估总得分'
       },
       {
-            'key': 'creator',
-            'title': '记录人'
+        key: 'creator',
+        title: '记录人'
       }
-]
+    ]
 
-    exportWithExpandedObjectArrays(processedData, headers, `防烫伤评估_${new Date().getTime()}.xlsx`, '防烫伤评估')
+    await exportWithExpandedObjectArrays(
+      processedData,
+      headers,
+      `防烫伤评估_${new Date().getTime()}.xlsx`,
+      '防烫伤评估'
+    )
     message.success('导出成功')
   } catch (error) {
     console.error('导出失败:', error)
@@ -279,6 +303,7 @@ const handleQuery = async () => {
 const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
+  queryParams.risk = ''
   queryParams.tenantIds = userStore.orgTenantId
   // queryParams.assessDate = getCurrentMonthRange()
   queryParams.assessDate = []

+ 356 - 414
src/views/elderly/apply/nine-precautions/equilibrium/AddForm.vue

@@ -35,330 +35,298 @@
       <div class="balance-test-section">
         <div class="section-title">老年人平衡能力测试表</div>
         <div class="assessment-table">
-          <div class="table-header">
-            <div class="col-category">测试类别</div>
-            <div class="col-item">测试项目</div>
-            <div class="col-desc">描述</div>
-            <div class="col-standard">评分标准</div>
-            <div class="col-score">得分</div>
-          </div>
-
-          <!-- 静态平衡能力 - 双脚并拢站立 -->
-          <div class="table-row">
-            <div class="col-category" rowspan="5">静态平衡能力</div>
-            <div class="col-item">双脚并拢站立</div>
-            <div class="col-desc">双脚同一水平并列靠拢站立,双手自然下垂,保持姿势尽可能超过10秒钟。</div>
-            <div class="col-standard">
-              <div>0分:≥10秒</div>
-              <div>1分:5-9秒</div>
-              <div>2分:0-4秒</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.staticBalance[0]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-                <el-radio :label="2">2</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 静态平衡能力 - 双脚前后位站立 -->
-          <div class="table-row">
-            <div class="col-item">双脚前后位站立</div>
-            <div class="col-desc">双脚成直线一前一后站立,前脚的后跟紧贴后脚的脚尖,双手自然下垂,保持姿势尽可能超过10秒钟。</div>
-            <div class="col-standard">
-              <div>0分:≥10秒</div>
-              <div>1分:5-9秒</div>
-              <div>2分:0-4秒</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.staticBalance[1]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-                <el-radio :label="2">2</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 静态平衡能力 - 闭眼双脚并拢站立 -->
-          <div class="table-row">
-            <div class="col-item">闭眼双脚并拢站立</div>
-            <div class="col-desc">闭上双眼,双脚同一水平并列靠拢站立,双手自然下垂,保持姿势尽可能超过10秒钟。</div>
-            <div class="col-standard">
-              <div>0分:≥10秒</div>
-              <div>1分:5-9秒</div>
-              <div>2分:0-4秒</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.staticBalance[2]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-                <el-radio :label="2">2</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 静态平衡能力 - 不闭眼单腿站立 -->
-          <div class="table-row">
-            <div class="col-item">不闭眼单腿站立</div>
-            <div class="col-desc">双手叉腰,单腿站立,抬起脚离地6厘米以上,保持姿势尽可能超过10秒钟。</div>
-            <div class="col-standard">
-              <div>0分:≥10秒</div>
-              <div>1分:5-9秒</div>
-              <div>2分:0-4秒</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.staticBalance[3]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-                <el-radio :label="2">2</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 静态平衡能力 - 闭眼单腿站立 -->
-          <div class="table-row">
-            <div class="col-item">闭眼单腿站立</div>
-            <div class="col-desc">闭上双眼,双手叉腰,单腿站立,抬起脚离地6厘米以上,保持姿势尽可能超过10秒钟。</div>
-            <div class="col-standard">
-              <div>0分:≥10秒</div>
-              <div>1分:5-9秒</div>
-              <div>2分:0-4秒</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.staticBalance[4]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-                <el-radio :label="2">2</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 姿势控制能力 - 由站立位坐下 -->
-          <div class="table-row">
-            <div class="col-category" rowspan="4">姿势控制能力</div>
-            <div class="col-item">由站立位坐下</div>
-            <div class="col-desc">站在椅子前面,弯曲膝盖和大腿,轻轻坐下。</div>
-            <div class="col-standard">
-              <div>0分:能够轻松坐下起立而不需扶手</div>
-              <div>1分:能够自己坐下起立,但略感吃力,需尝试数次或扶住扶手才能完成</div>
-              <div>2分:不能独立完成动作</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.postureControl[0]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-                <el-radio :label="2">2</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 姿势控制能力 - 由坐姿到站立 -->
-          <div class="table-row">
-            <div class="col-item">由坐姿到站立</div>
-            <div class="col-desc">坐在椅子上,靠腿部力量站起。</div>
-            <div class="col-standard">
-              <div>0分:能够轻松坐下起立而不需扶手</div>
-              <div>1分:能够自己坐下起立,但略感吃力,需尝试数次或扶住扶手才能完成</div>
-              <div>2分:不能独立完成动作</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.postureControl[1]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-                <el-radio :label="2">2</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 姿势控制能力 - 由站立位蹲下 -->
-          <div class="table-row">
-            <div class="col-item">由站立位蹲下</div>
-            <div class="col-desc">双脚分开站立与肩同宽,弯曲膝盖下蹲。</div>
-            <div class="col-standard">
-              <div>0分:能够轻松坐下、蹲下、起立而不需要扶手</div>
-              <div>1分:能够自己蹲下、起立,但略感吃力,需尝试数次或扶住旁边的固定物体才能完成</div>
-              <div>2分:不能独立完成动作</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.postureControl[2]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-                <el-radio :label="2">2</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 姿势控制能力 - 由下蹲姿势到站立 -->
-          <div class="table-row">
-            <div class="col-item">由下蹲姿势到站立</div>
-            <div class="col-desc">由下蹲姿势靠腿部力量站起。</div>
-            <div class="col-standard">
-              <div>0分:能够轻松坐下、蹲下、起立而不需要扶手</div>
-              <div>1分:能够自己蹲下、起立,但略感吃力,需尝试数次或扶住旁边的固定物体才能完成</div>
-              <div>2分:不能独立完成动作</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.postureControl[3]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-                <el-radio :label="2">2</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 动态平衡能力 - 起步 -->
-          <div class="table-row">
-            <div class="col-category" rowspan="8">动态平衡能力</div>
-            <div class="col-item">起步</div>
-            <div class="col-desc">
-              <div>①能立即迈步出发不犹豫。</div>
-              <div>②需要想一想或尝试几次才能迈步。</div>
-            </div>
-            <div class="col-standard">
-              <div>① = 0</div>
-              <div>② = 1</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.dynamicBalance[0]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 动态平衡能力 - 步高 -->
-          <div class="table-row">
-            <div class="col-item">步高</div>
-            <div class="col-desc">
-              <div>①脚抬离地面,干净利落。</div>
-              <div>②脚拖着地面走路。</div>
-            </div>
-            <div class="col-standard">
-              <div>① = 0</div>
-              <div>② = 1</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.dynamicBalance[1]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 动态平衡能力 - 步长 -->
-          <div class="table-row">
-            <div class="col-item">步长</div>
-            <div class="col-desc">
-              <div>①每步跨度长于脚长。</div>
-              <div>②不敢大步走,走小碎步。</div>
-            </div>
-            <div class="col-standard">
-              <div>① = 0</div>
-              <div>② = 1</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.dynamicBalance[2]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 动态平衡能力 - 脚步的匀称性 -->
-          <div class="table-row">
-            <div class="col-item">脚步的匀称性</div>
-            <div class="col-desc">
-              <div>①步子均匀,每步的长度和高度一致。</div>
-              <div>②步子不匀称,时长时短,一脚深一脚浅。</div>
-            </div>
-            <div class="col-standard">
-              <div>① = 0</div>
-              <div>② = 1</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.dynamicBalance[3]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 动态平衡能力 - 步行的连续性 -->
-          <div class="table-row">
-            <div class="col-item">步行的连续性</div>
-            <div class="col-desc">
-              <div>①连续迈步,中间没有停顿。</div>
-              <div>②步子不连贯,有时需要停顿。</div>
-            </div>
-            <div class="col-standard">
-              <div>① = 0</div>
-              <div>② = 1</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.dynamicBalance[4]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
-
-          <!-- 动态平衡能力 - 步行的直线性 -->
-          <div class="table-row">
-            <div class="col-item">步行的直线性</div>
-            <div class="col-desc">
-              <div>①能沿直线行走。</div>
-              <div>②不能走直线,偏向一边。</div>
-            </div>
-            <div class="col-standard">
-              <div>① = 0</div>
-              <div>② = 1</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.dynamicBalance[5]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
+          <table>
+            <colgroup>
+              <col class="col-category" />
+              <col class="col-item" />
+              <col class="col-desc" />
+              <col class="col-standard" />
+              <col class="col-score" />
+            </colgroup>
+            <thead>
+              <tr>
+                <th>测试类别</th>
+                <th>测试项目</th>
+                <th>描述</th>
+                <th>评分标准</th>
+                <th>得分</th>
+              </tr>
+            </thead>
+            <tbody>
+              <!-- 静态平衡能力 -->
+              <tr>
+                <td class="col-category" rowspan="4">静态平衡能力</td>
+                <td class="col-item">双脚并拢站立</td>
+                <td class="col-desc">双脚同一水平并列靠拢站立,双手自然下垂,保持姿势尽可能超过10秒钟。</td>
+                <td class="col-standard">
+                  <div>0分:≥10秒</div>
+                  <div>1分:5-9秒</div>
+                  <div>2分:0-4秒</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.staticBalance[0]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                    <el-radio :label="2">2</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr>
+                <td class="col-item">双脚前后位站立</td>
+                <td class="col-desc">双脚成直线一前一后站立,前脚的后跟紧贴后脚的脚尖,双手自然下垂,保持姿势尽可能超过10秒钟。</td>
+                <td class="col-standard">
+                  <div>0分:≥10秒</div>
+                  <div>1分:5-9秒</div>
+                  <div>2分:0-4秒</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.staticBalance[1]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                    <el-radio :label="2">2</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr>
+                <td class="col-item">闭眼双脚并拢站立</td>
+                <td class="col-desc">闭上双眼,双脚同一水平并列靠拢站立,双手自然下垂,保持姿势尽可能超过10秒钟。</td>
+                <td class="col-standard">
+                  <div>0分:≥10秒</div>
+                  <div>1分:5-9秒</div>
+                  <div>2分:0-4秒</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.staticBalance[2]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                    <el-radio :label="2">2</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr>
+                <td class="col-item">不闭眼单腿站立</td>
+                <td class="col-desc">双手叉腰,单腿站立,抬起脚离地6厘米以上,保持姿势尽可能超过10秒钟。</td>
+                <td class="col-standard">
+                  <div>0分:≥10秒</div>
+                  <div>1分:5-9秒</div>
+                  <div>2分:0-4秒</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.staticBalance[3]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                    <el-radio :label="2">2</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
 
-          <!-- 动态平衡能力 - 走动时躯干平稳性 -->
-          <div class="table-row">
-            <div class="col-item">走动时躯干平稳性</div>
-            <div class="col-desc">
-              <div>①躯干平稳不左右摇晃。</div>
-              <div>②摇晃或手需向两边伸开来保持平衡。</div>
-            </div>
-            <div class="col-standard">
-              <div>① = 0</div>
-              <div>② = 1</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.dynamicBalance[6]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
+              <!-- 姿势控制能力 -->
+              <tr>
+                <td class="col-category" rowspan="4">姿势控制能力</td>
+                <td class="col-item">由站立位坐下</td>
+                <td class="col-desc">站在椅子前面,弯曲膝盖和大腿,轻轻坐下。</td>
+                <td class="col-standard">
+                  <div>0分:能够轻松坐下起立而不需扶手</div>
+                  <div>1分:能够自己坐下起立,但略感吃力,需尝试数次或扶住扶手才能完成</div>
+                  <div>2分:不能独立完成动作</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.postureControl[0]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                    <el-radio :label="2">2</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr>
+                <td class="col-item">由坐姿到站立</td>
+                <td class="col-desc">坐在椅子上,靠腿部力量站起。</td>
+                <td class="col-standard">
+                  <div>0分:能够轻松坐下起立而不需扶手</div>
+                  <div>1分:能够自己坐下起立,但略感吃力,需尝试数次或扶住扶手才能完成</div>
+                  <div>2分:不能独立完成动作</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.postureControl[1]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                    <el-radio :label="2">2</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr>
+                <td class="col-item">由站立位蹲下</td>
+                <td class="col-desc">双脚分开站立与肩同宽,弯曲膝盖下蹲。</td>
+                <td class="col-standard">
+                  <div>0分:能够轻松坐下、蹲下、起立而不需要扶手</div>
+                  <div>1分:能够自己蹲下、起立,但略感吃力,需尝试数次或扶住旁边的固定物体才能完成</div>
+                  <div>2分:不能独立完成动作</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.postureControl[2]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                    <el-radio :label="2">2</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr>
+                <td class="col-item">由下蹲姿势到站立</td>
+                <td class="col-desc">由下蹲姿势靠腿部力量站起。</td>
+                <td class="col-standard">
+                  <div>0分:能够轻松坐下、蹲下、起立而不需要扶手</div>
+                  <div>1分:能够自己蹲下、起立,但略感吃力,需尝试数次或扶住旁边的固定物体才能完成</div>
+                  <div>2分:不能独立完成动作</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.postureControl[3]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                    <el-radio :label="2">2</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
 
-          <!-- 动态平衡能力 - 走动时转身 -->
-          <div class="table-row">
-            <div class="col-item">走动时转身</div>
-            <div class="col-desc">
-              <div>①躯干平稳,转身连续,转身时步行连续。</div>
-              <div>②摇晃,转身前需停步或转身时脚步有停顿。</div>
-            </div>
-            <div class="col-standard">
-              <div>① = 0</div>
-              <div>② = 1</div>
-            </div>
-            <div class="col-score">
-              <el-radio-group v-model="form.dynamicBalance[7]" :disabled="isDetail" @change="calculateTotal">
-                <el-radio :label="0">0</el-radio>
-                <el-radio :label="1">1</el-radio>
-              </el-radio-group>
-            </div>
-          </div>
+              <!-- 动态平衡能力 -->
+              <tr>
+                <td class="col-category" rowspan="8">动态平衡能力</td>
+                <td class="col-item">起步</td>
+                <td class="col-desc">
+                  <div>①能立即迈步出发不犹豫。</div>
+                  <div>②需要想一想或尝试几次才能迈步。</div>
+                </td>
+                <td class="col-standard">
+                  <div>① = 0</div>
+                  <div>② = 1</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.dynamicBalance[0]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr>
+                <td class="col-item">步高</td>
+                <td class="col-desc">
+                  <div>①脚抬离地面,干净利落。</div>
+                  <div>②脚拖着地面走路。</div>
+                </td>
+                <td class="col-standard">
+                  <div>① = 0</div>
+                  <div>② = 1</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.dynamicBalance[1]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr>
+                <td class="col-item">步长</td>
+                <td class="col-desc">
+                  <div>①每步跨度长于脚长。</div>
+                  <div>②不敢大步走,走小碎步。</div>
+                </td>
+                <td class="col-standard">
+                  <div>① = 0</div>
+                  <div>② = 1</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.dynamicBalance[2]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr>
+                <td class="col-item">脚步的匀称性</td>
+                <td class="col-desc">
+                  <div>①步子均匀,每步的长度和高度一致。</div>
+                  <div>②步子不匀称,时长时短,一脚深一脚浅。</div>
+                </td>
+                <td class="col-standard">
+                  <div>① = 0</div>
+                  <div>② = 1</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.dynamicBalance[3]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr>
+                <td class="col-item">步行的连续性</td>
+                <td class="col-desc">
+                  <div>①连续迈步,中间没有停顿。</div>
+                  <div>②步子不连贯,有时需要停顿。</div>
+                </td>
+                <td class="col-standard">
+                  <div>① = 0</div>
+                  <div>② = 1</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.dynamicBalance[4]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr>
+                <td class="col-item">步行的直线性</td>
+                <td class="col-desc">
+                  <div>①能沿直线行走。</div>
+                  <div>②不能走直线,偏向一边。</div>
+                </td>
+                <td class="col-standard">
+                  <div>① = 0</div>
+                  <div>② = 1</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.dynamicBalance[5]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr>
+                <td class="col-item">走动时躯干平稳性</td>
+                <td class="col-desc">
+                  <div>①躯干平稳不左右摇晃。</div>
+                  <div>②摇晃或手需向两边伸开来保持平衡。</div>
+                </td>
+                <td class="col-standard">
+                  <div>① = 0</div>
+                  <div>② = 1</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.dynamicBalance[6]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr>
+                <td class="col-item">走动时转身</td>
+                <td class="col-desc">
+                  <div>①躯干平稳,转身连续,转身时步行连续。</div>
+                  <div>②摇晃,转身前需停步或转身时脚步有停顿。</div>
+                </td>
+                <td class="col-standard">
+                  <div>① = 0</div>
+                  <div>② = 1</div>
+                </td>
+                <td class="col-score">
+                  <el-radio-group v-model="form.dynamicBalance[7]" :disabled="isDetail" @change="calculateTotal">
+                    <el-radio :label="0">0</el-radio>
+                    <el-radio :label="1">1</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+            </tbody>
+          </table>
         </div>
 
         <!-- 风险程度判断 -->
@@ -426,6 +394,7 @@
 <script lang="ts" setup>
 import { computed, ref, reactive } from 'vue'
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
 import {
   equilibriumCreate,
   equilibriumGetById,
@@ -433,6 +402,7 @@ import {
 } from "@/api/social-work";
 
 const message = useMessage()
+const userStore = useUserStore()
 const { t } = useI18n()
 const title = ref('')
 const dialogVisible = ref(false)
@@ -461,7 +431,7 @@ const elderUp = (e: any) => {
 
 // 表单数据
 const form = reactive({
-  staticBalance: [0, 0, 0, 0, 0],      // 静态平衡能力 5
+  staticBalance: [0, 0, 0, 0],      // 静态平衡能力 4
   postureControl: [0, 0, 0, 0],        // 姿势控制能力 4项
   dynamicBalance: [0, 0, 0, 0, 0, 0, 0, 0], // 动态平衡能力 8项
   totalScore: 0,
@@ -528,9 +498,11 @@ const deserializeFormData = (formData: Record<string, any>) => {
   if (!formData) return
 
   if (formData.staticBalance && formData.staticBalance.length > 0) {
-    form.staticBalance = formData.staticBalance
+    const arr = formData.staticBalance || []
+    form.staticBalance = arr.slice(0, 4)
+    while (form.staticBalance.length < 4) form.staticBalance.push(0)
   } else {
-    form.staticBalance = [0, 0, 0, 0, 0]
+    form.staticBalance = [0, 0, 0, 0]
   }
 
   if (formData.postureControl && formData.postureControl.length > 0) {
@@ -562,7 +534,7 @@ const resetForm = () => {
   }
   formRef.value?.resetFields()
 
-  form.staticBalance = [0, 0, 0, 0, 0]
+  form.staticBalance = [0, 0, 0, 0]
   form.postureControl = [0, 0, 0, 0]
   form.dynamicBalance = [0, 0, 0, 0, 0, 0, 0, 0]
   form.totalScore = 0
@@ -676,7 +648,6 @@ const handleExport = () => {
     { category: '静态平衡能力', name: '双脚前后位站立', desc: '双脚成直线一前一后站立,前脚的后跟紧贴后脚的脚尖,双手自然下垂,保持姿势尽可能超过10秒钟。', standard: ['≥10秒=0', '5-9秒=1', '0-4秒=2'], score: form.staticBalance[1] },
     { category: '静态平衡能力', name: '闭眼双脚并拢站立', desc: '闭上双眼,双脚同一水平并列靠拢站立,双手自然下垂,保持姿势尽可能超过10秒钟。', standard: ['≥10秒=0', '5-9秒=1', '0-4秒=2'], score: form.staticBalance[2] },
     { category: '静态平衡能力', name: '不闭眼单腿站立', desc: '双手叉腰,单腿站立,抬起脚离地6厘米以上,保持姿势尽可能超过10秒钟。', standard: ['≥10秒=0', '5-9秒=1', '0-4秒=2'], score: form.staticBalance[3] },
-    { category: '静态平衡能力', name: '闭眼单腿站立', desc: '闭上双眼,双手叉腰,单腿站立,抬起脚离地6厘米以上,保持姿势尽可能超过10秒钟。', standard: ['≥10秒=0', '5-9秒=1', '0-4秒=2'], score: form.staticBalance[4] },
     // 姿势控制能力
     { category: '姿势控制能力', name: '由站立位坐下', desc: '站在椅子前面,弯曲膝盖和大腿,轻轻坐下。', standard: ['轻松坐下起立而不需扶手=0', '略感吃力,需尝试数次或扶住扶手=1', '不能独立完成=2'], score: form.postureControl[0] },
     { category: '姿势控制能力', name: '由坐姿到站立', desc: '坐在椅子上,靠腿部力量站起。', standard: ['轻松坐下起立而不需扶手=0', '略感吃力,需尝试数次或扶住扶手=1', '不能独立完成=2'], score: form.postureControl[1] },
@@ -694,6 +665,7 @@ const handleExport = () => {
   ]
 
   // 构建打印内容
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
   const printContent = `
     <!DOCTYPE html>
     <html>
@@ -844,6 +816,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <h1>老年人平衡能力测试表</h1>
       </div>
@@ -975,107 +948,76 @@ const rules = {
       border-radius: 4px;
       overflow: hidden;
 
-      .table-header {
-        display: flex;
-        background-color: #f5f7fa;
-        font-weight: bold;
-        border-bottom: 1px solid #e4e7ed;
+      table {
+        width: 100%;
+        border-collapse: collapse;
+        table-layout: fixed;
+      }
 
-        .col-category {
-          width: 10%;
-          padding: 12px;
-          border-right: 1px solid #e4e7ed;
-          text-align: center;
-        }
+      th,
+      td {
+        padding: 12px;
+        border-right: 1px solid #e4e7ed;
+        border-bottom: 1px solid #e4e7ed;
+        vertical-align: middle;
+        text-align: center;
+      }
 
-        .col-item {
-          width: 12%;
-          padding: 12px;
-          border-right: 1px solid #e4e7ed;
-          text-align: center;
-        }
+      th:last-child,
+      td:last-child {
+        border-right: none;
+      }
 
-        .col-desc {
-          width: 35%;
-          padding: 12px;
-          border-right: 1px solid #e4e7ed;
-          text-align: center;
-        }
+      thead th {
+        background-color: #f5f7fa;
+        font-weight: bold;
+        border-bottom: 1px solid #e4e7ed;
+      }
 
-        .col-standard {
-          width: 30%;
-          padding: 12px;
-          border-right: 1px solid #e4e7ed;
-          text-align: center;
-        }
+      tbody tr:last-child td {
+        border-bottom: none;
+      }
 
-        .col-score {
-          width: 13%;
-          padding: 12px;
-          text-align: center;
-        }
+      col.col-category {
+        width: 10%;
       }
 
-      .table-row {
-        display: flex;
-        border-bottom: 1px solid #e4e7ed;
+      col.col-item {
+        width: 12%;
+      }
 
-        &:last-child {
-          border-bottom: none;
-        }
+      col.col-desc {
+        width: 35%;
+      }
 
-        .col-category {
-          width: 10%;
-          padding: 12px;
-          border-right: 1px solid #e4e7ed;
-          display: flex;
-          align-items: center;
-          justify-content: center;
-          font-weight: bold;
-        }
+      col.col-standard {
+        width: 30%;
+      }
 
-        .col-item {
-          width: 12%;
-          padding: 12px;
-          border-right: 1px solid #e4e7ed;
-          display: flex;
-          align-items: center;
-          justify-content: center;
-          font-weight: bold;
-        }
+      col.col-score {
+        width: 13%;
+      }
 
-        .col-desc {
-          width: 35%;
-          padding: 12px;
-          border-right: 1px solid #e4e7ed;
-          display: flex;
-          flex-direction: column;
-          justify-content: center;
-          line-height: 1.6;
-        }
+      .col-category {
+        font-weight: bold;
+        background-color: #fafafa;
+      }
 
-        .col-standard {
-          width: 30%;
-          padding: 12px;
-          border-right: 1px solid #e4e7ed;
-          display: flex;
-          flex-direction: column;
-          justify-content: center;
-          line-height: 1.6;
-        }
+      .col-item {
+        font-weight: bold;
+      }
 
-        .col-score {
-          width: 13%;
-          padding: 12px;
-          display: flex;
-          align-items: center;
-          justify-content: center;
+      .col-desc,
+      .col-standard {
+        text-align: left;
+        line-height: 1.6;
+      }
 
-          .el-radio-group {
-            display: flex;
-            flex-direction: row;
-            gap: 8px;
-          }
+      .col-score {
+        .el-radio-group {
+          display: inline-flex;
+          flex-direction: row;
+          gap: 8px;
         }
       }
     }

+ 41 - 16
src/views/elderly/apply/nine-precautions/equilibrium/index.vue

@@ -18,6 +18,23 @@
         />
       </el-form-item>
 
+      <el-form-item label="风险等级">
+        <el-select v-model="queryParams.risk" class="!w-240px">
+          <el-option
+            v-for="(item, index) in [
+              { label: '无风险', value: 'none' },
+              { label: '低风险', value: 'low' },
+              { label: '中风险', value: 'medium' },
+              { label: '高风险', value: 'high' }
+            ]"
+            :key="index"
+            placeholder="请选择"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+
       <el-form-item label="评估人">
         <el-input v-model="queryParams.assessor" placeholder="评估人" class="!w-240px" clearable />
       </el-form-item>
@@ -174,6 +191,7 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
+  risk: '',
   // assessDate: getCurrentMonthRange(),
   assessDate: [],
   tenantIds: userStore.orgTenantId
@@ -188,6 +206,7 @@ const handleImportCard = async () => {
       pageNo: 1,
       pageSize: 9999,
       elderName: queryParams.elderName,
+      risk: queryParams.elderName,
       assessor: queryParams.assessor,
       assessDate: queryParams.assessDate,
       tenantIds: queryParams.tenantIds
@@ -215,36 +234,41 @@ const handleImportCard = async () => {
 
     const headers = [
       {
-            'key': 'orgName',
-            'title': '机构名称'
+        key: 'orgName',
+        title: '机构名称'
       },
       {
-            'key': 'elderName',
-            'title': '长者姓名'
+        key: 'elderName',
+        title: '长者姓名'
       },
       {
-            'key': 'assessor',
-            'title': '评估人'
+        key: 'assessor',
+        title: '评估人'
       },
       {
-            'key': 'assessDate',
-            'title': '记录日期'
+        key: 'assessDate',
+        title: '记录日期'
       },
       {
-            'key': 'assessScore',
-            'title': '评估总得分'
+        key: 'assessScore',
+        title: '评估总得分'
       },
       {
-            'key': 'riskLevelText',
-            'title': '风险等级'
+        key: 'riskLevelText',
+        title: '风险等级'
       },
       {
-            'key': 'creator',
-            'title': '记录人'
+        key: 'creator',
+        title: '记录人'
       }
-]
+    ]
 
-    exportWithExpandedObjectArrays(processedData, headers, `平衡能力评估_${new Date().getTime()}.xlsx`, '平衡能力评估')
+    await exportWithExpandedObjectArrays(
+      processedData,
+      headers,
+      `平衡能力评估_${new Date().getTime()}.xlsx`,
+      '平衡能力评估'
+    )
     message.success('导出成功')
   } catch (error) {
     console.error('导出失败:', error)
@@ -279,6 +303,7 @@ const handleQuery = async () => {
 const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
+  queryParams.risk = ''
   queryParams.tenantIds = userStore.orgTenantId
   // queryParams.assessDate = getCurrentMonthRange()
   queryParams.assessDate = []

+ 4 - 0
src/views/elderly/apply/nine-precautions/fall-down/AddForm.vue

@@ -213,6 +213,7 @@
 <script lang="ts" setup>
 import { computed, ref, reactive } from 'vue'
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
 import {
   fallDownCreate,
   fallDownGetById,
@@ -220,6 +221,7 @@ import {
 } from "@/api/social-work";
 
 const message = useMessage()
+const userStore = useUserStore()
 const { t } = useI18n()
 const title = ref('')
 const dialogVisible = ref(false)
@@ -456,6 +458,7 @@ const handleExport = () => {
   ]
 
   // 构建打印内容
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
   const printContent = `
     <!DOCTYPE html>
     <html>
@@ -615,6 +618,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <h1>跌倒风险评估表</h1>
       </div>

+ 41 - 16
src/views/elderly/apply/nine-precautions/fall-down/index.vue

@@ -18,6 +18,23 @@
         />
       </el-form-item>
 
+      <el-form-item label="风险等级">
+        <el-select v-model="queryParams.risk" class="!w-240px">
+          <el-option
+            v-for="(item, index) in [
+              { label: '无风险', value: 'none' },
+              { label: '低风险', value: 'low' },
+              { label: '中风险', value: 'medium' },
+              { label: '高风险', value: 'high' }
+            ]"
+            :key="index"
+            placeholder="请选择"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+
       <el-form-item label="评估人">
         <el-input v-model="queryParams.assessor" placeholder="评估人" class="!w-240px" clearable />
       </el-form-item>
@@ -174,6 +191,7 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
+  risk: '',
   // assessDate: getCurrentMonthRange(),
   assessDate: [],
   tenantIds: userStore.orgTenantId
@@ -188,6 +206,7 @@ const handleImportCard = async () => {
       pageNo: 1,
       pageSize: 9999,
       elderName: queryParams.elderName,
+      risk: queryParams.risk,
       assessor: queryParams.assessor,
       assessDate: queryParams.assessDate,
       tenantIds: queryParams.tenantIds
@@ -215,36 +234,41 @@ const handleImportCard = async () => {
 
     const headers = [
       {
-            'key': 'orgName',
-            'title': '机构名称'
+        key: 'orgName',
+        title: '机构名称'
       },
       {
-            'key': 'elderName',
-            'title': '长者姓名'
+        key: 'elderName',
+        title: '长者姓名'
       },
       {
-            'key': 'assessor',
-            'title': '评估人'
+        key: 'assessor',
+        title: '评估人'
       },
       {
-            'key': 'assessDate',
-            'title': '记录日期'
+        key: 'assessDate',
+        title: '记录日期'
       },
       {
-            'key': 'assessScore',
-            'title': '评估总得分'
+        key: 'assessScore',
+        title: '评估总得分'
       },
       {
-            'key': 'riskLevelText',
-            'title': '风险等级'
+        key: 'riskLevelText',
+        title: '风险等级'
       },
       {
-            'key': 'creator',
-            'title': '记录人'
+        key: 'creator',
+        title: '记录人'
       }
-]
+    ]
 
-    exportWithExpandedObjectArrays(processedData, headers, `跌倒风险评估_${new Date().getTime()}.xlsx`, '跌倒风险评估')
+    await exportWithExpandedObjectArrays(
+      processedData,
+      headers,
+      `跌倒风险评估_${new Date().getTime()}.xlsx`,
+      '跌倒风险评估'
+    )
     message.success('导出成功')
   } catch (error) {
     console.error('导出失败:', error)
@@ -279,6 +303,7 @@ const handleQuery = async () => {
 const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
+  queryParams.risk = ''
   queryParams.tenantIds = userStore.orgTenantId
   // queryParams.assessDate = getCurrentMonthRange()
   queryParams.assessDate = []

+ 4 - 0
src/views/elderly/apply/nine-precautions/fall-prevention-measures/AddForm.vue

@@ -153,6 +153,7 @@
 <script lang="ts" setup>
 import { computed, ref, reactive } from 'vue'
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
 import {
   fallPreventionCreate,
   fallPreventionGetById,
@@ -160,6 +161,7 @@ import {
 } from "@/api/social-work";
 
 const message = useMessage()
+const userStore = useUserStore()
 const { t } = useI18n()
 const title = ref('')
 const dialogVisible = ref(false)
@@ -401,6 +403,7 @@ const handleExport = () => {
   }
 
   // 构建打印内容
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
   const printContent = `
     <!DOCTYPE html>
     <html>
@@ -558,6 +561,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <h1>防坠床评估表</h1>
       </div>

+ 41 - 16
src/views/elderly/apply/nine-precautions/fall-prevention-measures/index.vue

@@ -18,6 +18,23 @@
         />
       </el-form-item>
 
+      <el-form-item label="风险等级">
+        <el-select v-model="queryParams.risk" class="!w-240px">
+          <el-option
+            v-for="(item, index) in [
+              { label: '无风险', value: 'none' },
+              { label: '低风险', value: 'low' },
+              { label: '中风险', value: 'medium' },
+              { label: '高风险', value: 'high' }
+            ]"
+            :key="index"
+            placeholder="请选择"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+
       <el-form-item label="评估人">
         <el-input v-model="queryParams.assessor" placeholder="评估人" class="!w-240px" clearable />
       </el-form-item>
@@ -174,6 +191,7 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
+  risk: '',
   // assessDate: getCurrentMonthRange(),
   assessDate: [],
   tenantIds: userStore.orgTenantId
@@ -188,6 +206,7 @@ const handleImportCard = async () => {
       pageNo: 1,
       pageSize: 9999,
       elderName: queryParams.elderName,
+      risk: queryParams.risk,
       assessor: queryParams.assessor,
       assessDate: queryParams.assessDate,
       tenantIds: queryParams.tenantIds
@@ -215,36 +234,41 @@ const handleImportCard = async () => {
 
     const headers = [
       {
-            'key': 'orgName',
-            'title': '机构名称'
+        key: 'orgName',
+        title: '机构名称'
       },
       {
-            'key': 'elderName',
-            'title': '长者姓名'
+        key: 'elderName',
+        title: '长者姓名'
       },
       {
-            'key': 'assessor',
-            'title': '评估人'
+        key: 'assessor',
+        title: '评估人'
       },
       {
-            'key': 'assessDate',
-            'title': '记录日期'
+        key: 'assessDate',
+        title: '记录日期'
       },
       {
-            'key': 'assessScore',
-            'title': '评估总得分'
+        key: 'assessScore',
+        title: '评估总得分'
       },
       {
-            'key': 'riskLevelText',
-            'title': '风险等级'
+        key: 'riskLevelText',
+        title: '风险等级'
       },
       {
-            'key': 'creator',
-            'title': '记录人'
+        key: 'creator',
+        title: '记录人'
       }
-]
+    ]
 
-    exportWithExpandedObjectArrays(processedData, headers, `防坠床评估_${new Date().getTime()}.xlsx`, '防坠床评估')
+    await exportWithExpandedObjectArrays(
+      processedData,
+      headers,
+      `防坠床评估_${new Date().getTime()}.xlsx`,
+      '防坠床评估'
+    )
     message.success('导出成功')
   } catch (error) {
     console.error('导出失败:', error)
@@ -279,6 +303,7 @@ const handleQuery = async () => {
 const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
+  queryParams.risk = ''
   queryParams.tenantIds = userStore.orgTenantId
   // queryParams.assessDate = getCurrentMonthRange()
   queryParams.assessDate = []

+ 5 - 1
src/views/elderly/apply/nine-precautions/nutritional-risk/AddForm.vue

@@ -478,6 +478,7 @@
 <script setup lang="ts">
 import { ref, reactive, nextTick } from 'vue'
 import { useAppStore } from '@/store/modules/app'
+import { useUserStore } from '@/store/modules/user'
 import {
   nutritionalRiskCreate,
   nutritionalRiskUpdate,
@@ -487,6 +488,7 @@ import {
 import {getTenantId} from "@/utils/auth";
 
 const message = useMessage()
+const userStore = useUserStore()
 const appStore = useAppStore()
 const emit = defineEmits(['success'])
 
@@ -810,7 +812,8 @@ const handleExport = () => {
   ]
 
   // 构建打印内容
-  const printContent = `
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
+  const printContent =`
     <!DOCTYPE html>
     <html>
     <head>
@@ -988,6 +991,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <h1>营养风险评估表</h1>
       </div>

+ 4 - 0
src/views/elderly/apply/nine-precautions/pressure-sores/AddForm.vue

@@ -157,6 +157,7 @@
 <script lang="ts" setup>
 import { computed, ref, reactive } from 'vue'
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
 import {
   pressureSoresCreate,
   pressureSoresGetById,
@@ -164,6 +165,7 @@ import {
 } from "@/api/social-work";
 
 const message = useMessage()
+const userStore = useUserStore()
 const { t } = useI18n()
 const title = ref('')
 const dialogVisible = ref(false)
@@ -428,6 +430,7 @@ const handleExport = () => {
   const record = form.assessments[0]
 
   // 构建打印内容
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
   const printContent = `
     <!DOCTYPE html>
     <html>
@@ -585,6 +588,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <h1>防压疮评估表</h1>
       </div>

+ 41 - 16
src/views/elderly/apply/nine-precautions/pressure-sores/index.vue

@@ -18,6 +18,23 @@
         />
       </el-form-item>
 
+      <el-form-item label="风险等级">
+        <el-select v-model="queryParams.risk" class="!w-240px">
+          <el-option
+            v-for="(item, index) in [
+              { label: '无风险', value: 'none' },
+              { label: '低风险', value: 'low' },
+              { label: '中风险', value: 'medium' },
+              { label: '高风险', value: 'high' }
+            ]"
+            :key="index"
+            placeholder="请选择"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+
       <el-form-item label="评估人">
         <el-input v-model="queryParams.assessor" placeholder="评估人" class="!w-240px" clearable />
       </el-form-item>
@@ -174,6 +191,7 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
+  risk: '',
   // assessDate: getCurrentMonthRange(),
   assessDate: [],
   tenantIds: userStore.orgTenantId
@@ -187,6 +205,7 @@ const handleImportCard = async () => {
     const queryP = {
       pageNo: 1,
       pageSize: 9999,
+      risk: queryParams.risk,
       elderName: queryParams.elderName,
       assessor: queryParams.assessor,
       assessDate: queryParams.assessDate,
@@ -215,36 +234,41 @@ const handleImportCard = async () => {
 
     const headers = [
       {
-            'key': 'orgName',
-            'title': '机构名称'
+        key: 'orgName',
+        title: '机构名称'
       },
       {
-            'key': 'elderName',
-            'title': '长者姓名'
+        key: 'elderName',
+        title: '长者姓名'
       },
       {
-            'key': 'assessor',
-            'title': '评估人'
+        key: 'assessor',
+        title: '评估人'
       },
       {
-            'key': 'assessDate',
-            'title': '记录日期'
+        key: 'assessDate',
+        title: '记录日期'
       },
       {
-            'key': 'assessScore',
-            'title': '评估总得分'
+        key: 'assessScore',
+        title: '评估总得分'
       },
       {
-            'key': 'riskLevelText',
-            'title': '风险等级'
+        key: 'riskLevelText',
+        title: '风险等级'
       },
       {
-            'key': 'creator',
-            'title': '记录人'
+        key: 'creator',
+        title: '记录人'
       }
-]
+    ]
 
-    exportWithExpandedObjectArrays(processedData, headers, `防压疮评估_${new Date().getTime()}.xlsx`, '防压疮评估')
+    exportWithExpandedObjectArrays(
+      processedData,
+      headers,
+      `防压疮评估_${new Date().getTime()}.xlsx`,
+      '防压疮评估'
+    )
     message.success('导出成功')
   } catch (error) {
     console.error('导出失败:', error)
@@ -279,6 +303,7 @@ const handleQuery = async () => {
 const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
+  queryParams.risk = ''
   queryParams.tenantIds = userStore.orgTenantId
   // queryParams.assessDate = getCurrentMonthRange()
   queryParams.assessDate = []

+ 1 - 1
src/views/elderly/apply/nine-precautions/risk-disclosure-statement/Form.vue

@@ -645,7 +645,7 @@ const handleExport = () => {
     </head>
     <body>
       <div class="print-container">
-        <div class="tenant-name" style="text-align: center; font-size: 18px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
+        <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
         <div class="title">服务安全风险知情告知书</div>
         
         <div class="info-row">

+ 4 - 0
src/views/elderly/apply/nine-precautions/wander-away/AddForm.vue

@@ -368,6 +368,7 @@
 <script lang="ts" setup>
 import { ref, reactive } from 'vue'
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
 import {
   wanderAwayCreate,
   wanderAwayGetById,
@@ -375,6 +376,7 @@ import {
 } from "@/api/social-work";
 
 const message = useMessage()
+const userStore = useUserStore()
 const { t } = useI18n()
 const title = ref('')
 const dialogVisible = ref(false)
@@ -618,6 +620,7 @@ const handleExport = () => {
   ]
 
   // 构建打印内容
+  const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
   const printContent = `
     <!DOCTYPE html>
     <html>
@@ -784,6 +787,7 @@ const handleExport = () => {
       </style>
     </head>
     <body>
+      <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
       <div class="header">
         <h1>防走失风险评估表</h1>
       </div>

+ 86 - 18
src/views/elderly/apply/nine-precautions/wander-away/index.vue

@@ -18,6 +18,49 @@
         />
       </el-form-item>
 
+      <el-form-item label="风险等级">
+        <el-select v-model="queryParams.risk" class="!w-240px">
+          <el-option
+            v-for="(item, index) in [
+              { label: '无风险', value: 'none' },
+              { label: '低风险', value: 'low' },
+              { label: '中风险', value: 'medium' },
+              { label: '高风险', value: 'high' }
+            ]"
+            :key="index"
+            placeholder="请选择"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+
+<!--      <el-form-item label="楼栋">-->
+<!--        <el-select-->
+<!--          v-model="queryParams.buildId"-->
+<!--          placeholder="选择楼栋"-->
+<!--          style="width: 180px"-->
+<!--          @change="handleBuildChange"-->
+<!--        >-->
+<!--          <el-option-->
+<!--            v-for="(item, index) in buildList"-->
+<!--            :key="index"-->
+<!--            :label="item.buildName"-->
+<!--            :value="item.id"-->
+<!--          />-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="楼层">-->
+<!--        <el-select v-model="queryParams.floorId" placeholder="选择楼层" style="width: 180px">-->
+<!--          <el-option-->
+<!--            v-for="(item, index) in floorList"-->
+<!--            :key="index"-->
+<!--            :label="item.floorName"-->
+<!--            :value="item.id"-->
+<!--          />-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+
       <el-form-item label="评估人">
         <el-input v-model="queryParams.assessor" placeholder="评估人" class="!w-240px" clearable />
       </el-form-item>
@@ -160,6 +203,8 @@ import { getCurrentMonthRange } from '@/utils/dateUtil'
 import { wanderAwayDelete, wanderAwayPage } from '@/api/social-work'
 import { exportWithExpandedObjectArrays } from '@/utils/excel-export'
 import { findLabelById } from '@/utils/dict'
+import { ref } from 'vue'
+import { getBuildList } from '@/api/system/badManage'
 
 const message = useMessage()
 const { t } = useI18n()
@@ -174,6 +219,7 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
+  risk: '',
   // assessDate: getCurrentMonthRange(),
   assessDate: [],
   tenantIds: userStore.orgTenantId
@@ -189,6 +235,7 @@ const handleImportCard = async () => {
       pageSize: 9999,
       elderName: queryParams.elderName,
       assessor: queryParams.assessor,
+      risk: queryParams.risk,
       assessDate: queryParams.assessDate,
       tenantIds: queryParams.tenantIds
     }
@@ -215,36 +262,41 @@ const handleImportCard = async () => {
 
     const headers = [
       {
-            'key': 'orgName',
-            'title': '机构名称'
+        key: 'orgName',
+        title: '机构名称'
       },
       {
-            'key': 'elderName',
-            'title': '长者姓名'
+        key: 'elderName',
+        title: '长者姓名'
       },
       {
-            'key': 'assessor',
-            'title': '评估人'
+        key: 'assessor',
+        title: '评估人'
       },
       {
-            'key': 'assessDate',
-            'title': '记录日期'
+        key: 'assessDate',
+        title: '记录日期'
       },
       {
-            'key': 'assessScore',
-            'title': '评估总得分'
+        key: 'assessScore',
+        title: '评估总得分'
       },
       {
-            'key': 'riskLevelText',
-            'title': '风险等级'
+        key: 'riskLevelText',
+        title: '风险等级'
       },
       {
-            'key': 'creator',
-            'title': '记录人'
+        key: 'creator',
+        title: '记录人'
       }
-]
+    ]
 
-    exportWithExpandedObjectArrays(processedData, headers, `防走失风险评估_${new Date().getTime()}.xlsx`, '防走失风险评估')
+    await exportWithExpandedObjectArrays(
+      processedData,
+      headers,
+      `防走失风险评估_${new Date().getTime()}.xlsx`,
+      '防走失风险评估'
+    )
     message.success('导出成功')
   } catch (error) {
     console.error('导出失败:', error)
@@ -279,6 +331,9 @@ const handleQuery = async () => {
 const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
+  queryParams.floorId = ''
+  queryParams.buildId = ''
+  queryParams.risk = ''
   queryParams.tenantIds = userStore.orgTenantId
   // queryParams.assessDate = getCurrentMonthRange()
   queryParams.assessDate = []
@@ -328,13 +383,26 @@ const cancelDelete = async (id: number) => {
   } catch {}
 }
 
+const floorList = ref([])
+const buildList = ref([])
+const handleBuildChange = (buildId: any) => {
+  const selectedBuild = buildList.value.find((item: any) => item.id === buildId)
+  if (selectedBuild) {
+    floorList.value = selectedBuild.floorList || []
+  }
+}
+
 const route = useRoute()
 /** 初始化 **/
-onMounted(() => {
+onMounted(async () => {
   if (route.query && route.query.elderName) {
     queryParams.elderName = route.query.elderName as string
   }
-  getList()
+  await getList()
+
+  try {
+    buildList.value = await getBuildList({ tenantIds: queryParams.tenantIds[0] })
+  } catch (e) {}
 })
 
 // 表头格式

+ 65 - 0
src/views/elderly/elder/elder-file/index.vue

@@ -96,6 +96,9 @@
         <el-button type="primary" color="indigo" plain @click="handleImportCard(2)">
           <Icon icon="ep:upload" class="mr-5px" /> 批量导出分享卡
         </el-button>
+        <el-button type="success" plain @click="handleExportFormat" v-show="false" :loading="exportLoading">
+          <Icon icon="ep:download" class="mr-5px" /> 导出为特定格式
+        </el-button>
       </template>
     </TabBarBtn>
     <Table2
@@ -202,6 +205,8 @@ import download from '@/utils/download'
 import { importCard } from '@/utils/outBedCard'
 import { getElderHealthRecordById } from '@/api/elderly/elder/health-record'
 import { getBuildList } from '@/api/system/badManage'
+import { exportWithExpandedObjectArrays } from '@/utils/excel-export'
+import { formatTimestampYMD } from '@/utils/dateUtil'
 import { ref } from 'vue'
 defineOptions({ name: 'ElderFile' })
 const userStore = useUserStore()
@@ -405,6 +410,66 @@ const handleExport = async () => {
   }
 }
 
+/** 导出为特定格式 */
+const handleExportFormat = async () => {
+  exportLoading.value = true
+  try {
+    // 获取当前列表所有数据(不分页)
+    const data = await getElderlyPage({
+      ...queryParams,
+      pageNo: 1,
+      pageSize: 9999
+    })
+    const exportData = data.list || []
+    if (exportData.length === 0) {
+      message.warning('暂无数据可导出')
+      return
+    }
+
+    // 处理数据
+    const processedData = exportData.map((item: any) => {
+      const bedNameParts = (item.bedName || '').split('-')
+      return {
+        elderName: item.elderName || '',
+        accountIdCard: item.idCard || '',
+        elderSex: item.elderSex === 1 ? '男' : item.elderSex === 2 ? '女' : item.elderSex,
+        registeredResidenceAddress: item.registeredResidenceAddress || '',
+        idCard: item.idCard || '',
+        checkInTime: item.checkInTime ? formatTimestampYMD(Number(item.checkInTime)) : '',
+        floorName: bedNameParts.slice(0, 2).join('-'),
+        bedName: bedNameParts.slice(2).join('-'),
+        contractNumber: item.contractNumber || ''
+      }
+    })
+
+    // 表头配置
+    const headers = [
+      { key: 'elderName', title: '姓名', width: 15 },
+      { key: 'accountIdCard', title: '账号(身份证号)', width: 25 },
+      { key: 'elderSex', title: '性别', width: 10 },
+      { key: 'registeredResidenceAddress', title: '地址', width: 40 },
+      { key: 'idCard', title: '身份证号', width: 25 },
+      { key: 'checkInTime', title: '入住日期', width: 15 },
+      { key: 'floorName', title: '区/楼层', width: 20 },
+      { key: 'bedName', title: '床号', width: 20 },
+      { key: 'contractNumber', title: '合同号', width: 20 }
+    ]
+
+    await exportWithExpandedObjectArrays(
+      processedData,
+      headers,
+      `长者档案特定格式_${Date.now()}.xlsx`,
+      '长者档案'
+    )
+    message.success('导出成功')
+  } catch (error) {
+    console.error('导出失败:', error)
+    message.error('导出失败,请重试')
+  } finally {
+    exportLoading.value = false
+  }
+}
+
 const buildList = ref([])
 const floorList = ref([])
 const handleBuildChange = (buildId: any) => {

+ 110 - 48
src/views/elderly/elder/family-appointment/time-setting/index.vue

@@ -299,41 +299,41 @@
         </el-col>
 
         <el-col :span="12" class="col-right">
-          <div class="card card-mid-right">
-            <div class="card-header">
-              <el-icon class="card-icon icon-green"><Tickets /></el-icon>
-              <span class="card-title">总名额限制(按自然周和月)</span>
-              <el-button
-                type="primary"
-                size="small"
-                :disabled="isDisabled || totalLimits.length >= 3"
-                @click="openTotalLimitDialog"
-              >
-                <el-icon><Plus /></el-icon>
-                添加
-              </el-button>
-            </div>
-            <div class="card-body card-body-limit">
-              <div v-if="totalLimits.length === 0" class="empty-limits-inline">
-                <el-empty description="暂无限制,点击右上角添加" :image-size="40" />
-              </div>
-              <div v-else class="limit-list-inline">
-                <div v-for="(limit, index) in totalLimits" :key="index" class="limit-item-inline">
-                  <span class="limit-type-badge">{{ getLimitTypeLabel(limit.type) }}</span>
-                  <span class="limit-count-num">{{ limit.count }} <em>次</em></span>
-                  <el-button
-                    type="danger"
-                    link
-                    size="small"
-                    :disabled="isDisabled"
-                    @click="removeTotalLimit(index)"
-                  >
-                    <el-icon><Delete /></el-icon>
-                  </el-button>
-                </div>
-              </div>
-            </div>
-          </div>
+<!--          <div class="card card-mid-right">-->
+<!--            <div class="card-header">-->
+<!--              <el-icon class="card-icon icon-green"><Tickets /></el-icon>-->
+<!--              <span class="card-title">总名额限制(按自然周和月)</span>-->
+<!--              <el-button-->
+<!--                type="primary"-->
+<!--                size="small"-->
+<!--                :disabled="isDisabled || totalLimits.length >= 3"-->
+<!--                @click="openTotalLimitDialog"-->
+<!--              >-->
+<!--                <el-icon><Plus /></el-icon>-->
+<!--                添加-->
+<!--              </el-button>-->
+<!--            </div>-->
+<!--            <div class="card-body card-body-limit">-->
+<!--              <div v-if="totalLimits.length === 0" class="empty-limits-inline">-->
+<!--                <el-empty description="暂无限制,点击右上角添加" :image-size="40" />-->
+<!--              </div>-->
+<!--              <div v-else class="limit-list-inline">-->
+<!--                <div v-for="(limit, index) in totalLimits" :key="index" class="limit-item-inline">-->
+<!--                  <span class="limit-type-badge">{{ getLimitTypeLabel(limit.type) }}</span>-->
+<!--                  <span class="limit-count-num">{{ limit.count }} <em>次</em></span>-->
+<!--                  <el-button-->
+<!--                    type="danger"-->
+<!--                    link-->
+<!--                    size="small"-->
+<!--                    :disabled="isDisabled"-->
+<!--                    @click="removeTotalLimit(index)"-->
+<!--                  >-->
+<!--                    <el-icon><Delete /></el-icon>-->
+<!--                  </el-button>-->
+<!--                </div>-->
+<!--              </div>-->
+<!--            </div>-->
+<!--          </div>-->
 
           <div class="card card-bottom-right">
             <div class="card-header">
@@ -518,6 +518,7 @@
 import { ref, reactive, onMounted, computed } from 'vue'
 import { Setting, Calendar, User, Plus, Delete, Tickets, Minus } from '@element-plus/icons-vue'
 import type { FormInstance, FormRules } from 'element-plus'
+import { ElMessageBox } from 'element-plus'
 import { useUserStore } from '@/store/modules/user'
 import {
   appointmentConfigADD,
@@ -542,6 +543,8 @@ type CycleType = 'daily' | 'weekly' | 'monthly' | 'custom'
 
 type AppointmentItem = {
   id: number
+  // 后端返回的真实 id,新增的 item 没有此字段;提交时回传给后端,删除时进入 deleteIds
+  serverId?: number
   startTime: string
   endTime: string
   limitCount: number
@@ -621,6 +624,8 @@ const dateTypeToCycleType = (dateType: string): CycleType => {
 const totalLimits = ref<LimitItem[]>([])
 const personLimits = ref<LimitItem[]>([])
 const appointmentGroups = ref<AppointmentGroup[]>([])
+// 被删除的旧 item 后端 id 列表,提交时一并传给后端做物理删除
+const deleteIds = ref<number[]>([])
 
 const totalLimitDialogVisible = ref(false)
 const personLimitDialogVisible = ref(false)
@@ -729,13 +734,20 @@ const addAppointmentGroup = () => {
         id: itemIdCounter,
         startTime: '08:00',
         endTime: '09:00',
-        limitCount: 100
+        limitCount: 20
       }
     ]
   })
 }
 
 const removeGroup = (index: number) => {
+  const group = appointmentGroups.value[index]
+  // 该组下所有带 serverId 的 item 都是后端旧数据,删除时记录 id 交给后端物理删除
+  group.items.forEach((item) => {
+    if (item.serverId) {
+      deleteIds.value.push(item.serverId)
+    }
+  })
   appointmentGroups.value.splice(index, 1)
 }
 
@@ -769,11 +781,16 @@ const addItem = (group: AppointmentGroup) => {
     id: itemIdCounter,
     startTime: newStart,
     endTime: newEnd,
-    limitCount: 100
+    limitCount: 20
   })
 }
 
 const removeItem = (group: AppointmentGroup, index: number) => {
+  const item = group.items[index]
+  // 带 serverId 表示是后端旧数据,删除时记录 id 交给后端物理删除
+  if (item.serverId) {
+    deleteIds.value.push(item.serverId)
+  }
   group.items.splice(index, 1)
 }
 
@@ -891,6 +908,30 @@ const removePersonLimit = (index: number) => {
   personLimits.value.splice(index, 1)
 }
 
+const validatePersonLimits = (): string | null => {
+  const daily = personLimits.value.find((item) => item.type === 1)
+  const weekly = personLimits.value.find((item) => item.type === 2)
+  const monthly = personLimits.value.find((item) => item.type === 3)
+
+  if (daily && daily.count <= 0) {
+    return '单人每日名额限制必须大于0'
+  }
+  if (weekly && weekly.count <= 0) {
+    return '单人每周名额限制必须大于0'
+  }
+  if (monthly && monthly.count <= 0) {
+    return '单人每月名额限制必须大于0'
+  }
+  if (monthly && weekly && monthly.count <= weekly.count) {
+    return '单人每月名额限制必须大于每周名额限制'
+  }
+  if (weekly && daily && weekly.count <= daily.count) {
+    return '单人每周名额限制必须大于每日名额限制'
+  }
+
+  return null
+}
+
 const validateAdvanceDays = (_rule: any, value: any, callback: any) => {
   if (!value || value < 1) {
     callback(new Error('提前预约天数最少为1'))
@@ -948,6 +989,8 @@ const parseGroups = (groups: AppointmentGroupDO[]): AppointmentGroup[] => {
     itemIdCounter++
     group.items.push({
       id: itemIdCounter,
+      // 保留后端真实 id,用于更新时回传和删除时入 deleteIds
+      serverId: g.id,
       startTime: g.beginTime || '',
       endTime: g.endTime || '',
       limitCount: g.limitCount || 100
@@ -983,6 +1026,8 @@ const getSetting = async () => {
       })
       groupIdCounter = 0
       itemIdCounter = 0
+      // 重新拉取配置后,本地 deleteIds 已无意义,清空避免脏数据
+      deleteIds.value = []
       appointmentGroups.value = parseGroups(res.group || [])
       if (appointmentGroups.value.length > 0) {
         groupIdCounter = Math.max(...appointmentGroups.value.map((g) => g.id))
@@ -1112,23 +1157,28 @@ const validateGroups = (): string | null => {
 const handleSubmit = async () => {
   if (!formRef.value) return
   if (!organizationId) {
-    message.error('请选择机构!')
+    await ElMessageBox.alert('请选择机构!', '警告', { type: 'warning' })
     return
   }
   if (!formData.advanceDays || formData.advanceDays < 1) {
-    message.error('提前预约天数最少为1')
+    await ElMessageBox.alert('提前预约天数最少为1', '警告', { type: 'warning' })
     return
   }
   const groupError = validateGroups()
   if (groupError) {
-    message.error(groupError)
+    await ElMessageBox.alert(groupError, '警告', { type: 'warning' })
+    return
+  }
+  const personLimitError = validatePersonLimits()
+  if (personLimitError) {
+    await ElMessageBox.alert(personLimitError, '警告', { type: 'warning' })
     return
   }
   for (const group of appointmentGroups.value) {
     for (let i = 0; i < group.items.length; i++) {
       const item = group.items[i]
       if (!item.limitCount || item.limitCount <= 0) {
-        message.error('限制人数必须大于0')
+        await ElMessageBox.alert('限制人数必须大于0', '警告', { type: 'warning' })
         return
       }
       if (
@@ -1136,12 +1186,20 @@ const handleSubmit = async () => {
         item.endTime &&
         timeToMinutes(item.startTime) >= timeToMinutes(item.endTime)
       ) {
-        message.error('存在开始时间晚于或等于结束时间的预约项,请检查')
+        await ElMessageBox.alert(
+          '存在开始时间晚于或等于结束时间的预约项,请检查',
+          '警告',
+          { type: 'warning' }
+        )
         return
       }
       for (let j = i + 1; j < group.items.length; j++) {
         if (isOverlap(item, group.items[j])) {
-          message.error('同一预约组内存在时间段重叠的预约项,请检查')
+          await ElMessageBox.alert(
+            '同一预约组内存在时间段重叠的预约项,请检查',
+            '警告',
+            { type: 'warning' }
+          )
           return
         }
       }
@@ -1163,10 +1221,12 @@ const handleSubmit = async () => {
         config[field.total] = limit.count
       }
     })
-    personLimits.value.forEach((limit) => {
-      const field = limitTypeToFieldMap[limit.type]
+    // 单人名额:未设置或删除时传 -1(后端表示无限制)
+    ;[1, 2, 3].forEach((type) => {
+      const field = limitTypeToFieldMap[type]
       if (field) {
-        config[field.person] = limit.count
+        const limit = personLimits.value.find((item) => item.type === type)
+        config[field.person] = limit ? limit.count : -1
       }
     })
     const group: AppointmentGroupDO[] = []
@@ -1178,6 +1238,8 @@ const handleSubmit = async () => {
       const enable = g.enable || 0
       g.items.forEach((item) => {
         group.push({
+          // 旧数据带回后端 id 用于更新;新增数据不带 id,后端按新增处理
+          ...(item.serverId ? { id: item.serverId } : {}),
           dateType,
           weekDays,
           monthDays,
@@ -1190,7 +1252,7 @@ const handleSubmit = async () => {
         })
       })
     })
-    const params = { config, group }
+    const params = { config, group, deleteIds: deleteIds.value }
     const res = configId.value
       ? await appointmentConfigUpdate(params)
       : await appointmentConfigADD(params)
@@ -1200,7 +1262,7 @@ const handleSubmit = async () => {
     }
   } catch (error: any) {
     if (error?.message) {
-      message.error(error.message)
+      await ElMessageBox.alert(error.message, '警告', { type: 'warning' })
     }
   } finally {
     submitting.value = false

+ 46 - 0
src/views/elderly/fee/bill-pay/index.vue

@@ -124,6 +124,15 @@
           >
             <Icon icon="ep:promotion" class="mr-5px" /> 供养批量缴费
           </el-button>
+          <el-button
+            plain
+            type="danger"
+            :disabled="!ids.length"
+            @click="handleBitchDelete()"
+            v-hasPermi="['bill-pay:bitch-delete']"
+          >
+            批量删除
+          </el-button>
         </template>
       </TabBarBtn>
       <Table2
@@ -426,6 +435,7 @@ const { t } = useI18n() // 国际化
 import { exportWithCustomHeaders } from '@/utils/excel-export'
 import { formatToDateTime } from '@/utils/dateUtil'
 import { CloseBold } from '@element-plus/icons-vue'
+import { delDailyExpenses } from '@/api/elderly/fee/daily-fee'
 defineOptions({ name: 'BillPay' })
 const userStore = useUserStore()
 const message = useMessage() // 消息弹窗
@@ -775,8 +785,44 @@ const handleGenerator = () => {
 }
 
 const ids = ref([])
+const idsRow = ref([])
 const handleSelectionChange = (val) => {
   ids.value = val.map((item) => item.id)
+  idsRow.value = val.map((item: any) => item)
+  //console.log(idsRow.value, ids.value)
+}
+
+const handleBitchDelete = async () => {
+  if (!ids.value.length) {
+    message.error('请选择一条数据')
+    return
+  }
+  try {
+    // 删除的二次确认
+    await ElMessageBox({
+      title: '温馨提示',
+      message: h('p', null, [
+        h('span', null, '删除选中数据可能会影响'),
+        h('span', { style: 'color: red' }, '“账单缴费”'),
+        h('span', null, ',是否删除选中数据? ')
+      ]),
+      confirmButtonText: t('common.ok'),
+      cancelButtonText: t('common.cancel'),
+      type: 'warning',
+      showCancelButton: true
+    })
+    // 发起删除
+    //
+    //
+    for (const row of idsRow.value) {
+      if ((row.type == 2 || row.type == 4) && row.payStatus != 1) {
+        await deletePayment(row.id)
+      }
+    }
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
 }
 
 const handleClosed = () => {

+ 1 - 1
src/views/elderly/fee/daily-fee/index.vue

@@ -121,7 +121,7 @@
       :columns="DailyFeeColumns"
       :queryParams="queryParams"
       selection
-      @selectionChange="handleSelectionChange"
+      @selection-change="handleSelectionChange"
       disabledSelectedText="status"
       @detail="(arg) => openForm(arg, true)"
     />

+ 75 - 24
src/views/elderly/fee/leave-settle/index.vue

@@ -31,29 +31,29 @@
         </el-select>
       </el-form-item>
 
-<!--      <el-form-item label="退住日期" prop="retreatDate">-->
-<!--        <el-date-picker-->
-<!--          v-model="queryParams.retreatDate"-->
-<!--          class="!w-240px"-->
-<!--          placeholder="请选择"-->
-<!--          end-placeholder="结束日期"-->
-<!--          start-placeholder="开始日期"-->
-<!--          type="date"-->
-<!--          value-format="YYYY-MM-DD"-->
-<!--        />-->
-<!--      </el-form-item>-->
+      <!--      <el-form-item label="退住日期" prop="retreatDate">-->
+      <!--        <el-date-picker-->
+      <!--          v-model="queryParams.retreatDate"-->
+      <!--          class="!w-240px"-->
+      <!--          placeholder="请选择"-->
+      <!--          end-placeholder="结束日期"-->
+      <!--          start-placeholder="开始日期"-->
+      <!--          type="date"-->
+      <!--          value-format="YYYY-MM-DD"-->
+      <!--        />-->
+      <!--      </el-form-item>-->
 
-<!--      <el-form-item label="费用截止日期" prop="costDeadlineDate">-->
-<!--        <el-date-picker-->
-<!--          v-model="queryParams.costDeadlineDate"-->
-<!--          class="!w-240px"-->
-<!--          placeholder="请选择"-->
-<!--          end-placeholder="结束日期"-->
-<!--          start-placeholder="开始日期"-->
-<!--          type="date"-->
-<!--          value-format="YYYY-MM-DD"-->
-<!--        />-->
-<!--      </el-form-item>-->
+      <!--      <el-form-item label="费用截止日期" prop="costDeadlineDate">-->
+      <!--        <el-date-picker-->
+      <!--          v-model="queryParams.costDeadlineDate"-->
+      <!--          class="!w-240px"-->
+      <!--          placeholder="请选择"-->
+      <!--          end-placeholder="结束日期"-->
+      <!--          start-placeholder="开始日期"-->
+      <!--          type="date"-->
+      <!--          value-format="YYYY-MM-DD"-->
+      <!--        />-->
+      <!--      </el-form-item>-->
 
       <el-form-item>
         <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
@@ -64,10 +64,11 @@
 
   <!-- 列表 -->
   <ContentWrap>
-    <el-button plain type="success" @click="handleExport">
+    <el-button plain type="success" :loading="loading" @click="handleExport">
       <Icon class="mr-5px" icon="ep:download" />
       导出
     </el-button>
+
     <TabBarBtn />
 
     <Table2
@@ -117,10 +118,12 @@
 import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
 import { getRefundSettlementOrderPage } from '@/api/elderly/fee/leave-settle'
 import { levelSettleColumn } from '../column'
-import Form from './Form.vue'
 import RefundSettlement from './refund-settlement.vue'
 import Print from './Print.vue'
 import { useUserStore } from '@/store/modules/user'
+import { exportWithCustomHeaders } from '@/utils/excel-export'
+import { formatToDateTime } from '@/utils/dateUtil'
+import { Message as message } from '@/layout/components/Message'
 defineOptions({ name: 'LevelSettle' })
 const userStore = useUserStore()
 const loading = ref(true) // 列表的加载中
@@ -147,6 +150,7 @@ const getList = async () => {
     const data = await getRefundSettlementOrderPage(queryParams)
     list.value = data.list
     total.value = data.total
+    return list.value
   } finally {
     loading.value = false
   }
@@ -167,6 +171,53 @@ const resetQuery = () => {
   handleQuery()
 }
 
+/** 导出按钮操作 */
+const handleExport = async () => {
+  if (loading.value) return
+  try {
+    loading.value = true
+    queryParams.pageNo = 1
+    queryParams.pageSize = 99999
+    const exportList = await getList()
+    if (!exportList || exportList.length === 0) {
+      message.error('暂无数据可以导出!')
+      return
+    }
+    const statusOptions = getStrDictOptions(DICT_TYPE.SETTLEMENT_STATUS)
+    const data = exportList.map((item) => ({
+      ...item,
+      statusLabel:
+        statusOptions.find((dict) => String(dict.value) === String(item.status))?.label ||
+        item.status,
+      settlementTimeStr: item.settlementTime ? formatToDateTime(item.settlementTime) : '',
+      createdTimeStr: item.createdTime ? formatToDateTime(item.createdTime) : ''
+    }))
+    const headers = [
+      { key: 'tenantName', title: '所属机构', width: 40 },
+      { key: 'elderName', title: '长者姓名', width: 40 },
+      { key: 'bedName', title: '床位号', width: 40 },
+      { key: 'statusLabel', title: '结算状态', width: 40 },
+      { key: 'retreatDate', title: '退住日期', width: 40 },
+      { key: 'costDeadlineDate', title: '费用截止日期', width: 40 },
+      { key: 'refundableAmount', title: '应退金额', width: 40 },
+      { key: 'receivableAmount', title: '应收金额', width: 40 },
+      { key: 'refundAmount', title: '实缴金额', width: 40 },
+      { key: 'settlementTimeStr', title: '结算时间', width: 40 },
+      { key: 'settlementPersonName', title: '结算人', width: 40 },
+      { key: 'orderNumber', title: '结算单号', width: 40 },
+      { key: 'createdBy', title: '创建人', width: 40 },
+      { key: 'createdTimeStr', title: '创建时间', width: 40 }
+    ]
+    await exportWithCustomHeaders(data, headers, `退住结算-${formatToDateTime()}.xlsx`, '退住结算')
+  } catch (e) {
+    message.error('导出失败!')
+    console.log(e)
+  } finally {
+    queryParams.pageSize = 10
+    loading.value = false
+  }
+}
+
 /** 添加/修改操作 */
 // const formRef = ref()
 const openForm = (row: any = {}, isDetail: boolean = false) => {