Przeglądaj źródła

完成7张表的页面设计

unknown 2 miesięcy temu
rodzic
commit
f0e4933d89

+ 250 - 3
src/api/social-work/index.ts

@@ -65,11 +65,11 @@ export const floorActivityRecordGetPage = async (params) => {
 }
 
 export const floorActivityRecordCreate = async (data) => {
-  return await request.post({ url: '/floor-activity-record/create', data: data })
+  return await request.post({ url: '/elderly-build-floor-activity-text/create', data: data })
 }
 
 export const floorActivityRecordUpdate = async (data) => {
-  return await request.put({ url: '/floor-activity-record/update', data: data })
+  return await request.put({ url: '', data: data })
 }
 
 // ==================== 楼层活动照片记录表 ====================
@@ -86,9 +86,256 @@ export const floorActivityPhotoRecordGetPage = async (params) => {
 }
 
 export const floorActivityPhotoRecordCreate = async (data) => {
-  return await request.post({ url: '/floor-activity-photo-record/create', data: data })
+  return await request.post({ url: '/elderly-build-floor-activity-image/create', data: data })
 }
 
 export const floorActivityPhotoRecordUpdate = async (data) => {
   return await request.put({ url: '/floor-activity-photo-record/update', data: data })
 }
+
+// ==================== 评估服务量表 ====================
+
+// 创建 MMSE 评估记录
+export const mmseCreate = async (data) => {
+  return await request.post({ url: '/elderly-mmse/create', data })
+}
+
+// 更新 MMSE 评估记录
+export const mmseUpdate = async (data) => {
+  return await request.put({ url: '/elderly-mmse/update', data })
+}
+
+// 获得 MMSE 评估记录分页
+export const mmseGetPage = async (params) => {
+  return await request.get({ url: '/elderly-mmse/page', params })
+}
+
+// 获得 MMSE 评估记录
+export const mmseGetById = async (id) => {
+  return await request.get({ url: '/elderly-mmse/get?id=' + id })
+}
+
+// 根据长者ID获得 MMSE 评估记录
+export const mmseGetByElderId = async (elderId) => {
+  return await request.get({ url: '/elderly-mmse/get-by-elder-id?elderId=' + elderId })
+}
+
+// 删除 MMSE 评估记录
+export const mmseDelete = async (id) => {
+  return await request.delete({ url: `/elderly-mmse/delete?id=${id}` })
+}
+
+// 导出 MMSE 评估记录
+export const mmseExport = async (id) => {
+  return await request.download({ url: '/elderly-mmse/export?id=' + id })
+}
+
+
+// 感知觉与沟通评估表数据接口
+export interface PerceptionFormData {
+  id?: number
+  elderId: number
+  tenantId: number
+  assessmentData: Record<string, any>  // JSON 对象存储所有表单数据
+  totalScore?: number  // 总分(冗余字段,便于查询)
+  assessor?: string  // 评估人(冗余字段,便于查询)
+  assessDate?: string  // 评估日期(冗余字段,便于查询)
+  createdAt?: string
+  updatedAt?: string
+}
+
+// 创建感知觉与沟通评估记录
+export const perceptionCreate = async (data: PerceptionFormData) => {
+  return await request.post({ url: '/elderly-perception/create', data })
+}
+
+// 更新感知觉与沟通评估记录
+export const perceptionUpdate = async (data: PerceptionFormData) => {
+  return await request.put({ url: '/elderly-perception/update', data })
+}
+
+// 根据ID获取感知觉与沟通评估记录
+export const perceptionGetById = async (id: number) => {
+  return await request.get({ url: '/elderly-perception/get?id=' + id })
+}
+
+// 获取长者的感知觉与沟通评估记录
+export const perceptionGetByElderId = async (elderId: number) => {
+  return await request.get({ url: '/elderly-perception/getByElderId?elderId=' + elderId })
+}
+
+// 分页查询感知觉与沟通评估记录
+export const perceptionPage = async (params: {
+  pageNo: number
+  pageSize: number
+  elderId?: number
+  assessor?: string
+  assessDate?: string
+}) => {
+  return await request.post({ url: '/elderly-perception/page', data: params })
+}
+
+// 删除感知觉与沟通评估记录
+export const perceptionDelete = async (id: number) => {
+  return await request.delete({ url: `/elderly-perception/delete?id=${id}` })
+}
+
+// 导出感知觉与沟通评估记录
+export const perceptionExport = async (id: number) => {
+  return await request.download({ url: '/elderly-perception/export?id=' + id })
+}
+
+
+// NGASR自杀风险评估量表数据接口
+export interface NGASRFormData {
+  id?: number
+  elderId: number
+  tenantId: number
+  assessmentData: Record<string, any>  // JSON 对象存储所有表单数据
+  totalScore?: number  // 总分(冗余字段,便于查询)
+  assessor?: string  // 评估人(冗余字段,便于查询)
+  assessDate?: string  // 评估日期(冗余字段,便于查询)
+  createdAt?: string
+  updatedAt?: string
+}
+
+// 创建NGASR评估记录
+export const ngasrCreate = async (data: NGASRFormData) => {
+  return await request.post({ url: '/elderly-ngasr/create', data })
+}
+
+// 更新NGASR评估记录
+export const ngasrUpdate = async (data: NGASRFormData) => {
+  return await request.put({ url: '/elderly-ngasr/update', data })
+}
+
+// 根据ID获取NGASR评估记录
+export const ngasrGetById = async (id: number) => {
+  return await request.get({ url: '/elderly-ngasr/get?id=' + id })
+}
+
+// 获取长者的NGASR评估记录
+export const ngasrGetByElderId = async (elderId: number) => {
+  return await request.get({ url: '/elderly-ngasr/getByElderId?elderId=' + elderId })
+}
+
+// 分页查询NGASR评估记录
+export const ngasrPage = async (params: {
+  pageNo: number
+  pageSize: number
+  elderId?: number
+  assessor?: string
+  assessDate?: string
+}) => {
+  return await request.post({ url: '/elderly-ngasr/page', data: params })
+}
+
+// 删除NGASR评估记录
+export const ngasrDelete = async (id: number) => {
+  return await request.delete({ url: `/elderly-ngasr/delete?id=${id}` })
+}
+
+
+
+// 攻击风险因素评估量表数据接口
+export interface AttackRiskFormData {
+  id?: number
+  elderId: number
+  tenantId: number
+  assessmentData: Record<string, any>  // JSON 对象存储所有表单数据
+  attackLevel?: number  // 攻击风险等级(1=I级,2=II级,3=III级,4=IV级)
+  riskLevel?: string  // 风险等级(none/low/medium/high)
+  assessor?: string  // 评估人(冗余字段,便于查询)
+  assessDate?: string  // 评估日期(冗余字段,便于查询)
+  createdAt?: string
+  updatedAt?: string
+}
+
+// 创建攻击风险因素评估记录
+export const attackRiskCreate = async (data: AttackRiskFormData) => {
+  return await request.post({ url: '/elderly-attack-risk/create', data })
+}
+
+// 更新攻击风险因素评估记录
+export const attackRiskUpdate = async (data: AttackRiskFormData) => {
+  return await request.put({ url: '/elderly-attack-risk/update', data })
+}
+
+// 根据ID获取攻击风险因素评估记录
+export const attackRiskGetById = async (id: number) => {
+  return await request.get({ url: '/elderly-attack-risk/get?id=' + id })
+}
+
+// 获取长者的攻击风险因素评估记录
+export const attackRiskGetByElderId = async (elderId: number) => {
+  return await request.get({ url: '/elderly-attack-risk/getByElderId?elderId=' + elderId })
+}
+
+// 分页查询攻击风险因素评估记录
+export const attackRiskPage = async (params: {
+  pageNo: number
+  pageSize: number
+  elderId?: number
+  assessor?: string
+  assessDate?: string
+}) => {
+  return await request.post({ url: '/elderly-attack-risk/page', data: params })
+}
+
+// 删除攻击风险因素评估记录
+export const attackRiskDelete = async (id: number) => {
+  return await request.delete({ url: `/elderly-attack-risk/delete?id=${id}` })
+}
+
+
+
+// 抑郁自评量表(SDS)数据接口
+export interface SDSFormData {
+  id?: number
+  elderId: number
+  tenantId: number
+  assessmentData: Record<string, any>  // JSON 对象存储所有表单数据
+  rawScore?: number  // 粗分
+  standardScore?: number  // 标准分
+  depressionLevel?: string  // 抑郁程度
+  assessor?: string  // 评估人(冗余字段,便于查询)
+  assessDate?: string  // 评估日期(冗余字段,便于查询)
+  createdAt?: string
+  updatedAt?: string
+}
+
+// 创建抑郁自评量表记录
+export const sdsCreate = async (data: SDSFormData) => {
+  return await request.post({ url: '/elderly-sds/create', data })
+}
+
+// 更新抑郁自评量表记录
+export const sdsUpdate = async (data: SDSFormData) => {
+  return await request.put({ url: '/elderly-sds/update', data })
+}
+
+// 根据ID获取抑郁自评量表记录
+export const sdsGetById = async (id: number) => {
+  return await request.get({ url: '/elderly-sds/get?id=' + id })
+}
+
+// 获取长者的抑郁自评量表记录
+export const sdsGetByElderId = async (elderId: number) => {
+  return await request.get({ url: '/elderly-sds/getByElderId?elderId=' + elderId })
+}
+
+// 分页查询抑郁自评量表记录
+export const sdsPage = async (params: {
+  pageNo: number
+  pageSize: number
+  elderId?: number
+  assessor?: string
+  assessDate?: string
+}) => {
+  return await request.post({ url: '/elderly-sds/page', data: params })
+}
+
+// 删除抑郁自评量表记录
+export const sdsDelete = async (id: number) => {
+  return await request.delete({ url: `/elderly-sds/delete?id=${id}` })
+}

+ 1218 - 0
src/views/social-worker/assessment/AttackRiskFactors/AddForm.vue

@@ -0,0 +1,1218 @@
+<template>
+  <el-drawer
+    v-model="dialogVisible"
+    :title="title"
+    resizable
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    :destroy-on-close="true"
+    size="70%"
+    :before-close="handleClosed"
+  >
+
+    <div class="attack-risk-form">
+      <h1 class="form-title">攻击风险因素评估量表</h1>
+      <!-- 基本信息 -->
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>长者姓名</text>
+          <search-the-elderly ref="selectElderRef" :disabled="isDetail" @update_elder="elderUp" v-model="dataForm.elderName" :tId="dataForm.tenantId"/>
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>档案号</text>
+          <el-input v-if="!isDetail" v-model="dataForm.contractNumber" disabled />
+          <el-text v-else disabled="">{{dataForm.contractNumber}}</el-text>
+        </el-col>
+      </el-row>
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>入院日期</text>
+          <el-input v-if="!isDetail" :model-value="dayjs(dataForm.checkInTime).format('YYYY-MM-DD')=='Invalid Date'?'':dayjs(dataForm.checkInTime).format('YYYY-MM-DD')" disabled />
+          <el-text v-else disabled="">{{dayjs(dataForm.checkInTime).format('YYYY-MM-DD')}}</el-text>
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>床位号</text>
+          <el-input v-if="!isDetail" v-model="dataForm.bedName" disabled />
+          <el-text v-else disabled="">{{dataForm.bedName}}</el-text>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>评估人</text>
+          <el-input v-model="form.assessor"  />
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>评估日期</text>
+          <el-date-picker v-model="form.assessDate" type="date" style="width: 100%;"/>
+
+        </el-col>
+      </el-row>
+
+      <!-- 表单内容区域 -->
+      <div class="form-body">
+
+
+        <!-- 评估表格 -->
+        <div class="assessment-table">
+          <table>
+            <thead>
+              <tr>
+                <th class="content-col">评估内容</th>
+                <th class="level-col">级别</th>
+                <th class="select-col">选择</th>
+              </tr>
+            </thead>
+            <tbody>
+              <!-- I级 -->
+              <tr>
+                <td class="content" rowspan="7">
+                  <div class="content-title">存在右之一者,若为男性则有两项:</div>
+                  <div class="content-item">(1) 男性</div>
+                  <div class="content-item">(2) 精神分裂症,伴有幻听或被害妄想</div>
+                  <div class="content-item">(3) 躁狂</div>
+                  <div class="content-item">(4) 酒药依赖的脱瘾期</div>
+                  <div class="content-item">(5) 意识障碍伴行为紊乱</div>
+                  <div class="content-item">(6) 痴呆伴行为紊乱</div>
+                  <div class="content-item">(7) 既往人格不良者(有冲动、边缘型人格障碍)</div>
+                </td>
+                <td class="level" rowspan="7">I级</td>
+                <td class="select" rowspan="7">
+                  <el-radio-group v-model="form.attackLevel" :disabled="isDetail">
+                    <el-radio :value="1">  符合</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr>
+              
+              <!-- II级 -->
+              <tr>
+                <td class="content" rowspan="3">
+                  <div class="content-title">存在右侧情形之一者</div>
+                  <div class="content-item">(1) 被动的言语攻击行为,表现为激惹性增高,如无对象的抱怨、发牢骚、说怪话</div>
+                  <div class="content-item">(2) 交谈时态度不好、抵触、有敌意或不信任</div>
+                  <div class="content-item">(3) 或精神分裂症有命令性幻听者</div>
+                </td>
+                <td class="level" rowspan="3">II级</td>
+                <td class="select" rowspan="3">
+                  <el-radio-group v-model="form.attackLevel" :disabled="isDetail">
+                    <el-radio :value="2">  符合</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr></tr><tr></tr>
+              
+              <!-- III级 -->
+              <tr>
+                <td class="content" rowspan="4">
+                  <div class="content-title">存在右侧情形之一者</div>
+                  <div class="content-item">(1) 主动的言语攻击行为,如有对象的辱骂</div>
+                  <div class="content-item">(2) 被动的躯体攻击行为如毁物</div>
+                  <div class="content-item">(3) 在交往时出现社交粗暴(交谈时突然离去、躲避、推挡他人善意的躯体接触)</div>
+                  <div class="content-item">(4) 既往曾有过主动的躯体攻击行为</div>
+                </td>
+                <td class="level" rowspan="4">III级</td>
+                <td class="select" rowspan="4">
+                  <el-radio-group v-model="form.attackLevel" :disabled="isDetail">
+                    <el-radio :value="3">  符合</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr></tr><tr></tr><tr></tr>
+              
+              <!-- IV级 -->
+              <tr>
+                <td class="content" rowspan="2">
+                  <div class="content-title">存在右侧情形之一者</div>
+                  <div class="content-item">(1) 有主动的躯体攻击行为,如踢、打、咬或使用物</div>
+                  <div class="content-item">(2) 攻击行为在一天内至少出现两次以上或攻击行为造成了他人肉体上的伤害</div>
+                </td>
+                <td class="level" rowspan="2">IV级</td>
+                <td class="select" rowspan="2">
+                  <el-radio-group v-model="form.attackLevel" :disabled="isDetail">
+                    <el-radio :value="4">  符合</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+              <tr></tr>
+            </tbody>
+          </table>
+        </div>
+
+        <!-- 风险程度判断 -->
+        <div class="risk-judgment-section">
+          <div class="risk-judgment-title">风险程度判断:</div>
+          <div class="risk-options">
+            <el-radio v-model="form.riskLevel" value="none" :disabled="isDetail">
+                无风险:无级别
+            </el-radio>
+            <el-radio v-model="form.riskLevel" value="low" :disabled="isDetail">
+                低风险:I级
+            </el-radio>
+            <el-radio v-model="form.riskLevel" value="medium" :disabled="isDetail">
+                中风险:II级
+            </el-radio>
+            <el-radio v-model="form.riskLevel" value="high" :disabled="isDetail">
+                高风险:III级、IV级
+            </el-radio>
+          </div>
+        </div>
+
+        <!-- 预防措施 -->
+        <div class="preventive-section">
+          <div class="preventive-title">预防措施:</div>
+          <div class="preventive-options">
+            <el-checkbox v-model="form.preventiveMeasures" value="patrol" :disabled="isDetail">
+              加强巡视
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" value="handover" :disabled="isDetail">
+              严格交接班
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" value="checkItems" :disabled="isDetail">
+              检查有无危险物品
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" value="emotion" :disabled="isDetail">
+              注重长者情绪行为
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" value="other" :disabled="isDetail">
+              其他
+            </el-checkbox>
+            <el-input v-if="form.preventiveMeasures.includes('other')" v-model="form.preventiveMeasuresOther" placeholder="请输入其他措施" :disabled="isDetail" class="other-input"/>
+          </div>
+        </div>
+
+        <!-- 签名区域 -->
+        <div class="signature-section">
+          <div class="signature-row">
+            <div class="signature-item">
+              <span class="signature-label">家属/监护人签名:</span>
+              <el-input v-model="form.familySignature" :disabled="isDetail" class="signature-input"/>
+            </div>
+
+          </div>
+        </div>
+
+        <!-- 说明 -->
+        <div class="note-section">
+          <div class="note-title">说明:</div>
+          <div class="note-content">
+            <p>1. 新入住长者应在长者入住24小时内完成首次评估;</p>
+            <p>2. 定期评估:</p>
+            <p class="indent">(1)认知照护专区:高风险1个月评估一次,中风险、低风险3个月评估一次;</p>
+            <p class="indent">(2)非认知照护专区:高风险1个月评估一次,中风险3个月评估一次,低风险6个月评估一次;</p>
+            <p>3. 当长者身体发生变化者,应及时进行动态评估。</p>
+          </div>
+        </div>
+      </div>
+
+    </div>
+
+    <div><div style="font-weight: bold">这是提交字段,后端可照此字段创建数据表</div>:
+      {
+      "contractNumber": "",
+      "elderName": "",
+      "bedName": "",
+      "checkInTime": "",
+      "elderId": "",
+      "tenantId": 211,
+      "assessmentData": "{\"assessor\":\"\",\"assessDate\":\"\",\"attackLevel\":0,\"riskLevel\":\"\",\"preventiveMeasures\":[],\"preventiveMeasuresOther\":\"\",\"familySignature\":\"\",\"familySignDate\":\"\"}",
+      "attackLevel": 0,
+      "riskLevel": "",
+      "assessor": "",
+      "assessDate": "",
+      "orgType": 1
+      }
+    </div>
+
+    <template #footer>
+      <el-button @click="handleClosed">关闭</el-button>
+      <el-button   type="success" @click="handleExport">打印</el-button>
+      <el-button style="margin-left: 22px;margin-right: 30px" v-loading="formLoading" type="primary" v-show="!isDetail" @click="submitForm">确定</el-button>
+    </template>
+
+  </el-drawer>
+</template>
+
+<script lang="ts" setup>
+import { computed, ref, watch } from 'vue'
+
+import dayjs from 'dayjs'
+
+import { attackRiskCreate, attackRiskGetById, attackRiskUpdate, attackRiskGetByElderId } from "@/api/social-work";
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+const title = ref('')
+const dialogVisible = ref(false) // 弹窗
+const formRef = ref() // 表单 Ref
+const selectElderRef = ref() // 表单 Ref
+const isDetail = ref(false) // 是否详情打开
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+let dataForm = ref({
+  // 表单字段
+  id: undefined,
+  idCard: '',
+  contractNumber: '', //档案号
+  elderName: '',//长者姓名
+  bedName: '', //床位号
+  elderAge: '', //年龄
+  elderSex: '', //性别
+  checkInTime: '', //入院日期
+  elderId: '',
+  tenantId: undefined
+})
+
+
+
+
+const elderUp = (e) => {
+  dataForm.value.elderName = e.elderName
+  dataForm.value.elderId = e.id
+  dataForm.value.elderSex = e.elderSex === 1 ? '男' : '女'
+  dataForm.value.bedName = e.bedName || ''
+  dataForm.value.checkInTime = e.checkInTime
+  dataForm.value.contractNumber = e.contractNumber
+  dataForm.value.elderAge = e.elderAge
+}
+
+// ========== 攻击风险因素评估量表 表单序列化方法 ==========
+
+/** 风险程度文本 */
+const riskLevelText = computed(() => {
+  const level = form.attackLevel
+  if (!level || level === 0) return '无风险'
+  if (level === 1) return 'I级'
+  if (level === 2) return 'II级'
+  if (level === 3) return 'III级'
+  return 'IV级'
+})
+
+/** 风险程度样式类 */
+const riskLevelClass = computed(() => {
+  const level = form.attackLevel
+  if (!level || level === 0) return 'risk-none'
+  if (level === 1) return 'risk-low'
+  if (level === 2) return 'risk-medium'
+  return 'risk-high'
+})
+
+/** 自动判断风险等级 */
+const autoJudgeRiskLevel = () => {
+  const level = form.attackLevel
+  if (!level || level === 0) form.riskLevel = 'none'
+  else if (level === 1) form.riskLevel = 'low'
+  else if (level === 2) form.riskLevel = 'medium'
+  else form.riskLevel = 'high'
+}
+
+
+
+/** 将表单数据序列化为 JSON 对象 */
+const serializeFormData = () => {
+  return {
+    // 基本信息
+    assessor: form.assessor || '',
+    assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : '',
+
+    // 攻击风险等级(1=I级,2=II级,3=III级,4=IV级)
+    attackLevel: form.attackLevel || 0,
+
+    // 风险程度
+    riskLevel: form.riskLevel || '',
+
+    // 预防措施
+    preventiveMeasures: form.preventiveMeasures || [],
+    preventiveMeasuresOther: form.preventiveMeasuresOther || '',
+
+    // 签名
+    familySignature: form.familySignature || '',
+    familySignDate: form.familySignDate ? dayjs(form.familySignDate).format('YYYY-MM-DD') : ''
+  }
+}
+
+/** 将 JSON 对象反序列化为表单数据 */
+const deserializeFormData = (formData: Record<string, any>) => {
+  if (!formData) return
+
+  // 基本信息
+  form.assessor = formData.assessor || ''
+  form.assessDate = formData.assessDate ? dayjs(formData.assessDate).toDate() : ''
+
+  // 攻击风险等级
+  form.attackLevel = formData.attackLevel || 0
+
+  // 风险程度
+  form.riskLevel = formData.riskLevel || ''
+
+  // 预防措施
+  form.preventiveMeasures = formData.preventiveMeasures || []
+  form.preventiveMeasuresOther = formData.preventiveMeasuresOther || ''
+
+  // 签名
+  form.familySignature = formData.familySignature || ''
+  form.familySignDate = formData.familySignDate ? dayjs(formData.familySignDate).toDate() : ''
+}
+
+/** 重置攻击风险因素评估表表单数据 */
+const resetAttackRiskForm = () => {
+  form.assessor = ''
+  form.assessDate = ''
+
+  // 攻击风险等级
+  form.attackLevel = 0
+
+  // 风险程度
+  form.riskLevel = ''
+
+  // 预防措施
+  form.preventiveMeasures = []
+  form.preventiveMeasuresOther = ''
+
+  // 签名
+  form.familySignature = ''
+  form.familySignDate = ''
+}
+
+/** 打开弹窗 */
+const open = async (tenantId, id?: any, detail: boolean = false) => {
+  resetForm()
+  dialogVisible.value = true
+  dataForm.value.id = id || undefined
+  dataForm.value.tenantId = tenantId
+  isDetail.value = detail
+  if (id) {
+    title.value = "编辑-攻击风险因素评估"
+    // 加载评估数据
+    await loadAttackRiskData(id)
+  } else {
+    title.value = "新增-攻击风险因素评估"
+    // 如果选择了长者,尝试加载已有的评估数据
+    if (dataForm.value.elderId) {
+      await loadAttackRiskByElderId(dataForm.value.elderId)
+    }
+  }
+}
+
+/** 加载评估数据 */
+const loadAttackRiskData = async (id: number) => {
+  try {
+    const res = await attackRiskGetById(id)
+    if (res) {
+      // 填充长者基本信息
+      dataForm.value.elderName = res.elderName || ''
+      dataForm.value.elderId = res.elderId || ''
+      dataForm.value.elderSex = res.elderSex || ''
+      dataForm.value.bedName = res.bedName || ''
+      dataForm.value.checkInTime = res.checkInTime || ''
+      dataForm.value.contractNumber = res.contractNumber || ''
+      dataForm.value.elderAge = res.elderAge || ''
+
+      // 解析 assessmentData
+      if (res.assessmentData) {
+        const formData = JSON.parse(res.assessmentData)
+        deserializeFormData(formData)
+      }
+    }
+  } catch (error) {
+    message.error('加载评估数据失败')
+  }
+}
+
+/** 根据长者ID加载评估数据 */
+const loadAttackRiskByElderId = async (elderId: number) => {
+  try {
+    const res = await attackRiskGetByElderId(elderId)
+    if (res && res.assessmentData) {
+      const formData = JSON.parse(res.assessmentData)
+      deserializeFormData(formData)
+    }
+  } catch (error) {
+    // 无历史数据,不处理
+  }
+}
+
+const form = reactive({
+  // 基本信息
+  assessor: '',
+  assessDate: '',
+
+  // 攻击风险等级(0=无,1=I级,2=II级,3=III级,4=IV级)
+  attackLevel: 0,
+
+  // 风险程度
+  riskLevel: '',
+
+  // 预防措施
+  preventiveMeasures: [],
+  preventiveMeasuresOther: '',
+
+  // 签名
+  familySignature: '',
+  familySignDate: ''
+})
+
+// 监听攻击等级变化,自动判断风险等级
+watch(() => form.attackLevel, () => {
+  autoJudgeRiskLevel()
+})
+
+
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  if (formLoading.value) {
+    return
+  }
+  formLoading.value = true
+  // 提交请求
+  try {
+    const assessmentData = serializeFormData()
+    const tempParams = {
+      ...dataForm.value,
+      assessmentData: JSON.stringify(assessmentData),
+      attackLevel: form.attackLevel,
+      riskLevel: form.riskLevel,
+      assessor: form.assessor,
+      assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''
+    }
+
+    if (dataForm.value.id) {
+      const res = await attackRiskUpdate(tempParams)
+      if (res) {
+        message.success(t('common.updateSuccess'))
+        dialogVisible.value = false
+        // 发送操作成功的事件
+        emit('success')
+      }
+    } else {
+      const res = await attackRiskCreate(tempParams)
+      if (res) {
+        message.success(t('common.createSuccess'))
+        dialogVisible.value = false
+        // 发送操作成功的事件
+        emit('success')
+      }
+    }
+  } finally {
+    setTimeout(() => {
+      formLoading.value = false
+    }, 500)
+  }
+}
+
+
+
+/** 重置表单 */
+const resetForm = () => {
+  dataForm.value = {
+    id: undefined,
+    idCard: '',
+    contractNumber: '', //档案号
+    elderName: '',//长者姓名
+    bedName: '', //床位号
+    elderAge: '', //年龄
+    elderSex: '', //性别
+    checkInTime: '', //入院日期
+    elderId: '',
+    tenantId: undefined
+  }
+  formRef.value?.resetFields()
+
+  // 重置攻击风险因素评估表表单
+  resetAttackRiskForm()
+}
+
+// 关闭表单
+const handleClosed = () => {
+  dialogVisible.value = false
+  resetForm()
+}
+
+/** 导出打印 */
+const handleExport = () => {
+  // 创建打印窗口
+  const printWindow = window.open('', '_blank')
+  if (!printWindow) {
+    message.error('请允许弹出窗口')
+    return
+  }
+
+  // 构建打印内容
+  const printContent = `
+    <!DOCTYPE html>
+    <html>
+    <head>
+      <meta charset="UTF-8">
+      <title>攻击风险因素评估量表 - ${dataForm.value.elderName || ''}</title>
+      <style>
+        @media print {
+          @page { size: A4 portrait; margin: 15mm; }
+        }
+        body {
+          font-family: 'SimSun', 'Microsoft YaHei', serif;
+          font-size: 10pt;
+          line-height: 1.4;
+          color: #333;
+        }
+        .header {
+          text-align: center;
+          margin-bottom: 15px;
+          border-bottom: 2px solid #333;
+          padding-bottom: 10px;
+        }
+        .header h1 {
+          font-size: 16pt;
+          margin: 0;
+          letter-spacing: 2px;
+        }
+        .info-section {
+          margin-bottom: 15px;
+          padding: 10px;
+          border: 1px solid #999;
+          background: #fafafa;
+        }
+        .info-row {
+          display: flex;
+          flex-wrap: wrap;
+          gap: 20px;
+        }
+        .info-item {
+          display: flex;
+          align-items: center;
+        }
+        .info-item .label {
+          font-weight: bold;
+          margin-right: 8px;
+          color: #555;
+        }
+        .info-item .value {
+          border-bottom: 1px solid #333;
+          min-width: 80px;
+          padding: 0 5px;
+          text-align: center;
+        }
+        .score-summary {
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          padding: 10px 15px;
+          background: #f0f0f0;
+          border: 2px solid #333;
+          margin-bottom: 15px;
+        }
+        .total-score {
+          font-size: 14pt;
+          font-weight: bold;
+        }
+        .total-score .score-value {
+          color: #d9534f;
+          font-size: 18pt;
+        }
+
+        .assessment-table {
+          width: 100%;
+          border-collapse: collapse;
+          margin-bottom: 15px;
+        }
+        .assessment-table th, .assessment-table td {
+          border: 1px solid #333;
+          padding: 8px;
+          text-align: left;
+          vertical-align: top;
+        }
+        .assessment-table th {
+          background: #e8e8e8;
+          font-weight: bold;
+          text-align: center;
+        }
+        .assessment-table .content-col {
+          width: 65%;
+        }
+        .assessment-table .level-col {
+          width: 10%;
+          text-align: center;
+        }
+        .assessment-table .select-col {
+          width: 25%;
+          text-align: center;
+        }
+        .assessment-table .content-title {
+          font-weight: bold;
+          margin-bottom: 5px;
+        }
+        .assessment-table .content-item {
+          margin-left: 15px;
+          margin-bottom: 3px;
+        }
+
+        .risk-judgment-section {
+          margin: 15px 0;
+          padding: 10px;
+          border: 1px solid #999;
+        }
+        .risk-judgment-title {
+          font-weight: bold;
+          margin-bottom: 10px;
+        }
+        .risk-options {
+          display: flex;
+          flex-wrap: wrap;
+          gap: 15px;
+        }
+
+        .measures-section {
+          margin: 15px 0;
+          border: 1px solid #999;
+        }
+        .measures-title {
+          font-weight: bold;
+          background: #e8e8e8;
+          padding: 8px 12px;
+          border-bottom: 1px solid #999;
+        }
+        .measures-content {
+          padding: 10px 12px;
+        }
+        .measure-item {
+          margin-bottom: 8px;
+          font-size: 10pt;
+        }
+        .measure-other {
+          margin-left: 10px;
+          border-bottom: 1px solid #333;
+          min-width: 200px;
+          display: inline-block;
+        }
+
+        .signature-section {
+          margin-top: 20px;
+          padding: 15px;
+          border: 1px solid #999;
+        }
+        .signature-row {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+        }
+        .signature-item {
+          display: flex;
+          align-items: center;
+          gap: 10px;
+        }
+        .signature-label {
+          font-weight: bold;
+        }
+        .signature-value {
+          border-bottom: 1px solid #333;
+          min-width: 150px;
+          height: 25px;
+        }
+
+        .note-section {
+          margin-top: 15px;
+          padding: 10px;
+          border: 1px solid #999;
+          background: #fafafa;
+        }
+        .note-title {
+          font-weight: bold;
+          margin-bottom: 8px;
+        }
+        .note-content {
+          font-size: 9pt;
+          line-height: 1.6;
+        }
+        .note-content p {
+          margin: 3px 0;
+        }
+        .note-content .indent {
+          margin-left: 20px;
+        }
+      </style>
+    </head>
+    <body>
+      <div class="header">
+        <h1>攻击风险因素评估量表</h1>
+      </div>
+
+      <div class="info-section">
+        <div class="info-row">
+          <div class="info-item">
+            <span class="label">长者姓名:</span>
+            <span class="value">${dataForm.value.elderName || ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">档案号:</span>
+            <span class="value">${dataForm.value.contractNumber || ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">床位号:</span>
+            <span class="value">${dataForm.value.bedName || ''}</span>
+          </div>
+        </div>
+        <div class="info-row" style="margin-top: 10px;">
+          <div class="info-item">
+            <span class="label">评估日期:</span>
+            <span class="value">${form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">评估人:</span>
+            <span class="value">${form.assessor || ''}</span>
+          </div>
+        </div>
+      </div>
+
+
+
+      <!-- 评估表格 -->
+      <table class="assessment-table">
+        <thead>
+          <tr>
+            <th class="content-col">评估内容</th>
+            <th class="level-col">级别</th>
+            <th class="select-col">选择</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr>
+            <td class="content">
+              <div class="content-title">存在右之一者,若为男性则有两项:</div>
+              <div class="content-item">(1) 男性</div>
+              <div class="content-item">(2) 精神分裂症,伴有幻听或被害妄想</div>
+              <div class="content-item">(3) 躁狂</div>
+              <div class="content-item">(4) 酒药依赖的脱瘾期</div>
+              <div class="content-item">(5) 意识障碍伴行为紊乱</div>
+              <div class="content-item">(6) 痴呆伴行为紊乱</div>
+              <div class="content-item">(7) 既往人格不良者(有冲动、边缘型人格障碍)</div>
+            </td>
+            <td class="level">I级</td>
+            <td class="select">${form.attackLevel === 1 ? '☑' : '☐'} 符合</td>
+          </tr>
+          <tr>
+            <td class="content">
+              <div class="content-title">存在右侧情形之一者</div>
+              <div class="content-item">(1) 被动的言语攻击行为,表现为激惹性增高,如无对象的抱怨、发牢骚、说怪话</div>
+              <div class="content-item">(2) 交谈时态度不好、抵触、有敌意或不信任</div>
+              <div class="content-item">(3) 或精神分裂症有命令性幻听者</div>
+            </td>
+            <td class="level">II级</td>
+            <td class="select">${form.attackLevel === 2 ? '☑' : '☐'} 符合</td>
+          </tr>
+          <tr>
+            <td class="content">
+              <div class="content-title">存在右侧情形之一者</div>
+              <div class="content-item">(1) 主动的言语攻击行为,如有对象的辱骂</div>
+              <div class="content-item">(2) 被动的躯体攻击行为如毁物</div>
+              <div class="content-item">(3) 在交往时出现社交粗暴(交谈时突然离去、躲避、推挡他人善意的躯体接触)</div>
+              <div class="content-item">(4) 既往曾有过主动的躯体攻击行为</div>
+            </td>
+            <td class="level">III级</td>
+            <td class="select">${form.attackLevel === 3 ? '☑' : '☐'} 符合</td>
+          </tr>
+          <tr>
+            <td class="content">
+              <div class="content-title">存在右侧情形之一者</div>
+              <div class="content-item">(1) 有主动的躯体攻击行为,如踢、打、咬或使用物</div>
+              <div class="content-item">(2) 攻击行为在一天内至少出现两次以上或攻击行为造成了他人肉体上的伤害</div>
+            </td>
+            <td class="level">IV级</td>
+            <td class="select">${form.attackLevel === 4 ? '☑' : '☐'} 符合</td>
+          </tr>
+        </tbody>
+      </table>
+
+      <!-- 风险程度判断 -->
+      <div class="risk-judgment-section">
+        <div class="risk-judgment-title">风险程度判断:</div>
+        <div class="risk-options">
+          <span class="risk-option">${form.riskLevel === 'none' ? '☑' : '☐'} 无风险:无级别</span>
+          <span class="risk-option">${form.riskLevel === 'low' ? '☑' : '☐'} 低风险:I级</span>
+          <span class="risk-option">${form.riskLevel === 'medium' ? '☑' : '☐'} 中风险:II级</span>
+          <span class="risk-option">${form.riskLevel === 'high' ? '☑' : '☐'} 高风险:III级、IV级</span>
+        </div>
+      </div>
+
+      <!-- 预防措施 -->
+      <div class="measures-section">
+        <div class="measures-title">预防措施</div>
+        <div class="measures-content">
+          <div class="measure-item">${form.preventiveMeasures?.includes('patrol') ? '☑' : '☐'} 加强巡视</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('handover') ? '☑' : '☐'} 严格交接班</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('checkItems') ? '☑' : '☐'} 检查有无危险物品</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('emotion') ? '☑' : '☐'} 注重长者情绪行为</div>
+          <div class="measure-item">
+            ${form.preventiveMeasures?.includes('other') ? '☑' : '☐'} 其他
+            ${form.preventiveMeasures?.includes('other') ? '<span class="measure-other">' + (form.preventiveMeasuresOther || '') + '</span>' : ''}
+          </div>
+        </div>
+      </div>
+
+      <!-- 签名区域 -->
+      <div class="signature-section">
+        <div class="signature-row">
+          <div class="signature-item">
+            <span class="signature-label">家属/监护人签名:</span>
+            <span class="signature-value">${form.familySignature || ''}</span>
+          </div>
+
+        </div>
+      </div>
+
+      <!-- 说明 -->
+      <div class="note-section">
+        <div class="note-title">说明:</div>
+        <div class="note-content">
+          <p>1. 新入住长者应在长者入住24小时内完成首次评估;</p>
+          <p>2. 定期评估:</p>
+          <p class="indent">(1)认知照护专区:高风险1个月评估一次,中风险、低风险3个月评估一次;</p>
+          <p class="indent">(2)非认知照护专区:高风险1个月评估一次,中风险3个月评估一次,低风险6个月评估一次;</p>
+          <p>3. 当长者身体发生变化者,应及时进行动态评估。</p>
+        </div>
+      </div>
+    </body>
+    </html>
+  `
+
+  // 写入内容并打印
+  printWindow.document.write(printContent)
+  printWindow.document.close()
+
+  // 延迟打印,确保样式加载完成
+  setTimeout(() => {
+    printWindow.print()
+  }, 500)
+}
+
+</script>
+
+<style scoped lang="scss">
+
+.form-title {
+  text-align: center;
+  font-size: 20px;
+  width: 100%;
+  margin-bottom: 20px;
+}
+
+.attack-risk-form {
+  max-width: 1200px;
+  margin: 0 auto;
+  background: #fff;
+
+
+
+
+
+  .info-row {
+    display: flex;
+    gap: 40px;
+    width: 100%;
+    flex-direction: row;
+    align-items: center;
+    margin-bottom: 10px;
+
+    .info-item {
+      display: flex;
+      align-items: center;
+      gap: 8px;
+
+      .label {
+        width: 82px;
+        text-align: right;
+        margin-right: 4px;
+        white-space: nowrap;
+      }
+    }
+  }
+
+
+  .form-body {
+    border: 1px solid #333;
+    padding: 15px;
+  }
+
+  // 调整 Element Plus 组件样式
+  :deep(.el-input__inner) {
+    height: 28px;
+    line-height: 28px;
+    border-top: none;
+    border-left: none;
+    border-right: none;
+    border-radius: 0;
+    padding: 0 4px;
+
+    &:focus {
+      border-color: #409eff;
+    }
+  }
+
+  :deep(.el-checkbox__label),
+  :deep(.el-radio__label) {
+    padding-left: 4px;
+  }
+}
+.row{
+  margin-bottom: 12px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  text{
+    text-align: right;
+    margin-right: 4px;
+    width: 82px;
+  }
+}
+
+// NGASR自杀风险评估量表 特有样式
+.total-score-section {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  margin-bottom: 20px;
+
+  .total-score {
+    display: flex;
+    align-items: baseline;
+    gap: 4px;
+
+    .score-label {
+      font-size: 16px;
+      font-weight: bold;
+    }
+
+    .score-value {
+      font-size: 28px;
+      font-weight: bold;
+      color: #409eff;
+    }
+
+    .score-max {
+      font-size: 14px;
+      color: #909399;
+    }
+  }
+
+  .risk-level {
+    font-size: 16px;
+    font-weight: bold;
+    padding: 8px 16px;
+    border-radius: 4px;
+
+    &.risk-none {
+      color: #67c23a;
+      background: #f0f9eb;
+    }
+
+    &.risk-low {
+      color: #e6a23c;
+      background: #fdf6ec;
+    }
+
+    &.risk-medium {
+      color: #f56c6c;
+      background: #fef0f0;
+    }
+
+    &.risk-high {
+      color: #f56c6c;
+      background: #fef0f0;
+      border: 1px solid #f56c6c;
+    }
+  }
+}
+
+.assessment-table {
+  width: 100%;
+  border-collapse: collapse;
+  margin-bottom: 20px;
+
+  table {
+    width: 100%;
+    border: 1px solid #333;
+
+    th, td {
+      border: 1px solid #333;
+      padding: 12px;
+      text-align: left;
+      vertical-align: top;
+    }
+
+    th {
+      background: #f5f7fa;
+      font-weight: bold;
+      text-align: center;
+    }
+
+    .content-col {
+      width: 65%;
+    }
+
+    .level-col {
+      width: 10%;
+      text-align: center;
+    }
+
+    .select-col {
+      width: 25%;
+      text-align: center;
+    }
+
+    .content {
+      text-align: left;
+
+      .content-title {
+        font-weight: bold;
+        margin-bottom: 8px;
+      }
+
+      .content-item {
+        margin-left: 15px;
+        margin-bottom: 4px;
+        font-size: 13px;
+      }
+    }
+
+    .level {
+      text-align: center;
+      font-weight: bold;
+    }
+
+    .select {
+      text-align: center;
+
+      :deep(.el-radio) {
+        margin-right: 0;
+      }
+    }
+  }
+}
+
+.risk-judgment-section {
+  margin: 20px 0;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .risk-judgment-title {
+    font-weight: bold;
+    font-size: 16px;
+    margin-bottom: 12px;
+    color: #303133;
+  }
+
+  .risk-options {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 20px;
+
+    :deep(.el-radio) {
+      margin-right: 0;
+    }
+  }
+}
+
+.preventive-section {
+  margin: 20px 0;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .preventive-title {
+    font-weight: bold;
+    font-size: 16px;
+    margin-bottom: 12px;
+    color: #303133;
+  }
+
+  .preventive-options {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 15px;
+
+    :deep(.el-checkbox) {
+      margin-right: 20px;
+      margin-bottom: 8px;
+    }
+
+    .other-input {
+      width: 200px;
+      margin-left: 10px;
+    }
+  }
+}
+
+.signature-section {
+  margin: 20px 0;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .signature-row {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    gap: 20px;
+  }
+
+  .signature-item {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+
+    &.date-item {
+      :deep(.el-date-picker) {
+        width: 150px;
+      }
+    }
+  }
+
+  .signature-label {
+    font-weight: bold;
+    white-space: nowrap;
+  }
+
+  .signature-input {
+    width: 150px;
+  }
+
+  .date-picker {
+    width: 150px;
+  }
+}
+
+.note-section {
+  margin-top: 20px;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .note-title {
+    font-weight: bold;
+    font-size: 16px;
+    margin-bottom: 12px;
+    color: #303133;
+  }
+
+  .note-content {
+    font-size: 13px;
+    line-height: 1.8;
+    color: #606266;
+
+    p {
+      margin: 5px 0;
+    }
+
+    .indent {
+      margin-left: 20px;
+    }
+  }
+}
+</style>

+ 327 - 0
src/views/social-worker/assessment/AttackRiskFactors/index.vue

@@ -0,0 +1,327 @@
+<template>
+  <ContentWrap>
+    <!-- 保护性约束观察记录表 -->
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="110px"
+    >
+      <el-form-item label="长者姓名">
+        <el-input
+          v-model="queryParams.elderName"
+          placeholder="长者姓名"
+          class="!w-240px"
+          clearable
+        />
+      </el-form-item>
+
+
+
+      <el-form-item label="记录日期">
+        <el-date-picker
+          size="default"
+          ref="selectRef"
+          class="!w-240px"
+          v-model="queryParams.recordDate"
+          type="daterange"
+          :clearable="true"
+          :editable="false"
+          placeholder="选择记录日期"
+          value-format="YYYY-MM-DD"
+          format="YYYY-MM-DD"
+          date-format="YYYY-MM-DD"
+        />
+      </el-form-item>
+
+      <el-form-item>
+        <el-button @click="handleQuery" style="margin-left: 2vw"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <div class="mb-10px">
+
+      <ButtonAdd @click="openForm(undefined)"  />
+      <!--      <el-button @click="inputH" type="success"><Icon icon="fa:cloud-upload" :size="16" class="mr-1"/>导入</el-button>-->
+      <ButtonImport @click="handleImportCard"  />
+
+
+    </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">
+          {{
+            scope.$index + (queryParams.pageNo * queryParams.pageSize - queryParams.pageSize) + 1
+          }}
+        </template>
+      </el-table-column>
+
+
+      <el-table-column prop="elderName" header-align="center" align="center" label="长者姓名" min-width="150" show-overflow-tooltip/>
+      <el-table-column prop="bedName" header-align="center" align="center" label="床位号" min-width="200" show-overflow-tooltip/>
+      <el-table-column prop="recordDate" header-align="center" align="center" label="记录日期" min-width="200" show-overflow-tooltip/>
+
+      <el-table-column prop="creator" header-align="center" align="center" label="记录人" min-width="200" show-overflow-tooltip/>
+
+
+      <el-table-column label="操作" align="center" width="200" >
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            @click="openFormEdit(scope.row, scope.row.id)"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="warning"
+            @click="openFormDetail(scope.row,scope.row.id)"
+          >
+            详情
+          </el-button>
+          <el-button
+            link
+            type="danger"
+            @click="openClose(scope.row)"
+          >
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+  <AddForm ref="formRef" @success="getList" />
+
+  <!-- 通用批量导出弹窗 -->
+  <BatchExportDialog
+    :show="showBatchExport"
+    :title="exportConfig.title"
+    :loading="exportLoading"
+    :batch-min="exportConfig.batchMin"
+    :batch-max="exportConfig.batchMax"
+    :count-min="exportConfig.countMin"
+    :count-max="exportConfig.countMax"
+    :default-batch="exportConfig.defaultBatch"
+    :default-count="exportConfig.defaultCount"
+    :description="exportConfig.description"
+    @update:show="showBatchExport = $event"
+    @confirm="handleBatchExport"
+    @cancel="showBatchExport = false"
+  />
+
+
+  <Import
+    ref="importRef"
+    @success="getList"
+    :config="{
+      title: '导入',
+      downloadUrl: 'elderly-service-order/get-import-template',
+      excelTempName: '居家工单-【导入】模板',
+      importUrl: '/elderly-service-order/import',
+      failExportUrl: '',
+    }"
+  />
+
+</template>
+
+<script setup lang="ts">
+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 {formatTimestamp, getCurrentMonthRange} from "@/utils/dateUtil";
+import Import from "@/components/ImportFile/index.vue";
+import {restraintCreatePage, restraintDelete} from "@/api/elderly/nursing/keep-fit";
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+const userStore = useUserStore()
+const loading = ref(true) // 列表的加载中
+const detailRef = ref()
+const importRef = ref()
+const total = ref(0) // 列表的总页数
+const list = ref([]) // 列表的数据
+
+// 状态管理
+const showBatchExport = ref(false)
+const exportConfig = ref({
+  title: '',
+  batchMin: 1,
+  batchMax: 999,
+  countMin: 1,
+  countMax: 200,
+  defaultBatch: 1,
+  defaultCount: 200,
+  description: [] as string[]
+})
+const exportLoading = ref(false)
+
+let queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  elderName: '',
+  creator: '',
+  recordDate: getCurrentMonthRange(),
+  tenantIds: userStore.orgTenantId
+})
+const queryFormRef = ref() // 搜索的表单
+
+const inputH = () => {
+  importRef.value.open(queryParams.tenantIds[0])
+}
+// 打开导出弹窗
+const handleImportCard = async () => {
+
+  // showBatchExport.value = true
+}
+
+// 处理批量导出
+const handleBatchExport = async (batch: number, count: number) => {
+  exportLoading.value = true
+  console.log(batch,count)
+  // try {
+  //   let queryParams = {
+  //     pageNo: batch,
+  //     pageSize: count,
+  //     tenantId: userStore.orgTenantId[0]
+  //   }
+  //   const list = await careRecordsPage(queryParams)
+  //   if (list.length <= 0) {
+  //     message.error('暂无数据可以导出!')
+  //     return
+  //   }
+  //   const headers = [
+  //     { key: 'organizationName', title: '机构名称' },
+  //     { key: 'visitName', title: '姓名' },
+  //     { key: 'visitPhone', title: '手机号' },
+  //     { key: 'visitDate', title: '预约时间' },
+  //     { key: 'accompanyCount', title: '陪同人数' },
+  //     { key: 'reason', title: '理由' }
+  //   ]
+  //   exportWithExpandedObjectArrays(list, headers, `医疗护理记录${formatToDateTime()}.xlsx`, '医疗护理记录')
+  // } catch (_) {}
+
+}
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    //let queryP = {...queryParams,discoveryTime:queryParams.discoveryTime?[queryParams.discoveryTime[0]+" 00:00:00",queryParams.discoveryTime[1]+" 23:59:59"]:null}
+    const data = await restraintCreatePage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = async () => {
+  if (!queryFormRef.value) return
+  const valid = await queryFormRef.value.validate()
+  if (!valid) return
+  queryParams.pageNo = 1
+  await getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryParams.elderName = ''
+  queryParams.creator = ''
+  queryParams.tenantIds = userStore.orgTenantId
+  queryParams.recordDate= getCurrentMonthRange()
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+/** 添加/修改操作 */
+const formRef = ref()
+const openForm = (id?: number) => {
+  if(queryParams.tenantIds.length == 0 || queryParams.tenantIds.length > 1){
+    message.error('新增只能选择一个机构')
+    return
+  }
+  formRef.value.open(queryParams.tenantIds[0], id,false)
+}
+
+const editRef = ref()
+const openFormEdit = (row: any = {}, id?: number) => {
+  formRef.value.open(row.tenantId, id,false)
+}
+
+
+const openFormDetail = (row: any = {},id?: number) => {
+  formRef.value.open(row.tenantId,id,true)
+}
+
+
+
+
+
+const openClose = async (item) => {
+  try {
+    console.log("任务ID",item)
+    const res = await message.confirm('确定要删除吗?', '提示')
+    if (res == 'confirm') {
+      // 发起
+      try {
+        const res = await restraintDelete(item.id)
+        if (res){
+          message.success(t('common.updateSuccess'))
+        }
+      }catch(err) {}
+    }
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 取消按钮操作 */
+const cancelDelete = async (id: number) => {
+  try {
+    // 取消的二次确认
+    await message.cancelConfirm()
+    // 发起取消
+    // await elderlyBakDel(id)
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+const route = useRoute()
+/** 初始化 **/
+onMounted(() => {
+  if(route.query && route.query.elderName){
+    queryParams.elderName = route.query.elderName as string
+  }
+  getList()
+})
+
+// 表头格式
+const tableHeaderColor = ({ rowIndex }: any) => {
+  if (rowIndex === 0) {
+    return {
+      backgroundColor: '#f8f8f9',
+      color: '#666666',
+      fontWeight: 'bold'
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss"></style>

+ 1511 - 0
src/views/social-worker/assessment/MMSE/AddForm.vue

@@ -0,0 +1,1511 @@
+<template>
+  <el-drawer
+    v-model="dialogVisible"
+    :title="title"
+    resizable
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    :destroy-on-close="true"
+    size="70%"
+    :before-close="handleClosed"
+  >
+
+    <div class="mmse-form">
+      <h1 class="form-title">简易精神状态评价量表</h1>
+        <!-- 基本信息 -->
+        <el-row :gutter="40">
+          <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+            <text>长者姓名</text>
+            <search-the-elderly ref="selectElderRef" :disabled="isDetail" @update_elder="elderUp" v-model="dataForm.elderName" :tId="dataForm.tenantId"/>
+          </el-col>
+          <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+            <text>档案号</text>
+            <el-input v-if="!isDetail" v-model="dataForm.contractNumber" disabled />
+            <el-text v-else disabled="">{{dataForm.contractNumber}}</el-text>
+          </el-col>
+        </el-row>
+        <el-row :gutter="40">
+          <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+            <text>入院日期</text>
+            <el-input v-if="!isDetail" :model-value="dayjs(dataForm.checkInTime).format('YYYY-MM-DD')=='Invalid Date'?'':dayjs(dataForm.checkInTime).format('YYYY-MM-DD')" disabled />
+            <el-text v-else disabled="">{{dayjs(dataForm.checkInTime).format('YYYY-MM-DD')}}</el-text>
+          </el-col>
+          <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+            <text>床位号</text>
+            <el-input v-if="!isDetail" v-model="dataForm.bedName" disabled />
+            <el-text v-else disabled="">{{dataForm.bedName}}</el-text>
+          </el-col>
+        </el-row>
+
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>评估人</text>
+          <el-input v-model="form.assessor"  />
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>评估日期</text>
+          <el-date-picker v-model="form.assessDate" type="date" style="width: 100%;"/>
+
+        </el-col>
+      </el-row>
+
+        <!-- 表单内容区域 -->
+        <div class="form-body">
+          <!-- 总分显示 -->
+          <div class="total-score-section">
+            <div class="total-score">
+              <span class="score-label">总分:</span>
+              <span class="score-value">{{ totalScore }}</span>
+              <span class="score-max">/ 30分</span>
+            </div>
+
+          </div>
+
+          <!-- 一、定向力 (10分) -->
+          <div class="section">
+            <div class="section-title">一、定向力(10分)</div>
+
+            <div class="form-item">
+              <span class="item-number">1.</span>
+              <span class="item-label">时间定向(5分):</span>
+              <div class="score-group">
+                <div class="score-row">
+                  <span>今年是哪一年?</span>
+                  <el-radio-group v-model="form.orientation.year" size="small">
+                    <el-radio :value="1">正确(1分)</el-radio>
+                    <el-radio :value="0">错误(0分)</el-radio>
+                  </el-radio-group>
+                </div>
+                <div class="score-row">
+                  <span>现在是什么季节?</span>
+                  <el-radio-group v-model="form.orientation.season" size="small">
+                    <el-radio :value="1">正确(1分)</el-radio>
+                    <el-radio :value="0">错误(0分)</el-radio>
+                  </el-radio-group>
+                </div>
+                <div class="score-row">
+                  <span>现在是几月份?</span>
+                  <el-radio-group v-model="form.orientation.month" size="small">
+                    <el-radio :value="1">正确(1分)</el-radio>
+                    <el-radio :value="0">错误(0分)</el-radio>
+                  </el-radio-group>
+                </div>
+                <div class="score-row">
+                  <span>今天是几号?</span>
+                  <el-radio-group v-model="form.orientation.day" size="small">
+                    <el-radio :value="1">正确(1分)</el-radio>
+                    <el-radio :value="0">错误(0分)</el-radio>
+                  </el-radio-group>
+                </div>
+                <div class="score-row">
+                  <span>今天是星期几?</span>
+                  <el-radio-group v-model="form.orientation.weekDay" size="small">
+                    <el-radio :value="1">正确(1分)</el-radio>
+                    <el-radio :value="0">错误(0分)</el-radio>
+                  </el-radio-group>
+                </div>
+              </div>
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">2.</span>
+              <span class="item-label">地点定向(5分):</span>
+              <div class="score-group">
+                <div class="score-row">
+                  <span>你住在那个省?</span>
+                  <el-radio-group v-model="form.orientation.province" size="small">
+                    <el-radio :value="1">正确(1分)</el-radio>
+                    <el-radio :value="0">错误(0分)</el-radio>
+                  </el-radio-group>
+                </div>
+                <div class="score-row">
+                  <span>你住在那个县(区)?</span>
+                  <el-radio-group v-model="form.orientation.county" size="small">
+                    <el-radio :value="1">正确(1分)</el-radio>
+                    <el-radio :value="0">错误(0分)</el-radio>
+                  </el-radio-group>
+                </div>
+                <div class="score-row">
+                  <span>你住在那个乡(街道)?</span>
+                  <el-radio-group v-model="form.orientation.town" size="small">
+                    <el-radio :value="1">正确(1分)</el-radio>
+                    <el-radio :value="0">错误(0分)</el-radio>
+                  </el-radio-group>
+                </div>
+                <div class="score-row">
+                  <span>咱们现在在哪个养老院?</span>
+                  <el-radio-group v-model="form.orientation.nursingHome" size="small">
+                    <el-radio :value="1">正确(1分)</el-radio>
+                    <el-radio :value="0">错误(0分)</el-radio>
+                  </el-radio-group>
+                </div>
+                <div class="score-row">
+                  <span>咱们现在在第几层楼?</span>
+                  <el-radio-group v-model="form.orientation.floor" size="small">
+                    <el-radio :value="1">正确(1分)</el-radio>
+                    <el-radio :value="0">错误(0分)</el-radio>
+                  </el-radio-group>
+                </div>
+              </div>
+            </div>
+          </div>
+
+          <!-- 二、记忆力 (3分) -->
+          <div class="section">
+            <div class="section-title">二、记忆力(3分)</div>
+            <div class="form-item">
+              <span class="item-number">3.</span>
+              <span class="item-label">告诉你三种东西,我说完后,请你重复一遍并记住,待会还会问你(各1分,共3分):</span>
+              <el-radio-group v-model="form.memory.score" size="small">
+                <el-radio :value="3">3分</el-radio>
+                <el-radio :value="2">2分</el-radio>
+                <el-radio :value="1">1分</el-radio>
+                <el-radio :value="0">0分</el-radio>
+              </el-radio-group>
+            </div>
+          </div>
+
+          <!-- 三、注意力和计算力 (5分) -->
+          <div class="section">
+            <div class="section-title">三、注意力和计算力(5分)</div>
+            <div class="form-item">
+              <span class="item-number">4.</span>
+              <span class="item-label">100-7=?连续减5次(93、86、79、72、65。各1分,共5分。若错了,但下一个答案正确,只记一次错误):</span>
+              <el-radio-group v-model="form.attention.score" size="small">
+                <el-radio :value="5">5分</el-radio>
+                <el-radio :value="4">4分</el-radio>
+                <el-radio :value="3">3分</el-radio>
+                <el-radio :value="2">2分</el-radio>
+                <el-radio :value="1">1分</el-radio>
+                <el-radio :value="0">0分</el-radio>
+              </el-radio-group>
+            </div>
+          </div>
+
+          <!-- 四、回忆能力 (3分) -->
+          <div class="section">
+            <div class="section-title">四、回忆能力(3分)</div>
+            <div class="form-item">
+              <span class="item-number">5.</span>
+              <span class="item-label">现在请你说出我刚才告诉你让你记住的那些东西?</span>
+              <el-radio-group v-model="form.recall.score" size="small">
+                <el-radio :value="3">3分</el-radio>
+                <el-radio :value="2">2分</el-radio>
+                <el-radio :value="1">1分</el-radio>
+                <el-radio :value="0">0分</el-radio>
+              </el-radio-group>
+            </div>
+          </div>
+
+          <!-- 五、命名能力 (2分) -->
+          <div class="section">
+            <div class="section-title">五、命名能力(2分)</div>
+            <div class="form-item">
+              <span class="item-number">6.</span>
+              <span class="item-label">命名能力:</span>
+              <div class="score-group">
+                <div class="score-row">
+                  <span>出示手表,问这个是什么东西?</span>
+                  <el-radio-group v-model="form.naming.watch" size="small">
+                    <el-radio :value="1">正确(1分)</el-radio>
+                    <el-radio :value="0">错误(0分)</el-radio>
+                  </el-radio-group>
+                </div>
+                <div class="score-row">
+                  <span>出示钢笔,问这个是什么东西?</span>
+                  <el-radio-group v-model="form.naming.pen" size="small">
+                    <el-radio :value="1">正确(1分)</el-radio>
+                    <el-radio :value="0">错误(0分)</el-radio>
+                  </el-radio-group>
+                </div>
+              </div>
+            </div>
+          </div>
+
+          <!-- 六、复述能力 (1分) -->
+          <div class="section">
+            <div class="section-title">六、复述能力(1分)</div>
+            <div class="form-item">
+              <span class="item-number">7.</span>
+              <span class="item-label">我现在说一句话,请跟我清楚的重复一遍(四十四只石狮子)!</span>
+              <el-radio-group v-model="form.repetition.score" size="small">
+                <el-radio :value="1">正确(1分)</el-radio>
+                <el-radio :value="0">错误(0分)</el-radio>
+              </el-radio-group>
+            </div>
+          </div>
+
+          <!-- 七、阅读能力 (1分) -->
+          <div class="section">
+            <div class="section-title">七、阅读能力(1分)</div>
+            <div class="form-item">
+              <span class="item-number">8.</span>
+              <span class="item-label">(闭上你的眼睛)请你念念这句话,并按上面意思去做!</span>
+              <el-radio-group v-model="form.reading.score" size="small">
+                <el-radio :value="1">正确(1分)</el-radio>
+                <el-radio :value="0">错误(0分)</el-radio>
+              </el-radio-group>
+            </div>
+          </div>
+
+          <!-- 八、三步命令 (3分) -->
+          <div class="section">
+            <div class="section-title">八、三步命令(3分)</div>
+            <div class="form-item">
+              <span class="item-number">9.</span>
+              <span class="item-label">我给您一张纸请您按我说的去做,现在开始:"用右手拿着这张纸,用两只手将它对折起来,放在您的左腿上。"(每个动作1分,共3分):</span>
+              <el-radio-group v-model="form.threeStepCommand.score" size="small">
+                <el-radio :value="3">3分</el-radio>
+                <el-radio :value="2">2分</el-radio>
+                <el-radio :value="1">1分</el-radio>
+                <el-radio :value="0">0分</el-radio>
+              </el-radio-group>
+            </div>
+          </div>
+
+          <!-- 九、书写能力 (1分) -->
+          <div class="section">
+            <div class="section-title">九、书写能力(1分)</div>
+            <div class="form-item">
+              <span class="item-number">10.</span>
+              <span class="item-label">书写能力要求受试者自己写一句完整的句子:</span>
+              <el-radio-group v-model="form.writing.score" size="small">
+                <el-radio :value="1">正确(1分)</el-radio>
+                <el-radio :value="0">错误(0分)</el-radio>
+              </el-radio-group>
+            </div>
+          </div>
+
+          <!-- 十、结构能力 (1分) -->
+          <div class="section">
+            <div class="section-title">十、结构能力(1分)</div>
+            <div class="form-item">
+              <span class="item-number">11.</span>
+              <span class="item-label">(出示图案)请你照上面图案画下来!</span>
+              <div class="structure-content">
+                <div class="structure-image">
+                  <!-- 两个重叠的五边形图案 -->
+                  <svg viewBox="0 0 200 120" class="pentagon-svg">
+                    <!-- 左侧五边形 -->
+                    <polygon points="50,10 90,30 90,80 50,100 10,80 10,30" fill="none" stroke="#333" stroke-width="2"/>
+                    <!-- 右侧五边形 -->
+                    <polygon points="110,10 150,30 150,80 110,100 70,80 70,30" fill="none" stroke="#333" stroke-width="2"/>
+                  </svg>
+                </div>
+                <el-radio-group v-model="form.structure.score" size="small">
+                  <el-radio :value="1">正确(1分)</el-radio>
+                  <el-radio :value="0">错误(0分)</el-radio>
+                </el-radio-group>
+              </div>
+            </div>
+          </div>
+
+          <!-- 风险程度判断 -->
+          <div class="section risk-section">
+            <div class="section-title">风险程度判断</div>
+            <div class="risk-judgment">
+              <el-radio-group v-model="form.riskLevel" >
+                <el-radio value="none" style="margin-right: 10px">无风险:MMSE ≥27分</el-radio>
+                <el-radio value="low" style="margin-right: 10px">低风险:MMSE 26-21分</el-radio>
+                <el-radio value="medium" style="margin-right: 10px">中风险:MMSE 10-20分</el-radio>
+                <el-radio value="high" style="margin-right: 10px">高风险:MMSE ≤9分</el-radio>
+              </el-radio-group>
+            </div>
+          </div>
+
+          <!-- 预防措施 -->
+          <div class="section">
+            <div class="section-title">预防措施</div>
+            <div class="form-item">
+              <el-checkbox-group v-model="form.preventiveMeasures" class="preventive-measures">
+                <el-checkbox value="diet">饮食与生活习惯管理</el-checkbox>
+                <el-checkbox value="environment">环境优化与安全保障</el-checkbox>
+                <el-checkbox value="emotion">情绪与行为干预</el-checkbox>
+                <el-checkbox value="monitoring">健康监测</el-checkbox>
+                <el-checkbox value="personalized">个性化活动(计算能力训练、方向感知觉训练、记忆力训练等)</el-checkbox>
+                <el-checkbox value="other">其他</el-checkbox>
+              </el-checkbox-group>
+              <template v-if="form.preventiveMeasures.includes('other')">
+                <el-input v-model="form.preventiveMeasuresOther" class="other-input" placeholder="请输入其他预防措施" />
+              </template>
+            </div>
+          </div>
+        </div>
+    </div>
+
+    <div><div style="font-weight: bold">这是提交字段,后端可照此字段创建数据表</div>:{
+      "contractNumber": "NS20190047",
+      "elderName": "胡肖红",
+      "bedName": "养护楼-6层-605-04",
+      "checkInTime": 1555459200000,
+      "elderId": 17582,
+      "tenantId": 211,
+      "assessmentData": "{\"assessor\":\"11\",\"assessDate\":\"2026-03-11\",\"orientation\":{\"year\":0,\"season\":0,\"month\":0,\"day\":0,\"weekDay\":0,\"province\":0,\"county\":0,\"town\":0,\"nursingHome\":1,\"floor\":0},\"memory\":{\"score\":0},\"attention\":{\"score\":0},\"recall\":{\"score\":0},\"naming\":{\"watch\":0,\"pen\":0},\"repetition\":{\"score\":0},\"reading\":{\"score\":0},\"threeStepCommand\":{\"score\":0},\"writing\":{\"score\":0},\"structure\":{\"score\":0},\"totalScore\":1,\"riskLevel\":\"high\",\"preventiveMeasures\":[\"emotion\"],\"preventiveMeasuresOther\":\"\"}",
+      "totalScore": 1,
+      "assessor": "11",
+      "assessDate": "2026-03-11",
+      "orgType": 1
+      }</div>
+    <template #footer>
+      <el-button @click="handleClosed">关闭</el-button>
+      <el-button style="margin-left: 22px;margin-right: 30px" v-loading="formLoading" type="primary" v-show="!isDetail" @click="submitForm">确定</el-button>
+      <el-button  type="success" @click="handleExport">打印</el-button>
+    </template>
+
+  </el-drawer>
+</template>
+
+<script lang="ts" setup>
+import { computed, ref } from 'vue'
+
+import dayjs from 'dayjs'
+
+import { mmseCreate, mmseGetById, mmseUpdate, mmseGetByElderId } from "@/api/social-work";
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+const title = ref('')
+const dialogVisible = ref(false) // 弹窗
+const formRef = ref() // 表单 Ref
+const selectElderRef = ref() // 表单 Ref
+const isDetail = ref(false) // 是否详情打开
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+let dataForm = ref({
+  // 表单字段
+  id: undefined,
+  idCard: '',
+  contractNumber: '', //档案号
+  elderName: '',//长者姓名
+  bedName: '', //床位号
+  elderAge: '', //年龄
+  elderSex: '', //性别
+  checkInTime: '', //入院日期
+  elderId: '',
+  tenantId: undefined
+})
+
+
+
+
+const elderUp = (e) => {
+  dataForm.value.elderName = e.elderName
+  dataForm.value.elderId = e.id
+  dataForm.value.elderSex = e.elderSex === 1 ? '男' : '女'
+  dataForm.value.bedName = e.bedName || ''
+  dataForm.value.checkInTime = e.checkInTime
+  dataForm.value.contractNumber = e.contractNumber
+  dataForm.value.elderAge = e.elderAge
+}
+
+// ========== MMSE 表单序列化方法 ==========
+
+/** 计算总分 */
+const totalScore = computed(() => {
+  const orientationScore = 
+    (form.orientation.year || 0) +
+    (form.orientation.season || 0) +
+    (form.orientation.month || 0) +
+    (form.orientation.day || 0) +
+    (form.orientation.weekDay || 0) +
+    (form.orientation.province || 0) +
+    (form.orientation.county || 0) +
+    (form.orientation.town || 0) +
+    (form.orientation.nursingHome || 0) +
+    (form.orientation.floor || 0)
+  
+  const namingScore = (form.naming.watch || 0) + (form.naming.pen || 0)
+  
+  return orientationScore +
+    (form.memory.score || 0) +
+    (form.attention.score || 0) +
+    (form.recall.score || 0) +
+    namingScore +
+    (form.repetition.score || 0) +
+    (form.reading.score || 0) +
+    (form.threeStepCommand.score || 0) +
+    (form.writing.score || 0) +
+    (form.structure.score || 0)
+})
+
+/** 风险程度文本 */
+const riskLevelText = computed(() => {
+  const score = totalScore.value
+  if (score >= 27) return '无风险'
+  if (score >= 21) return '低风险'
+  if (score >= 10) return '中风险'
+  return '高风险'
+})
+
+/** 风险程度样式类 */
+const riskLevelClass = computed(() => {
+  const score = totalScore.value
+  if (score >= 27) return 'risk-none'
+  if (score >= 21) return 'risk-low'
+  if (score >= 10) return 'risk-medium'
+  return 'risk-high'
+})
+
+/** 将表单数据序列化为 JSON 对象 */
+const serializeFormData = () => {
+  return {
+    // 基本信息
+    assessor: form.assessor || '',
+    assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : '',
+    
+    // 各项评分
+    orientation: { ...form.orientation },
+    memory: { ...form.memory },
+    attention: { ...form.attention },
+    recall: { ...form.recall },
+    naming: { ...form.naming },
+    repetition: { ...form.repetition },
+    reading: { ...form.reading },
+    threeStepCommand: { ...form.threeStepCommand },
+    writing: { ...form.writing },
+    structure: { ...form.structure },
+    
+    // 总分
+    totalScore: totalScore.value,
+    
+    // 风险程度
+    riskLevel: form.riskLevel || '',
+    
+    // 预防措施
+    preventiveMeasures: form.preventiveMeasures || [],
+    preventiveMeasuresOther: form.preventiveMeasuresOther || ''
+  }
+}
+
+/** 将 JSON 对象反序列化为表单数据 */
+const deserializeFormData = (formData: Record<string, any>) => {
+  if (!formData) return
+
+  // 基本信息
+  form.assessor = formData.assessor || ''
+  form.assessDate = formData.assessDate ? dayjs(formData.assessDate).toDate() : ''
+
+  // 各项评分
+  form.orientation = {
+    year: formData.orientation?.year ?? 0,
+    season: formData.orientation?.season ?? 0,
+    month: formData.orientation?.month ?? 0,
+    day: formData.orientation?.day ?? 0,
+    weekDay: formData.orientation?.weekDay ?? 0,
+    province: formData.orientation?.province ?? 0,
+    county: formData.orientation?.county ?? 0,
+    town: formData.orientation?.town ?? 0,
+    nursingHome: formData.orientation?.nursingHome ?? 0,
+    floor: formData.orientation?.floor ?? 0
+  }
+  form.memory = { score: formData.memory?.score ?? 0 }
+  form.attention = { score: formData.attention?.score ?? 0 }
+  form.recall = { score: formData.recall?.score ?? 0 }
+  form.naming = {
+    watch: formData.naming?.watch ?? 0,
+    pen: formData.naming?.pen ?? 0
+  }
+  form.repetition = { score: formData.repetition?.score ?? 0 }
+  form.reading = { score: formData.reading?.score ?? 0 }
+  form.threeStepCommand = { score: formData.threeStepCommand?.score ?? 0 }
+  form.writing = { score: formData.writing?.score ?? 0 }
+  form.structure = { score: formData.structure?.score ?? 0 }
+
+  // 风险程度
+  form.riskLevel = formData.riskLevel || ''
+
+  // 预防措施
+  form.preventiveMeasures = formData.preventiveMeasures || []
+  form.preventiveMeasuresOther = formData.preventiveMeasuresOther || ''
+}
+
+/** 重置 MMSE 表单数据 */
+const resetMMSEForm = () => {
+  form.assessor = ''
+  form.assessDate = ''
+
+  // 定向力
+  form.orientation = {
+    year: 0,
+    season: 0,
+    month: 0,
+    day: 0,
+    weekDay: 0,
+    province: 0,
+    county: 0,
+    town: 0,
+    nursingHome: 0,
+    floor: 0
+  }
+
+  // 其他评分
+  form.memory = { score: 0 }
+  form.attention = { score: 0 }
+  form.recall = { score: 0 }
+  form.naming = { watch: 0, pen: 0 }
+  form.repetition = { score: 0 }
+  form.reading = { score: 0 }
+  form.threeStepCommand = { score: 0 }
+  form.writing = { score: 0 }
+  form.structure = { score: 0 }
+
+  // 风险程度
+  form.riskLevel = ''
+
+  // 预防措施
+  form.preventiveMeasures = []
+  form.preventiveMeasuresOther = ''
+}
+
+/** 打开弹窗 */
+const open = async (tenantId, id?: any, detail: boolean = false) => {
+  resetForm()
+  dialogVisible.value = true
+  dataForm.value.id = id || undefined
+  dataForm.value.tenantId = tenantId
+  isDetail.value = detail
+  if (id) {
+    title.value = "编辑-MMSE评估"
+    // 加载 MMSE 数据
+    await loadMMSEData(id)
+  } else {
+    title.value = "新增-MMSE评估"
+    // 如果选择了长者,尝试加载已有的 MMSE 数据
+    if (dataForm.value.elderId) {
+      await loadMMSEByElderId(dataForm.value.elderId)
+    }
+  }
+}
+
+
+const form = reactive({
+  // 基本信息
+  assessor: '',
+  assessDate: '',
+
+  // 定向力 (10分)
+  orientation: {
+    year: 0,
+    season: 0,
+    month: 0,
+    day: 0,
+    weekDay: 0,
+    province: 0,
+    county: 0,
+    town: 0,
+    nursingHome: 0,
+    floor: 0
+  },
+
+  // 记忆力 (3分)
+  memory: { score: 0 },
+
+  // 注意力和计算力 (5分)
+  attention: { score: 0 },
+
+  // 回忆能力 (3分)
+  recall: { score: 0 },
+
+  // 命名能力 (2分)
+  naming: { watch: 0, pen: 0 },
+
+  // 复述能力 (1分)
+  repetition: { score: 0 },
+
+  // 阅读能力 (1分)
+  reading: { score: 0 },
+
+  // 三步命令 (3分)
+  threeStepCommand: { score: 0 },
+
+  // 书写能力 (1分)
+  writing: { score: 0 },
+
+  // 结构能力 (1分)
+  structure: { score: 0 },
+
+  // 风险程度
+  riskLevel: '',
+
+  // 预防措施
+  preventiveMeasures: [],
+  preventiveMeasuresOther: ''
+})
+
+// MMSE 不需要下拉选项,使用 radio 和 checkbox 直接评分
+
+
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  if (formLoading.value) {
+    return
+  }
+  formLoading.value = true
+  // 提交请求
+  try {
+    const assessmentData = serializeFormData()
+    const tempParams = {
+      ...dataForm.value,
+      assessmentData: JSON.stringify(assessmentData),
+      totalScore: totalScore.value,
+      assessor: form.assessor,
+      assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''
+    }
+
+    if (dataForm.value.id) {
+      const res = await mmseUpdate(tempParams)
+      if (res) {
+        message.success(t('common.updateSuccess'))
+        dialogVisible.value = false
+        // 发送操作成功的事件
+        emit('success')
+      }
+    } else {
+      const res = await mmseCreate(tempParams)
+      if (res) {
+        message.success(t('common.createSuccess'))
+        dialogVisible.value = false
+        // 发送操作成功的事件
+        emit('success')
+      }
+    }
+  } finally {
+    setTimeout(() => {
+      formLoading.value = false
+    }, 500)
+  }
+}
+
+
+
+/** 重置表单 */
+const resetForm = () => {
+  dataForm.value = {
+    id: undefined,
+    idCard: '',
+    contractNumber: '', //档案号
+    elderName: '',//长者姓名
+    bedName: '', //床位号
+    elderAge: '', //年龄
+    elderSex: '', //性别
+    checkInTime: '', //入院日期
+    elderId: '',
+    tenantId: undefined
+  }
+  formRef.value?.resetFields()
+
+  // 重置 MMSE 表单
+  resetMMSEForm()
+}
+
+// 关闭表单
+const handleClosed = () => {
+  dialogVisible.value = false
+  resetForm()
+}
+
+/** 导出PDF */
+const handleExport = () => {
+  // 创建打印窗口
+  const printWindow = window.open('', '_blank')
+  if (!printWindow) {
+    message.error('请允许弹出窗口')
+    return
+  }
+
+  // 辅助函数:获取评分状态
+  const getScoreMark = (score) => score === 1 ? '☑ 正确 (1分)' : '☐ 错误 (0分)'
+  const getMemoryMark = (score) => {
+    const marks = ['☐ 0分', '☐ 1分', '☐ 2分', '☐ 3分']
+    if (score >= 0 && score <= 3) marks[score] = marks[score].replace('☐', '☑')
+    return marks.join('  ')
+  }
+  const getAttentionMark = (score) => {
+    const marks = ['☐ 0分', '☐ 1分', '☐ 2分', '☐ 3分', '☐ 4分', '☐ 5分']
+    if (score >= 0 && score <= 5) marks[score] = marks[score].replace('☐', '☑')
+    return marks.join('  ')
+  }
+  const getRecallMark = (score) => {
+    const marks = ['☐ 0分', '☐ 1分', '☐ 2分', '☐ 3分']
+    if (score >= 0 && score <= 3) marks[score] = marks[score].replace('☐', '☑')
+    return marks.join('  ')
+  }
+  const getThreeStepMark = (score) => {
+    const marks = ['☐ 0分', '☐ 1分', '☐ 2分', '☐ 3分']
+    if (score >= 0 && score <= 3) marks[score] = marks[score].replace('☐', '☑')
+    return marks.join('  ')
+  }
+  const getNamingMark = (score) => score === 1 ? '☑ 正确 (1分)' : '☐ 错误 (0分)'
+
+  // 构建打印内容
+  const printContent = `
+    <!DOCTYPE html>
+    <html>
+    <head>
+      <meta charset="UTF-8">
+      <title>MMSE评估表 - ${dataForm.value.elderName || ''}</title>
+      <style>
+        @media print {
+          @page { size: A4 portrait; margin: 15mm; }
+        }
+        body { 
+          font-family: 'SimSun', 'Microsoft YaHei', serif; 
+          font-size: 11pt; 
+          line-height: 1.5; 
+          color: #333;
+        }
+        .header { 
+          text-align: center; 
+          margin-bottom: 20px; 
+          border-bottom: 2px solid #333;
+          padding-bottom: 10px;
+        }
+        .header h1 { 
+          font-size: 18pt; 
+          margin: 0; 
+          letter-spacing: 2px;
+        }
+        .header .sub-title {
+          font-size: 12pt;
+          color: #666;
+          margin-top: 5px;
+        }
+        .info-section {
+          margin-bottom: 15px;
+          padding: 10px;
+          border: 1px solid #999;
+          background: #fafafa;
+        }
+        .info-row {
+          display: flex;
+          flex-wrap: wrap;
+          gap: 20px;
+        }
+        .info-item {
+          display: flex;
+          align-items: center;
+        }
+        .info-item .label {
+          font-weight: bold;
+          margin-right: 8px;
+          color: #555;
+        }
+        .info-item .value {
+          border-bottom: 1px solid #333;
+          min-width: 80px;
+          padding: 0 5px;
+          text-align: center;
+        }
+        .score-summary {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          padding: 10px 15px;
+          background: #f0f0f0;
+          border: 2px solid #333;
+          margin-bottom: 15px;
+        }
+        .total-score { 
+          font-size: 14pt; 
+          font-weight: bold;
+        }
+        .total-score .score-value {
+          color: #d9534f;
+          font-size: 18pt;
+        }
+        .risk-level { 
+          font-size: 12pt; 
+          font-weight: bold; 
+          padding: 5px 15px;
+        }
+        .risk-none { color: #5cb85c; }
+        .risk-low { color: #f0ad4e; }
+        .risk-medium { color: #d9534f; }
+        .risk-high { color: #d9534f; background: #ffe6e6; padding: 5px 10px; border-radius: 3px; }
+        
+        .section { 
+          margin-bottom: 12px; 
+          border: 1px solid #999;
+        }
+        .section-header { 
+          font-weight: bold; 
+          background: #e8e8e8; 
+          padding: 8px 12px;
+          border-bottom: 1px solid #999;
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+        }
+        .section-title {
+          font-size: 12pt;
+        }
+        .section-score {
+          font-size: 11pt;
+          color: #666;
+        }
+        .question {
+          padding: 8px 12px;
+          border-bottom: 1px dashed #ccc;
+          display: flex;
+          justify-content: space-between;
+          align-items: flex-start;
+        }
+        .question:last-child {
+          border-bottom: none;
+        }
+        .question-text {
+          flex: 1;
+          padding-right: 15px;
+        }
+        .question-number {
+          font-weight: bold;
+          margin-right: 8px;
+          color: #555;
+        }
+        .question-desc {
+          font-size: 10pt;
+          color: #666;
+          margin-top: 3px;
+        }
+        .answer-options {
+          white-space: nowrap;
+          font-size: 10pt;
+          color: #555;
+        }
+        .structure-image {
+          text-align: center;
+          padding: 10px;
+          background: #fafafa;
+          margin: 10px 0;
+        }
+        .structure-image svg {
+          width: 200px;
+          height: 120px;
+        }
+        
+        .measures-section {
+          margin-top: 15px;
+          border: 1px solid #999;
+        }
+        .measures-title {
+          font-weight: bold;
+          background: #e8e8e8;
+          padding: 8px 12px;
+          border-bottom: 1px solid #999;
+        }
+        .measures-content {
+          padding: 10px 12px;
+        }
+        .measure-item {
+          margin-bottom: 5px;
+          font-size: 10pt;
+        }
+        .measure-other {
+          margin-left: 20px;
+          margin-top: 5px;
+          border-bottom: 1px solid #333;
+          min-width: 200px;
+          display: inline-block;
+        }
+        
+        .signature-section {
+          margin-top: 30px;
+          display: flex;
+          justify-content: space-between;
+        }
+        .signature-item {
+          width: 45%;
+        }
+        .signature-label {
+          margin-bottom: 5px;
+        }
+        .signature-line {
+          border-bottom: 1px solid #333;
+          height: 30px;
+        }
+        .date-line {
+          border-bottom: 1px solid #333;
+          height: 30px;
+          width: 150px;
+        }
+        
+        .footer-note {
+          margin-top: 20px;
+          font-size: 9pt;
+          color: #666;
+          text-align: center;
+          border-top: 1px solid #ccc;
+          padding-top: 10px;
+        }
+      </style>
+    </head>
+    <body>
+      <div class="header">
+        <h1>简易精神状态评价量表(MMSE)</h1>
+        <div class="sub-title">Mini-Mental State Examination</div>
+      </div>
+      
+      <div class="info-section">
+        <div class="info-row">
+          <div class="info-item">
+            <span class="label">长者姓名:</span>
+            <span class="value">${dataForm.value.elderName || ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">档案号:</span>
+            <span class="value">${dataForm.value.contractNumber || ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">床位号:</span>
+            <span class="value">${dataForm.value.bedName || ''}</span>
+          </div>
+        </div>
+        <div class="info-row" style="margin-top: 10px;">
+          <div class="info-item">
+            <span class="label">评估日期:</span>
+            <span class="value">${form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">评估人:</span>
+            <span class="value">${form.assessor || ''}</span>
+          </div>
+        </div>
+      </div>
+
+      <div class="score-summary">
+        <div class="total-score">
+          总分:<span class="score-value">${totalScore.value}</span> / 30分
+        </div>
+      </div>
+
+      <!-- 一、定向力 -->
+      <div class="section">
+        <div class="section-header">
+          <span class="section-title">一、定向力(10分)</span>
+          <span class="section-score">得分:${(form.orientation.year || 0) + (form.orientation.season || 0) + (form.orientation.month || 0) + (form.orientation.day || 0) + (form.orientation.weekDay || 0) + (form.orientation.province || 0) + (form.orientation.county || 0) + (form.orientation.town || 0) + (form.orientation.nursingHome || 0) + (form.orientation.floor || 0)} / 10分</span>
+        </div>
+        <div class="question">
+          <div class="question-text">
+            <span class="question-number">1.</span>
+            <div>
+              <div>时间定向(5分)</div>
+              <div class="question-desc">今年是哪一年?现在是什么季节?现在是几月份?今天是几号?今天是星期几?</div>
+            </div>
+          </div>
+          <div class="answer-options">
+            ${getScoreMark(form.orientation.year)}<br>
+            ${getScoreMark(form.orientation.season)}<br>
+            ${getScoreMark(form.orientation.month)}<br>
+            ${getScoreMark(form.orientation.day)}<br>
+            ${getScoreMark(form.orientation.weekDay)}
+          </div>
+        </div>
+        <div class="question">
+          <div class="question-text">
+            <span class="question-number">2.</span>
+            <div>
+              <div>地点定向(5分)</div>
+              <div class="question-desc">你住在那个省?你住在那个县(区)?你住在那个乡(街道)?咱们现在在哪个养老院?咱们现在在第几层楼?</div>
+            </div>
+          </div>
+          <div class="answer-options">
+            ${getScoreMark(form.orientation.province)}<br>
+            ${getScoreMark(form.orientation.county)}<br>
+            ${getScoreMark(form.orientation.town)}<br>
+            ${getScoreMark(form.orientation.nursingHome)}<br>
+            ${getScoreMark(form.orientation.floor)}
+          </div>
+        </div>
+      </div>
+
+      <!-- 二、记忆力 -->
+      <div class="section">
+        <div class="section-header">
+          <span class="section-title">二、记忆力(3分)</span>
+          <span class="section-score">得分:${form.memory.score || 0} / 3分</span>
+        </div>
+        <div class="question">
+          <div class="question-text">
+            <span class="question-number">3.</span>
+            <div>
+              <div>告诉你三种东西,我说完后,请你重复一遍并记住,待会还会问你(各1分,共3分)</div>
+              <div class="question-desc">例如:皮球、国旗、树木</div>
+            </div>
+          </div>
+          <div class="answer-options">
+            ${getMemoryMark(form.memory.score || 0)}
+          </div>
+        </div>
+      </div>
+
+      <!-- 三、注意力和计算力 -->
+      <div class="section">
+        <div class="section-header">
+          <span class="section-title">三、注意力和计算力(5分)</span>
+          <span class="section-score">得分:${form.attention.score || 0} / 5分</span>
+        </div>
+        <div class="question">
+          <div class="question-text">
+            <span class="question-number">4.</span>
+            <div>
+              <div>100-7=?连续减5次(93、86、79、72、65。各1分,共5分)</div>
+              <div class="question-desc">若错了,但下一个答案正确,只记一次错误</div>
+            </div>
+          </div>
+          <div class="answer-options">
+            ${getAttentionMark(form.attention.score || 0)}
+          </div>
+        </div>
+      </div>
+
+      <!-- 四、回忆能力 -->
+      <div class="section">
+        <div class="section-header">
+          <span class="section-title">四、回忆能力(3分)</span>
+          <span class="section-score">得分:${form.recall.score || 0} / 3分</span>
+        </div>
+        <div class="question">
+          <div class="question-text">
+            <span class="question-number">5.</span>
+            <div>现在请你说出我刚才告诉你让你记住的那些东西?</div>
+          </div>
+          <div class="answer-options">
+            ${getRecallMark(form.recall.score || 0)}
+          </div>
+        </div>
+      </div>
+
+      <!-- 五、命名能力 -->
+      <div class="section">
+        <div class="section-header">
+          <span class="section-title">五、命名能力(2分)</span>
+          <span class="section-score">得分:${(form.naming.watch || 0) + (form.naming.pen || 0)} / 2分</span>
+        </div>
+        <div class="question">
+          <div class="question-text">
+            <span class="question-number">6.</span>
+            <div>出示手表,问这个是什么东西?</div>
+          </div>
+          <div class="answer-options">
+            ${getNamingMark(form.naming.watch || 0)}
+          </div>
+        </div>
+        <div class="question">
+          <div class="question-text">
+            <span class="question-number"></span>
+            <div>出示钢笔,问这个是什么东西?</div>
+          </div>
+          <div class="answer-options">
+            ${getNamingMark(form.naming.pen || 0)}
+          </div>
+        </div>
+      </div>
+
+      <!-- 六、复述能力 -->
+      <div class="section">
+        <div class="section-header">
+          <span class="section-title">六、复述能力(1分)</span>
+          <span class="section-score">得分:${form.repetition.score || 0} / 1分</span>
+        </div>
+        <div class="question">
+          <div class="question-text">
+            <span class="question-number">7.</span>
+            <div>我现在说一句话,请跟我清楚的重复一遍(四十四只石狮子)!</div>
+          </div>
+          <div class="answer-options">
+            ${getScoreMark(form.repetition.score || 0)}
+          </div>
+        </div>
+      </div>
+
+      <!-- 七、阅读能力 -->
+      <div class="section">
+        <div class="section-header">
+          <span class="section-title">七、阅读能力(1分)</span>
+          <span class="section-score">得分:${form.reading.score || 0} / 1分</span>
+        </div>
+        <div class="question">
+          <div class="question-text">
+            <span class="question-number">8.</span>
+            <div>(闭上你的眼睛)请你念念这句话,并按上面意思去做!</div>
+          </div>
+          <div class="answer-options">
+            ${getScoreMark(form.reading.score || 0)}
+          </div>
+        </div>
+      </div>
+
+      <!-- 八、三步命令 -->
+      <div class="section">
+        <div class="section-header">
+          <span class="section-title">八、三步命令(3分)</span>
+          <span class="section-score">得分:${form.threeStepCommand.score || 0} / 3分</span>
+        </div>
+        <div class="question">
+          <div class="question-text">
+            <span class="question-number">9.</span>
+            <div>
+              <div>我给您一张纸请您按我说的去做,现在开始:</div>
+              <div class="question-desc">"用右手拿着这张纸,用两只手将它对折起来,放在您的左腿上。"(每个动作1分,共3分)</div>
+            </div>
+          </div>
+          <div class="answer-options">
+            ${getThreeStepMark(form.threeStepCommand.score || 0)}
+          </div>
+        </div>
+      </div>
+
+      <!-- 九、书写能力 -->
+      <div class="section">
+        <div class="section-header">
+          <span class="section-title">九、书写能力(1分)</span>
+          <span class="section-score">得分:${form.writing.score || 0} / 1分</span>
+        </div>
+        <div class="question">
+          <div class="question-text">
+            <span class="question-number">10.</span>
+            <div>书写能力要求受试者自己写一句完整的句子</div>
+          </div>
+          <div class="answer-options">
+            ${getScoreMark(form.writing.score || 0)}
+          </div>
+        </div>
+      </div>
+
+      <!-- 十、结构能力 -->
+      <div class="section">
+        <div class="section-header">
+          <span class="section-title">十、结构能力(1分)</span>
+          <span class="section-score">得分:${form.structure.score || 0} / 1分</span>
+        </div>
+        <div class="question">
+          <div class="question-text">
+            <span class="question-number">11.</span>
+            <div>(出示图案)请你照上面图案画下来!</div>
+          </div>
+          <div class="answer-options">
+            ${getScoreMark(form.structure.score || 0)}
+          </div>
+        </div>
+        <div class="structure-image">
+          <svg viewBox="0 0 200 120">
+            <polygon points="50,10 90,30 90,80 50,100 10,80 10,30" fill="none" stroke="#333" stroke-width="2"/>
+            <polygon points="110,10 150,30 150,80 110,100 70,80 70,30" fill="none" stroke="#333" stroke-width="2"/>
+          </svg>
+        </div>
+      </div>
+
+      <!-- 风险程度判断 -->
+      <div class="section">
+        <div class="section-header">
+          <span class="section-title">风险程度判断</span>
+        </div>
+        <div class="question">
+          <div class="question-text">
+            <div style="display: flex; gap: 30px; flex-wrap: wrap;">
+              <span>${form.riskLevel === 'none' ? '☑' : '☐'} 无风险:MMSE ≥27分</span>
+              <span>${form.riskLevel === 'low' ? '☑' : '☐'} 低风险:MMSE 26-21分</span>
+              <span>${form.riskLevel === 'medium' ? '☑' : '☐'} 中风险:MMSE 10-20分</span>
+              <span>${form.riskLevel === 'high' ? '☑' : '☐'} 高风险:MMSE ≤9分</span>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 预防措施 -->
+      <div class="measures-section">
+        <div class="measures-title">预防措施</div>
+        <div class="measures-content">
+          <div class="measure-item">${form.preventiveMeasures?.includes('diet') ? '☑' : '☐'} 饮食与生活习惯管理</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('environment') ? '☑' : '☐'} 环境优化与安全保障</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('emotion') ? '☑' : '☐'} 情绪与行为干预</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('monitoring') ? '☑' : '☐'} 健康监测</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('personalized') ? '☑' : '☐'} 个性化活动(计算能力训练、方向感知觉训练、记忆力训练等)</div>
+          <div class="measure-item">
+            ${form.preventiveMeasures?.includes('other') ? '☑' : '☐'} 其他
+            ${form.preventiveMeasures?.includes('other') ? '<span class="measure-other">' + (form.preventiveMeasuresOther || '') + '</span>' : ''}
+          </div>
+        </div>
+      </div>
+
+      <div class="signature-section">
+        <div class="signature-item">
+          <div class="signature-label">家属/评估员签名:</div>
+          <div class="signature-line"></div>
+        </div>
+        <div class="signature-item">
+          <div class="signature-label">日期:</div>
+          <div class="date-line"></div>
+        </div>
+      </div>
+
+      <div class="footer-note">
+        注:MMSE总分30分,≥27分为认知功能正常,26-21分为轻度认知障碍,10-20分为中度认知障碍,≤9分为重度认知障碍
+      </div>
+    </body>
+    </html>
+  `
+
+  // 写入内容并打印
+  printWindow.document.write(printContent)
+  printWindow.document.close()
+  
+  // 延迟打印,确保样式加载完成
+  setTimeout(() => {
+    printWindow.print()
+  }, 500)
+}
+
+</script>
+
+<style scoped lang="scss">
+.mmse-form {
+  max-width: 1200px;
+  margin: 0 auto;
+  background: #fff;
+
+  .form-title {
+    text-align: center;
+    font-size: 24px;
+    font-weight: bold;
+    margin-bottom: 20px;
+  }
+
+
+
+    .info-row {
+      display: flex;
+      gap: 40px;
+      width: 100%;
+      flex-direction: row;
+      align-items: center;
+      margin-bottom: 10px;
+
+      .info-item {
+        display: flex;
+        align-items: center;
+        gap: 8px;
+
+        .label {
+          width: 82px;
+          text-align: right;
+          margin-right: 4px;
+          white-space: nowrap;
+        }
+      }
+    }
+
+
+  .form-body {
+    border: 1px solid #333;
+    padding: 15px;
+  }
+
+  .section {
+    margin-bottom: 20px;
+
+    &:last-child {
+      margin-bottom: 0;
+    }
+
+    .section-title {
+      font-weight: bold;
+      margin-bottom: 10px;
+    }
+  }
+
+  .form-item {
+    display: flex;
+    align-items: center;
+    margin-bottom: 12px;
+    flex-wrap: wrap;
+    gap: 8px;
+
+    .item-number {
+      font-weight: bold;
+      min-width: 25px;
+    }
+
+    .item-label {
+      white-space: nowrap;
+      min-width: fit-content;
+    }
+
+  }
+
+  .other-input {
+    width: 200px;
+    margin-left: 10px;
+  }
+
+  // 调整 Element Plus 组件样式
+  :deep(.el-input__inner) {
+    height: 28px;
+    line-height: 28px;
+    border-top: none;
+    border-left: none;
+    border-right: none;
+    border-radius: 0;
+    padding: 0 4px;
+
+    &:focus {
+      border-color: #409eff;
+    }
+  }
+
+
+  :deep(.el-checkbox__label),
+  :deep(.el-radio__label) {
+    padding-left: 4px;
+  }
+}
+.row{
+  margin-bottom: 12px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  text{
+    text-align: right;
+    margin-right: 4px;
+    width: 82px;
+  }
+}
+
+// MMSE 特有样式
+.total-score-section {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  margin-bottom: 20px;
+
+  .total-score {
+    display: flex;
+    align-items: baseline;
+    gap: 4px;
+
+    .score-label {
+      font-size: 16px;
+      font-weight: bold;
+    }
+
+    .score-value {
+      font-size: 28px;
+      font-weight: bold;
+      color: #409eff;
+    }
+
+    .score-max {
+      font-size: 14px;
+      color: #909399;
+    }
+  }
+
+  .risk-level {
+    font-size: 16px;
+    font-weight: bold;
+    padding: 8px 16px;
+    border-radius: 4px;
+
+    &.risk-none {
+      color: #67c23a;
+      background: #f0f9eb;
+    }
+
+    &.risk-low {
+      color: #e6a23c;
+      background: #fdf6ec;
+    }
+
+    &.risk-medium {
+      color: #f56c6c;
+      background: #fef0f0;
+    }
+
+    &.risk-high {
+      color: #f56c6c;
+      background: #fef0f0;
+      border: 1px solid #f56c6c;
+    }
+  }
+}
+
+.score-group {
+  display: flex;
+  flex-direction: column;
+  gap: 10px;
+  margin-left: 35px;
+  margin-top: 8px;
+  width: 100%;
+
+  .score-row {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 8px 12px;
+    background: #fafafa;
+    border-radius: 4px;
+
+    span {
+      flex: 1;
+    }
+  }
+}
+
+.structure-content {
+  display: flex;
+  align-items: center;
+  gap: 20px;
+  margin-left: 35px;
+  margin-top: 8px;
+
+  .structure-image {
+    .pentagon-svg {
+      width: 200px;
+      height: 120px;
+      border: 1px solid #dcdfe6;
+      border-radius: 4px;
+      padding: 10px;
+    }
+  }
+}
+
+.risk-section {
+  background: #f5f7fa;
+  padding: 15px;
+  border-radius: 4px;
+
+  .risk-judgment {
+    margin-left: 35px;
+    margin-top: 10px;
+
+    :deep(.el-radio) {
+      display: block;
+      margin-bottom: 8px;
+      margin-right: 0;
+    }
+  }
+}
+
+.preventive-measures {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+  margin-left: 35px;
+  margin-top: 8px;
+
+  :deep(.el-checkbox) {
+    margin-right: 0;
+    height: auto;
+    align-items: flex-start;
+
+    .el-checkbox__label {
+      white-space: normal;
+      line-height: 1.5;
+    }
+  }
+}
+</style>

+ 335 - 0
src/views/social-worker/assessment/MMSE/index.vue

@@ -0,0 +1,335 @@
+<template>
+  <ContentWrap>
+    <!-- 保护性约束观察记录表 -->
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="110px"
+    >
+      <el-form-item label="长者姓名">
+        <el-input
+          v-model="queryParams.elderName"
+          placeholder="长者姓名"
+          class="!w-240px"
+          clearable
+        />
+      </el-form-item>
+
+      <el-form-item label="评估人">
+        <el-input
+          v-model="queryParams.elderName"
+          placeholder="输入评估人"
+          class="!w-240px"
+          clearable
+        />
+      </el-form-item>
+
+
+      <el-form-item label="评估日期">
+        <el-date-picker
+          size="default"
+          ref="selectRef"
+          class="!w-240px"
+          v-model="queryParams.recordDate"
+          type="daterange"
+          :clearable="true"
+          :editable="false"
+          placeholder="选择评估日期"
+          value-format="YYYY-MM-DD"
+          format="YYYY-MM-DD"
+          date-format="YYYY-MM-DD"
+        />
+      </el-form-item>
+
+      <el-form-item>
+        <el-button @click="handleQuery" style="margin-left: 2vw"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <div class="mb-10px">
+
+      <ButtonAdd @click="openForm(undefined)"  />
+      <!--      <el-button @click="inputH" type="success"><Icon icon="fa:cloud-upload" :size="16" class="mr-1"/>导入</el-button>-->
+      <ButtonImport @click="handleImportCard"  />
+
+
+    </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">
+          {{
+            scope.$index + (queryParams.pageNo * queryParams.pageSize - queryParams.pageSize) + 1
+          }}
+        </template>
+      </el-table-column>
+
+
+      <el-table-column prop="elderName" header-align="center" align="center" label="长者姓名" min-width="150" show-overflow-tooltip/>
+      <el-table-column prop="bedName" header-align="center" align="center" label="床位号" min-width="200" show-overflow-tooltip/>
+      <el-table-column prop="recordDate" header-align="center" align="center" label="记录日期" min-width="200" show-overflow-tooltip/>
+
+      <el-table-column prop="creator" header-align="center" align="center" label="记录人" min-width="200" show-overflow-tooltip/>
+
+
+      <el-table-column label="操作" align="center" width="200" >
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            @click="openFormEdit(scope.row, scope.row.id)"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="warning"
+            @click="openFormDetail(scope.row,scope.row.id)"
+          >
+            详情
+          </el-button>
+          <el-button
+            link
+            type="danger"
+            @click="openClose(scope.row)"
+          >
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+  <AddForm ref="formRef" @success="getList" />
+
+  <!-- 通用批量导出弹窗 -->
+  <BatchExportDialog
+    :show="showBatchExport"
+    :title="exportConfig.title"
+    :loading="exportLoading"
+    :batch-min="exportConfig.batchMin"
+    :batch-max="exportConfig.batchMax"
+    :count-min="exportConfig.countMin"
+    :count-max="exportConfig.countMax"
+    :default-batch="exportConfig.defaultBatch"
+    :default-count="exportConfig.defaultCount"
+    :description="exportConfig.description"
+    @update:show="showBatchExport = $event"
+    @confirm="handleBatchExport"
+    @cancel="showBatchExport = false"
+  />
+
+
+  <Import
+    ref="importRef"
+    @success="getList"
+    :config="{
+      title: '导入',
+      downloadUrl: 'elderly-service-order/get-import-template',
+      excelTempName: '居家工单-【导入】模板',
+      importUrl: '/elderly-service-order/import',
+      failExportUrl: '',
+    }"
+  />
+
+</template>
+
+<script setup lang="ts">
+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 {formatTimestamp, getCurrentMonthRange} from "@/utils/dateUtil";
+import Import from "@/components/ImportFile/index.vue";
+import {restraintCreatePage, restraintDelete} from "@/api/elderly/nursing/keep-fit";
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+const userStore = useUserStore()
+const loading = ref(true) // 列表的加载中
+const detailRef = ref()
+const importRef = ref()
+const total = ref(0) // 列表的总页数
+const list = ref([]) // 列表的数据
+
+// 状态管理
+const showBatchExport = ref(false)
+const exportConfig = ref({
+  title: '',
+  batchMin: 1,
+  batchMax: 999,
+  countMin: 1,
+  countMax: 200,
+  defaultBatch: 1,
+  defaultCount: 200,
+  description: [] as string[]
+})
+const exportLoading = ref(false)
+
+let queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  elderName: '',
+  creator: '',
+  recordDate: getCurrentMonthRange(),
+  tenantIds: userStore.orgTenantId
+})
+const queryFormRef = ref() // 搜索的表单
+
+const inputH = () => {
+  importRef.value.open(queryParams.tenantIds[0])
+}
+// 打开导出弹窗
+const handleImportCard = async () => {
+
+  // showBatchExport.value = true
+}
+
+// 处理批量导出
+const handleBatchExport = async (batch: number, count: number) => {
+  exportLoading.value = true
+  console.log(batch,count)
+  // try {
+  //   let queryParams = {
+  //     pageNo: batch,
+  //     pageSize: count,
+  //     tenantId: userStore.orgTenantId[0]
+  //   }
+  //   const list = await careRecordsPage(queryParams)
+  //   if (list.length <= 0) {
+  //     message.error('暂无数据可以导出!')
+  //     return
+  //   }
+  //   const headers = [
+  //     { key: 'organizationName', title: '机构名称' },
+  //     { key: 'visitName', title: '姓名' },
+  //     { key: 'visitPhone', title: '手机号' },
+  //     { key: 'visitDate', title: '预约时间' },
+  //     { key: 'accompanyCount', title: '陪同人数' },
+  //     { key: 'reason', title: '理由' }
+  //   ]
+  //   exportWithExpandedObjectArrays(list, headers, `医疗护理记录${formatToDateTime()}.xlsx`, '医疗护理记录')
+  // } catch (_) {}
+
+}
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    //let queryP = {...queryParams,discoveryTime:queryParams.discoveryTime?[queryParams.discoveryTime[0]+" 00:00:00",queryParams.discoveryTime[1]+" 23:59:59"]:null}
+    const data = await restraintCreatePage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = async () => {
+  if (!queryFormRef.value) return
+  const valid = await queryFormRef.value.validate()
+  if (!valid) return
+  queryParams.pageNo = 1
+  await getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryParams.elderName = ''
+  queryParams.creator = ''
+  queryParams.tenantIds = userStore.orgTenantId
+  queryParams.recordDate= getCurrentMonthRange()
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+/** 添加/修改操作 */
+const formRef = ref()
+const openForm = (id?: number) => {
+  if(queryParams.tenantIds.length == 0 || queryParams.tenantIds.length > 1){
+    message.error('新增只能选择一个机构')
+    return
+  }
+  formRef.value.open(queryParams.tenantIds[0], id,false)
+}
+
+const editRef = ref()
+const openFormEdit = (row: any = {}, id?: number) => {
+  formRef.value.open(row.tenantId, id,false)
+}
+
+
+const openFormDetail = (row: any = {},id?: number) => {
+  formRef.value.open(row.tenantId,id,true)
+}
+
+
+
+
+
+const openClose = async (item) => {
+  try {
+    console.log("任务ID",item)
+    const res = await message.confirm('确定要删除吗?', '提示')
+    if (res == 'confirm') {
+      // 发起
+      try {
+        const res = await restraintDelete(item.id)
+        if (res){
+          message.success(t('common.updateSuccess'))
+        }
+      }catch(err) {}
+    }
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 取消按钮操作 */
+const cancelDelete = async (id: number) => {
+  try {
+    // 取消的二次确认
+    await message.cancelConfirm()
+    // 发起取消
+    // await elderlyBakDel(id)
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+const route = useRoute()
+/** 初始化 **/
+onMounted(() => {
+  if(route.query && route.query.elderName){
+    queryParams.elderName = route.query.elderName as string
+  }
+  getList()
+})
+
+// 表头格式
+const tableHeaderColor = ({ rowIndex }: any) => {
+  if (rowIndex === 0) {
+    return {
+      backgroundColor: '#f8f8f9',
+      color: '#666666',
+      fontWeight: 'bold'
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss"></style>

+ 1185 - 0
src/views/social-worker/assessment/NGASR/AddForm.vue

@@ -0,0 +1,1185 @@
+<template>
+  <el-drawer
+    v-model="dialogVisible"
+    :title="title"
+    resizable
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    :destroy-on-close="true"
+    size="70%"
+    :before-close="handleClosed"
+  >
+
+    <div class="ngasr-form">
+      <h1 class="form-title">自杀风险评估量表</h1>
+      <!-- 基本信息 -->
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>长者姓名</text>
+          <search-the-elderly ref="selectElderRef" :disabled="isDetail" @update_elder="elderUp" v-model="dataForm.elderName" :tId="dataForm.tenantId"/>
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>档案号</text>
+          <el-input v-if="!isDetail" v-model="dataForm.contractNumber" disabled />
+          <el-text v-else disabled="">{{dataForm.contractNumber}}</el-text>
+        </el-col>
+      </el-row>
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>入院日期</text>
+          <el-input v-if="!isDetail" :model-value="dayjs(dataForm.checkInTime).format('YYYY-MM-DD')=='Invalid Date'?'':dayjs(dataForm.checkInTime).format('YYYY-MM-DD')" disabled />
+          <el-text v-else disabled="">{{dayjs(dataForm.checkInTime).format('YYYY-MM-DD')}}</el-text>
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>床位号</text>
+          <el-input v-if="!isDetail" v-model="dataForm.bedName" disabled />
+          <el-text v-else disabled="">{{dataForm.bedName}}</el-text>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>评估人</text>
+          <el-input v-model="form.assessor"  />
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>评估日期</text>
+          <el-date-picker v-model="form.assessDate" type="date" style="width: 100%;"/>
+
+        </el-col>
+      </el-row>
+
+      <!-- 表单内容区域 -->
+      <div class="form-body">
+        <!-- 总分显示 -->
+        <div class="total-score-section">
+          <div class="total-score">
+            <span class="score-label">评估总得分:</span>
+            <span class="score-value">{{ totalScore }}</span>
+            <span class="score-max">分</span>
+          </div>
+        </div>
+
+        <!-- 评估表格 -->
+        <div class="assessment-table">
+          <table>
+            <thead>
+              <tr>
+                <th class="risk-factor-col">危险因素</th>
+                <th class="score-yes-col">是</th>
+                <th class="score-no-col">否</th>
+                <th class="select-col">选择</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr v-for="(item, index) in riskFactors" :key="index">
+                <td class="risk-factor">{{ item.name }}</td>
+                <td class="score-yes">{{ item.yesScore }}分</td>
+                <td class="score-no">0分</td>
+                <td class="select">
+                  <el-radio-group v-model="form.riskScores[index]" :disabled="isDetail">
+                    <el-radio :value="item.yesScore" style="margin-right: 26px"> 是</el-radio>
+                    <el-radio :value="0">  否</el-radio>
+                  </el-radio-group>
+                </td>
+              </tr>
+            </tbody>
+          </table>
+        </div>
+
+        <!-- 风险程度判断 -->
+        <div class="risk-judgment-section">
+          <div class="risk-judgment-title">风险程度判断:</div>
+          <div class="risk-options">
+            <el-radio v-model="form.riskLevel" value="none" :disabled="isDetail">
+                无风险:0分
+            </el-radio>
+            <el-radio v-model="form.riskLevel" value="low" :disabled="isDetail">
+                低风险:1-5分
+            </el-radio>
+            <el-radio v-model="form.riskLevel" value="medium" :disabled="isDetail">
+                中风险:6-8分
+            </el-radio>
+            <el-radio v-model="form.riskLevel" value="high" :disabled="isDetail">
+                高风险:≥9分
+            </el-radio>
+          </div>
+        </div>
+
+        <!-- 预防措施 -->
+        <div class="preventive-section">
+          <div class="preventive-title">预防措施:</div>
+          <div class="preventive-options">
+            <el-checkbox v-model="form.preventiveMeasures" value="patrol" :disabled="isDetail">
+                加强巡视
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" value="handover" :disabled="isDetail">
+                严格交接班
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" value="checkItems" :disabled="isDetail">
+                检查有无危险物品
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" value="emotion" :disabled="isDetail">
+                注重长者情绪行为
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" value="other" :disabled="isDetail">
+                其他
+            </el-checkbox>
+            <el-input v-if="form.preventiveMeasures.includes('other')" v-model="form.preventiveMeasuresOther" placeholder="请输入其他措施" :disabled="isDetail" class="other-input"/>
+          </div>
+        </div>
+
+        <!-- 签名区域 -->
+        <div class="signature-section">
+          <div class="signature-row">
+            <div class="signature-item">
+              <span class="signature-label">家属/监护人签名:</span>
+              <el-input v-model="form.familySignature" :disabled="isDetail" class="signature-input"/>
+            </div>
+
+          </div>
+        </div>
+
+        <!-- 说明 -->
+        <div class="note-section">
+          <div class="note-title">说明:</div>
+          <div class="note-content">
+            <p>1. 新入住长者应在长者入住24小时内完成首次评估;</p>
+            <p>2. 定期评估:</p>
+            <p class="indent">(1)认知照护专区:高风险1个月评估一次,中风险、低风险3个月评估一次;</p>
+            <p class="indent">(2)非认知照护专区:高风险1个月评估一次,中风险3个月评估一次,低风险6个月评估一次;</p>
+            <p>3. 当长者身体发生变化者,应及时进行动态评估。</p>
+          </div>
+        </div>
+      </div>
+
+    </div>
+      <div><div style="font-weight: bold">这是提交字段,后端可照此字段创建数据表</div>:
+        {
+        "contractNumber": "NS20230012",
+        "elderName": "张宝贞",
+        "bedName": "养护楼-7层-712-01",
+        "checkInTime": 1676851200000,
+        "elderId": 17446,
+        "tenantId": 211,
+        "assessmentData": "{\"assessor\":\"\",\"assessDate\":\"\",\"riskScores\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"totalScore\":0,\"riskLevel\":\"\",\"preventiveMeasures\":[],\"preventiveMeasuresOther\":\"\",\"familySignature\":\"\",\"familySignDate\":\"\"}",
+        "totalScore": 0,
+        "assessor": "",
+        "assessDate": "",
+        "orgType": 1
+        }
+      </div>
+
+
+    <template #footer>
+      <el-button @click="handleClosed">关闭</el-button>
+      <el-button  type="success" @click="handleExport">打印</el-button>
+      <el-button style="margin-left: 22px;margin-right: 30px" v-loading="formLoading" type="primary" v-show="!isDetail" @click="submitForm">确定</el-button>
+    </template>
+
+  </el-drawer>
+</template>
+
+<script lang="ts" setup>
+import { computed, ref, watch } from 'vue'
+
+import dayjs from 'dayjs'
+
+import { ngasrCreate, ngasrGetById, ngasrUpdate, ngasrGetByElderId } from "@/api/social-work";
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+const title = ref('')
+const dialogVisible = ref(false) // 弹窗
+const formRef = ref() // 表单 Ref
+const selectElderRef = ref() // 表单 Ref
+const isDetail = ref(false) // 是否详情打开
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+let dataForm = ref({
+  // 表单字段
+  id: undefined,
+  idCard: '',
+  contractNumber: '', //档案号
+  elderName: '',//长者姓名
+  bedName: '', //床位号
+  elderAge: '', //年龄
+  elderSex: '', //性别
+  checkInTime: '', //入院日期
+  elderId: '',
+  tenantId: undefined
+})
+
+
+
+
+const elderUp = (e) => {
+  dataForm.value.elderName = e.elderName
+  dataForm.value.elderId = e.id
+  dataForm.value.elderSex = e.elderSex === 1 ? '男' : '女'
+  dataForm.value.bedName = e.bedName || ''
+  dataForm.value.checkInTime = e.checkInTime
+  dataForm.value.contractNumber = e.contractNumber
+  dataForm.value.elderAge = e.elderAge
+}
+
+// ========== NGASR自杀风险评估量表 表单序列化方法 ==========
+
+// 危险因素列表
+const riskFactors = [
+  { name: '绝望感', yesScore: 3 },
+  { name: '近期负性生活事件', yesScore: 1 },
+  { name: '被害妄想或有被害内容的幻听', yesScore: 1 },
+  { name: '情绪低落/兴趣丧失或愉快感缺乏', yesScore: 3 },
+  { name: '人际和社会功能退缩', yesScore: 1 },
+  { name: '言语流露自杀意图', yesScore: 1 },
+  { name: '计划采取自杀行动', yesScore: 3 },
+  { name: '自杀家族史', yesScore: 1 },
+  { name: '近亲人死亡或重要的亲密关系丧失', yesScore: 3 },
+  { name: '精神病史', yesScore: 1 },
+  { name: '鳏夫/寡妇', yesScore: 1 },
+  { name: '自杀未遂史', yesScore: 3 },
+  { name: '社会-经济地位低下', yesScore: 1 },
+  { name: '饮酒史或酒精滥用', yesScore: 1 },
+  { name: '罹患晚期疾病', yesScore: 1 }
+]
+
+
+
+/** 风险程度文本 */
+const riskLevelText = computed(() => {
+  const score = totalScore.value
+  if (score === 0) return '无风险'
+  if (score >= 1 && score <= 5) return '低风险'
+  if (score >= 6 && score <= 8) return '中风险'
+  return '高风险'
+})
+
+/** 风险程度样式类 */
+const riskLevelClass = computed(() => {
+  const score = totalScore.value
+  if (score === 0) return 'risk-none'
+  if (score >= 1 && score <= 5) return 'risk-low'
+  if (score >= 6 && score <= 8) return 'risk-medium'
+  return 'risk-high'
+})
+
+/** 自动判断风险等级 */
+const autoJudgeRiskLevel = () => {
+  const score = totalScore.value
+  if (score === 0) form.riskLevel = 'none'
+  else if (score >= 1 && score <= 5) form.riskLevel = 'low'
+  else if (score >= 6 && score <= 8) form.riskLevel = 'medium'
+  else form.riskLevel = 'high'
+}
+
+
+
+/** 将表单数据序列化为 JSON 对象 */
+const serializeFormData = () => {
+  return {
+    // 基本信息
+    assessor: form.assessor || '',
+    assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : '',
+
+    // 各危险因素得分
+    riskScores: form.riskScores || [],
+
+    // 总分
+    totalScore: totalScore.value,
+
+    // 风险程度
+    riskLevel: form.riskLevel || '',
+
+    // 预防措施
+    preventiveMeasures: form.preventiveMeasures || [],
+    preventiveMeasuresOther: form.preventiveMeasuresOther || '',
+
+    // 签名
+    familySignature: form.familySignature || '',
+    familySignDate: form.familySignDate ? dayjs(form.familySignDate).format('YYYY-MM-DD') : ''
+  }
+}
+
+/** 将 JSON 对象反序列化为表单数据 */
+const deserializeFormData = (formData: Record<string, any>) => {
+  if (!formData) return
+
+  // 基本信息
+  form.assessor = formData.assessor || ''
+  form.assessDate = formData.assessDate ? dayjs(formData.assessDate).toDate() : ''
+
+  // 各危险因素得分
+  form.riskScores = formData.riskScores || new Array(15).fill(0)
+
+  // 风险程度
+  form.riskLevel = formData.riskLevel || ''
+
+  // 预防措施
+  form.preventiveMeasures = formData.preventiveMeasures || []
+  form.preventiveMeasuresOther = formData.preventiveMeasuresOther || ''
+
+  // 签名
+  form.familySignature = formData.familySignature || ''
+  form.familySignDate = formData.familySignDate ? dayjs(formData.familySignDate).toDate() : ''
+}
+
+/** 重置NGASR评估表表单数据 */
+const resetNGASRForm = () => {
+  form.assessor = ''
+  form.assessDate = ''
+
+  // 各危险因素得分(15个因素,初始为0)
+  form.riskScores = new Array(15).fill(0)
+
+  // 风险程度
+  form.riskLevel = ''
+
+  // 预防措施
+  form.preventiveMeasures = []
+  form.preventiveMeasuresOther = ''
+
+  // 签名
+  form.familySignature = ''
+  form.familySignDate = ''
+}
+
+/** 打开弹窗 */
+const open = async (tenantId, id?: any, detail: boolean = false) => {
+  resetForm()
+  dialogVisible.value = true
+  dataForm.value.id = id || undefined
+  dataForm.value.tenantId = tenantId
+  isDetail.value = detail
+  if (id) {
+    title.value = "编辑-自杀风险评估"
+    // 加载评估数据
+    await loadNGASRData(id)
+  } else {
+    title.value = "新增-自杀风险评估"
+    // 如果选择了长者,尝试加载已有的评估数据
+    if (dataForm.value.elderId) {
+      await loadNGASRByElderId(dataForm.value.elderId)
+    }
+  }
+}
+
+/** 加载评估数据 */
+const loadNGASRData = async (id: number) => {
+  try {
+    const res = await ngasrGetById(id)
+    if (res) {
+      // 填充长者基本信息
+      dataForm.value.elderName = res.elderName || ''
+      dataForm.value.elderId = res.elderId || ''
+      dataForm.value.elderSex = res.elderSex || ''
+      dataForm.value.bedName = res.bedName || ''
+      dataForm.value.checkInTime = res.checkInTime || ''
+      dataForm.value.contractNumber = res.contractNumber || ''
+      dataForm.value.elderAge = res.elderAge || ''
+
+      // 解析 assessmentData
+      if (res.assessmentData) {
+        const formData = JSON.parse(res.assessmentData)
+        deserializeFormData(formData)
+      }
+    }
+  } catch (error) {
+    message.error('加载评估数据失败')
+  }
+}
+
+/** 根据长者ID加载评估数据 */
+const loadNGASRByElderId = async (elderId: number) => {
+  try {
+    const res = await ngasrGetByElderId(elderId)
+    if (res && res.assessmentData) {
+      const formData = JSON.parse(res.assessmentData)
+      deserializeFormData(formData)
+    }
+  } catch (error) {
+    // 无历史数据,不处理
+  }
+}
+
+const form = reactive({
+  // 基本信息
+  assessor: '',
+  assessDate: '',
+
+  // 各危险因素得分(15个因素)
+  riskScores: new Array(15).fill(0),
+
+  // 风险程度
+  riskLevel: '',
+
+  // 预防措施
+  preventiveMeasures: [],
+  preventiveMeasuresOther: '',
+
+  // 签名
+  familySignature: '',
+  familySignDate: ''
+})
+
+/** 计算总分 */
+const totalScore = computed(() => {
+  if (!form.riskScores || form.riskScores.length === 0) return 0
+  return form.riskScores.reduce((sum, score) => sum + (score || 0), 0)
+})
+
+// 监听总分变化,自动判断风险等级
+watch(totalScore, () => {
+  autoJudgeRiskLevel()
+})
+
+
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  if (formLoading.value) {
+    return
+  }
+  formLoading.value = true
+  // 提交请求
+  try {
+    const assessmentData = serializeFormData()
+    const tempParams = {
+      ...dataForm.value,
+      assessmentData: JSON.stringify(assessmentData),
+      totalScore: totalScore.value,
+      assessor: form.assessor,
+      assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''
+    }
+
+    if (dataForm.value.id) {
+      const res = await ngasrUpdate(tempParams)
+      if (res) {
+        message.success(t('common.updateSuccess'))
+        dialogVisible.value = false
+        // 发送操作成功的事件
+        emit('success')
+      }
+    } else {
+      const res = await ngasrCreate(tempParams)
+      if (res) {
+        message.success(t('common.createSuccess'))
+        dialogVisible.value = false
+        // 发送操作成功的事件
+        emit('success')
+      }
+    }
+  } finally {
+    setTimeout(() => {
+      formLoading.value = false
+    }, 500)
+  }
+}
+
+
+
+/** 重置表单 */
+const resetForm = () => {
+  dataForm.value = {
+    id: undefined,
+    idCard: '',
+    contractNumber: '', //档案号
+    elderName: '',//长者姓名
+    bedName: '', //床位号
+    elderAge: '', //年龄
+    elderSex: '', //性别
+    checkInTime: '', //入院日期
+    elderId: '',
+    tenantId: undefined
+  }
+  formRef.value?.resetFields()
+
+  // 重置NGASR评估表表单
+  resetNGASRForm()
+}
+
+// 关闭表单
+const handleClosed = () => {
+  dialogVisible.value = false
+  resetForm()
+}
+
+/** 导出打印 */
+const handleExport = () => {
+  // 创建打印窗口
+  const printWindow = window.open('', '_blank')
+  if (!printWindow) {
+    message.error('请允许弹出窗口')
+    return
+  }
+
+  // 构建危险因素表格行
+  const riskFactorRows = riskFactors.map((item, index) => {
+    const score = form.riskScores[index] || 0
+    return `
+      <tr>
+        <td class="risk-factor">${item.name}</td>
+        <td class="score-yes">${item.yesScore}分</td>
+        <td class="score-no">0分</td>
+        <td class="select">${score === item.yesScore ? '☑ 是' : '☐ 是'} / ${score === 0 ? '☑ 否' : '☐ 否'}</td>
+      </tr>
+    `
+  }).join('')
+
+  // 构建打印内容
+  const printContent = `
+    <!DOCTYPE html>
+    <html>
+    <head>
+      <meta charset="UTF-8">
+      <title>自杀风险评估量表(NGASR) - ${dataForm.value.elderName || ''}</title>
+      <style>
+        @media print {
+          @page { size: A4 portrait; margin: 15mm; }
+        }
+        body {
+          font-family: 'SimSun', 'Microsoft YaHei', serif;
+          font-size: 11pt;
+          line-height: 1.5;
+          color: #333;
+        }
+        .header {
+          text-align: center;
+          margin-bottom: 20px;
+          border-bottom: 2px solid #333;
+          padding-bottom: 10px;
+        }
+        .header h1 {
+          font-size: 18pt;
+          margin: 0;
+          letter-spacing: 2px;
+        }
+        .info-section {
+          margin-bottom: 15px;
+          padding: 10px;
+          border: 1px solid #999;
+          background: #fafafa;
+        }
+        .info-row {
+          display: flex;
+          flex-wrap: wrap;
+          gap: 20px;
+        }
+        .info-item {
+          display: flex;
+          align-items: center;
+        }
+        .info-item .label {
+          font-weight: bold;
+          margin-right: 8px;
+          color: #555;
+        }
+        .info-item .value {
+          border-bottom: 1px solid #333;
+          min-width: 80px;
+          padding: 0 5px;
+          text-align: center;
+        }
+        .score-summary {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          padding: 10px 15px;
+          background: #f0f0f0;
+          border: 2px solid #333;
+          margin-bottom: 15px;
+        }
+        .total-score {
+          font-size: 14pt;
+          font-weight: bold;
+        }
+        .total-score .score-value {
+          color: #d9534f;
+          font-size: 18pt;
+        }
+        .risk-level {
+          font-size: 12pt;
+          font-weight: bold;
+          padding: 5px 15px;
+        }
+        .risk-none { color: #5cb85c; }
+        .risk-low { color: #f0ad4e; }
+        .risk-medium { color: #d9534f; }
+        .risk-high { color: #d9534f; background: #ffe6e6; padding: 5px 10px; border-radius: 3px; }
+
+        .assessment-table {
+          width: 100%;
+          border-collapse: collapse;
+          margin-bottom: 15px;
+        }
+        .assessment-table th, .assessment-table td {
+          border: 1px solid #333;
+          padding: 8px;
+          text-align: left;
+        }
+        .assessment-table th {
+          background: #e8e8e8;
+          font-weight: bold;
+          text-align: center;
+        }
+        .assessment-table .risk-factor-col {
+          width: 45%;
+        }
+        .assessment-table .score-yes-col,
+        .assessment-table .score-no-col {
+          width: 12%;
+          text-align: center;
+        }
+        .assessment-table .select-col {
+          width: 31%;
+          text-align: center;
+        }
+        .assessment-table .risk-factor {
+          text-align: left;
+        }
+        .assessment-table .score-yes,
+        .assessment-table .score-no {
+          text-align: center;
+        }
+
+        .risk-judgment-section {
+          margin: 15px 0;
+          padding: 10px;
+          border: 1px solid #999;
+        }
+        .risk-judgment-title {
+          font-weight: bold;
+          margin-bottom: 10px;
+        }
+        .risk-options {
+          display: flex;
+          flex-wrap: wrap;
+          gap: 15px;
+        }
+        .risk-option {
+          display: inline-block;
+        }
+
+        .measures-section {
+          margin: 15px 0;
+          border: 1px solid #999;
+        }
+        .measures-title {
+          font-weight: bold;
+          background: #e8e8e8;
+          padding: 8px 12px;
+          border-bottom: 1px solid #999;
+        }
+        .measures-content {
+          padding: 10px 12px;
+        }
+        .measure-item {
+          margin-bottom: 8px;
+          font-size: 10pt;
+        }
+        .measure-other {
+          margin-left: 10px;
+          border-bottom: 1px solid #333;
+          min-width: 200px;
+          display: inline-block;
+        }
+
+        .signature-section {
+          margin-top: 30px;
+          padding: 15px;
+          border: 1px solid #999;
+        }
+        .signature-row {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+        }
+        .signature-item {
+          display: flex;
+          align-items: center;
+          gap: 10px;
+        }
+        .signature-label {
+          font-weight: bold;
+        }
+        .signature-value {
+          border-bottom: 1px solid #333;
+          min-width: 150px;
+          height: 25px;
+        }
+
+        .note-section {
+          margin-top: 20px;
+          padding: 15px;
+          border: 1px solid #999;
+          background: #fafafa;
+        }
+        .note-title {
+          font-weight: bold;
+          margin-bottom: 10px;
+        }
+        .note-content {
+          font-size: 10pt;
+          line-height: 1.8;
+        }
+        .note-content p {
+          margin: 5px 0;
+        }
+        .note-content .indent {
+          margin-left: 20px;
+        }
+      </style>
+    </head>
+    <body>
+      <div class="header">
+        <h1>自杀风险评估量表(NGASR)</h1>
+      </div>
+
+      <div class="info-section">
+        <div class="info-row">
+          <div class="info-item">
+            <span class="label">长者姓名:</span>
+            <span class="value">${dataForm.value.elderName || ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">档案号:</span>
+            <span class="value">${dataForm.value.contractNumber || ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">床位号:</span>
+            <span class="value">${dataForm.value.bedName || ''}</span>
+          </div>
+        </div>
+        <div class="info-row" style="margin-top: 10px;">
+          <div class="info-item">
+            <span class="label">评估日期:</span>
+            <span class="value">${form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">评估人:</span>
+            <span class="value">${form.assessor || ''}</span>
+          </div>
+        </div>
+      </div>
+
+      <div class="score-summary">
+        <div class="total-score">
+          总得分:<span class="score-value">${totalScore.value}</span> 分
+        </div>
+
+      </div>
+
+      <!-- 评估表格 -->
+      <table class="assessment-table">
+        <thead>
+          <tr>
+            <th class="risk-factor-col">危险因素</th>
+            <th class="score-yes-col">是</th>
+            <th class="score-no-col">否</th>
+            <th class="select-col">选择</th>
+          </tr>
+        </thead>
+        <tbody>
+          ${riskFactorRows}
+        </tbody>
+      </table>
+
+      <!-- 风险程度判断 -->
+      <div class="risk-judgment-section">
+        <div class="risk-judgment-title">风险程度判断:</div>
+        <div class="risk-options">
+          <span class="risk-option">${form.riskLevel === 'none' ? '☑' : '☐'} 无风险:0分</span>
+          <span class="risk-option">${form.riskLevel === 'low' ? '☑' : '☐'} 低风险:1-5分</span>
+          <span class="risk-option">${form.riskLevel === 'medium' ? '☑' : '☐'} 中风险:6-8分</span>
+          <span class="risk-option">${form.riskLevel === 'high' ? '☑' : '☐'} 高风险:≥9分</span>
+        </div>
+      </div>
+
+      <!-- 预防措施 -->
+      <div class="measures-section">
+        <div class="measures-title">预防措施</div>
+        <div class="measures-content">
+          <div class="measure-item">${form.preventiveMeasures?.includes('patrol') ? '☑' : '☐'} 加强巡视</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('handover') ? '☑' : '☐'} 严格交接班</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('checkItems') ? '☑' : '☐'} 检查有无危险物品</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('emotion') ? '☑' : '☐'} 注重长者情绪行为</div>
+          <div class="measure-item">
+            ${form.preventiveMeasures?.includes('other') ? '☑' : '☐'} 其他
+            ${form.preventiveMeasures?.includes('other') ? '<span class="measure-other">' + (form.preventiveMeasuresOther || '') + '</span>' : ''}
+          </div>
+        </div>
+      </div>
+
+      <!-- 签名区域 -->
+      <div class="signature-section">
+        <div class="signature-row">
+          <div class="signature-item">
+            <span class="signature-label">家属/监护人签名:</span>
+            <span class="signature-value">${form.familySignature || ''}</span>
+          </div>
+
+        </div>
+      </div>
+
+      <!-- 说明 -->
+      <div class="note-section">
+        <div class="note-title">说明:</div>
+        <div class="note-content">
+          <p>1. 新入住长者应在长者入住24小时内完成首次评估;</p>
+          <p>2. 定期评估:</p>
+          <p class="indent">(1)认知照护专区:高风险1个月评估一次,中风险、低风险3个月评估一次;</p>
+          <p class="indent">(2)非认知照护专区:高风险1个月评估一次,中风险3个月评估一次,低风险6个月评估一次;</p>
+          <p>3. 当长者身体发生变化者,应及时进行动态评估。</p>
+        </div>
+      </div>
+    </body>
+    </html>
+  `
+
+  // 写入内容并打印
+  printWindow.document.write(printContent)
+  printWindow.document.close()
+
+  // 延迟打印,确保样式加载完成
+  setTimeout(() => {
+    printWindow.print()
+  }, 500)
+}
+
+</script>
+
+<style scoped lang="scss">
+
+.form-title {
+  text-align: center;
+  font-size: 20px;
+  width: 100%;
+  margin-bottom: 20px;
+}
+
+.mmse-form {
+  max-width: 1200px;
+  margin: 0 auto;
+  background: #fff;
+
+
+
+
+
+  .info-row {
+    display: flex;
+    gap: 40px;
+    width: 100%;
+    flex-direction: row;
+    align-items: center;
+    margin-bottom: 10px;
+
+    .info-item {
+      display: flex;
+      align-items: center;
+      gap: 8px;
+
+      .label {
+        width: 82px;
+        text-align: right;
+        margin-right: 4px;
+        white-space: nowrap;
+      }
+    }
+  }
+
+
+  .form-body {
+    border: 1px solid #333;
+    padding: 15px;
+  }
+
+  // 调整 Element Plus 组件样式
+  :deep(.el-input__inner) {
+    height: 28px;
+    line-height: 28px;
+    border-top: none;
+    border-left: none;
+    border-right: none;
+    border-radius: 0;
+    padding: 0 4px;
+
+    &:focus {
+      border-color: #409eff;
+    }
+  }
+
+  :deep(.el-checkbox__label),
+  :deep(.el-radio__label) {
+    padding-left: 4px;
+  }
+}
+.row{
+  margin-bottom: 12px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  text{
+    text-align: right;
+    margin-right: 4px;
+    width: 82px;
+  }
+}
+
+// NGASR自杀风险评估量表 特有样式
+.total-score-section {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  margin-bottom: 20px;
+
+  .total-score {
+    display: flex;
+    align-items: baseline;
+    gap: 4px;
+
+    .score-label {
+      font-size: 16px;
+      font-weight: bold;
+    }
+
+    .score-value {
+      font-size: 28px;
+      font-weight: bold;
+      color: #409eff;
+    }
+
+    .score-max {
+      font-size: 14px;
+      color: #909399;
+    }
+  }
+
+  .risk-level {
+    font-size: 16px;
+    font-weight: bold;
+    padding: 8px 16px;
+    border-radius: 4px;
+
+    &.risk-none {
+      color: #67c23a;
+      background: #f0f9eb;
+    }
+
+    &.risk-low {
+      color: #e6a23c;
+      background: #fdf6ec;
+    }
+
+    &.risk-medium {
+      color: #f56c6c;
+      background: #fef0f0;
+    }
+
+    &.risk-high {
+      color: #f56c6c;
+      background: #fef0f0;
+      border: 1px solid #f56c6c;
+    }
+  }
+}
+
+.assessment-table {
+  width: 100%;
+  border-collapse: collapse;
+  margin-bottom: 20px;
+
+  table {
+    width: 100%;
+    border: 1px solid #333;
+
+    th, td {
+      border: 1px solid #333;
+      padding: 12px;
+      text-align: left;
+    }
+
+    th {
+      background: #f5f7fa;
+      font-weight: bold;
+      text-align: center;
+    }
+
+    .criteria-col {
+      width: 60%;
+    }
+
+    .score-col {
+      width: 15%;
+      text-align: center;
+    }
+
+    .select-col {
+      width: 25%;
+      text-align: center;
+    }
+
+    .criteria {
+      text-align: left;
+    }
+
+    .score {
+      text-align: center;
+      font-weight: bold;
+    }
+
+    .select {
+      text-align: center;
+
+      :deep(.el-radio) {
+        margin-right: 0;
+      }
+    }
+  }
+}
+
+.remark-section {
+  margin: 15px 0;
+  padding: 12px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .remark-label {
+    font-weight: bold;
+    color: #606266;
+  }
+
+  .remark-text {
+    color: #606266;
+  }
+}
+
+.risk-judgment-section {
+  margin: 20px 0;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .risk-judgment-title {
+    font-weight: bold;
+    font-size: 16px;
+    margin-bottom: 12px;
+    color: #303133;
+  }
+
+  .risk-options {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 20px;
+
+    :deep(.el-radio) {
+      margin-right: 0;
+    }
+  }
+}
+
+.preventive-section {
+  margin: 20px 0;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .preventive-title {
+    font-weight: bold;
+    font-size: 16px;
+    margin-bottom: 12px;
+    color: #303133;
+  }
+
+  .preventive-options {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 15px;
+
+    :deep(.el-checkbox) {
+      margin-right: 20px;
+      margin-bottom: 8px;
+    }
+
+    .other-input {
+      width: 200px;
+      margin-left: 10px;
+    }
+  }
+}
+
+.signature-section {
+  margin: 20px 0;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .signature-row {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    gap: 20px;
+  }
+
+  .signature-item {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+
+    &.date-item {
+      :deep(.el-date-picker) {
+        width: 150px;
+      }
+    }
+  }
+
+  .signature-label {
+    font-weight: bold;
+    white-space: nowrap;
+  }
+
+  .signature-input {
+    width: 150px;
+  }
+
+  .date-picker {
+    width: 150px;
+  }
+}
+
+.note-section {
+  margin-top: 20px;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .note-title {
+    font-weight: bold;
+    font-size: 16px;
+    margin-bottom: 12px;
+    color: #303133;
+  }
+
+  .note-content {
+    font-size: 13px;
+    line-height: 1.8;
+    color: #606266;
+
+    p {
+      margin: 5px 0;
+    }
+
+    .indent {
+      margin-left: 20px;
+    }
+  }
+}
+</style>

+ 327 - 0
src/views/social-worker/assessment/NGASR/index.vue

@@ -0,0 +1,327 @@
+<template>
+  <ContentWrap>
+    <!-- 保护性约束观察记录表 -->
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="110px"
+    >
+      <el-form-item label="长者姓名">
+        <el-input
+          v-model="queryParams.elderName"
+          placeholder="长者姓名"
+          class="!w-240px"
+          clearable
+        />
+      </el-form-item>
+
+
+
+      <el-form-item label="记录日期">
+        <el-date-picker
+          size="default"
+          ref="selectRef"
+          class="!w-240px"
+          v-model="queryParams.recordDate"
+          type="daterange"
+          :clearable="true"
+          :editable="false"
+          placeholder="选择记录日期"
+          value-format="YYYY-MM-DD"
+          format="YYYY-MM-DD"
+          date-format="YYYY-MM-DD"
+        />
+      </el-form-item>
+
+      <el-form-item>
+        <el-button @click="handleQuery" style="margin-left: 2vw"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <div class="mb-10px">
+
+      <ButtonAdd @click="openForm(undefined)"  />
+      <!--      <el-button @click="inputH" type="success"><Icon icon="fa:cloud-upload" :size="16" class="mr-1"/>导入</el-button>-->
+      <ButtonImport @click="handleImportCard"  />
+
+
+    </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">
+          {{
+            scope.$index + (queryParams.pageNo * queryParams.pageSize - queryParams.pageSize) + 1
+          }}
+        </template>
+      </el-table-column>
+
+
+      <el-table-column prop="elderName" header-align="center" align="center" label="长者姓名" min-width="150" show-overflow-tooltip/>
+      <el-table-column prop="bedName" header-align="center" align="center" label="床位号" min-width="200" show-overflow-tooltip/>
+      <el-table-column prop="recordDate" header-align="center" align="center" label="记录日期" min-width="200" show-overflow-tooltip/>
+
+      <el-table-column prop="creator" header-align="center" align="center" label="记录人" min-width="200" show-overflow-tooltip/>
+
+
+      <el-table-column label="操作" align="center" width="200" >
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            @click="openFormEdit(scope.row, scope.row.id)"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="warning"
+            @click="openFormDetail(scope.row,scope.row.id)"
+          >
+            详情
+          </el-button>
+          <el-button
+            link
+            type="danger"
+            @click="openClose(scope.row)"
+          >
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+  <AddForm ref="formRef" @success="getList" />
+
+  <!-- 通用批量导出弹窗 -->
+  <BatchExportDialog
+    :show="showBatchExport"
+    :title="exportConfig.title"
+    :loading="exportLoading"
+    :batch-min="exportConfig.batchMin"
+    :batch-max="exportConfig.batchMax"
+    :count-min="exportConfig.countMin"
+    :count-max="exportConfig.countMax"
+    :default-batch="exportConfig.defaultBatch"
+    :default-count="exportConfig.defaultCount"
+    :description="exportConfig.description"
+    @update:show="showBatchExport = $event"
+    @confirm="handleBatchExport"
+    @cancel="showBatchExport = false"
+  />
+
+
+  <Import
+    ref="importRef"
+    @success="getList"
+    :config="{
+      title: '导入',
+      downloadUrl: 'elderly-service-order/get-import-template',
+      excelTempName: '居家工单-【导入】模板',
+      importUrl: '/elderly-service-order/import',
+      failExportUrl: '',
+    }"
+  />
+
+</template>
+
+<script setup lang="ts">
+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 {formatTimestamp, getCurrentMonthRange} from "@/utils/dateUtil";
+import Import from "@/components/ImportFile/index.vue";
+import {restraintCreatePage, restraintDelete} from "@/api/elderly/nursing/keep-fit";
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+const userStore = useUserStore()
+const loading = ref(true) // 列表的加载中
+const detailRef = ref()
+const importRef = ref()
+const total = ref(0) // 列表的总页数
+const list = ref([]) // 列表的数据
+
+// 状态管理
+const showBatchExport = ref(false)
+const exportConfig = ref({
+  title: '',
+  batchMin: 1,
+  batchMax: 999,
+  countMin: 1,
+  countMax: 200,
+  defaultBatch: 1,
+  defaultCount: 200,
+  description: [] as string[]
+})
+const exportLoading = ref(false)
+
+let queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  elderName: '',
+  creator: '',
+  recordDate: getCurrentMonthRange(),
+  tenantIds: userStore.orgTenantId
+})
+const queryFormRef = ref() // 搜索的表单
+
+const inputH = () => {
+  importRef.value.open(queryParams.tenantIds[0])
+}
+// 打开导出弹窗
+const handleImportCard = async () => {
+
+  // showBatchExport.value = true
+}
+
+// 处理批量导出
+const handleBatchExport = async (batch: number, count: number) => {
+  exportLoading.value = true
+  console.log(batch,count)
+  // try {
+  //   let queryParams = {
+  //     pageNo: batch,
+  //     pageSize: count,
+  //     tenantId: userStore.orgTenantId[0]
+  //   }
+  //   const list = await careRecordsPage(queryParams)
+  //   if (list.length <= 0) {
+  //     message.error('暂无数据可以导出!')
+  //     return
+  //   }
+  //   const headers = [
+  //     { key: 'organizationName', title: '机构名称' },
+  //     { key: 'visitName', title: '姓名' },
+  //     { key: 'visitPhone', title: '手机号' },
+  //     { key: 'visitDate', title: '预约时间' },
+  //     { key: 'accompanyCount', title: '陪同人数' },
+  //     { key: 'reason', title: '理由' }
+  //   ]
+  //   exportWithExpandedObjectArrays(list, headers, `医疗护理记录${formatToDateTime()}.xlsx`, '医疗护理记录')
+  // } catch (_) {}
+
+}
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    //let queryP = {...queryParams,discoveryTime:queryParams.discoveryTime?[queryParams.discoveryTime[0]+" 00:00:00",queryParams.discoveryTime[1]+" 23:59:59"]:null}
+    const data = await restraintCreatePage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = async () => {
+  if (!queryFormRef.value) return
+  const valid = await queryFormRef.value.validate()
+  if (!valid) return
+  queryParams.pageNo = 1
+  await getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryParams.elderName = ''
+  queryParams.creator = ''
+  queryParams.tenantIds = userStore.orgTenantId
+  queryParams.recordDate= getCurrentMonthRange()
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+/** 添加/修改操作 */
+const formRef = ref()
+const openForm = (id?: number) => {
+  if(queryParams.tenantIds.length == 0 || queryParams.tenantIds.length > 1){
+    message.error('新增只能选择一个机构')
+    return
+  }
+  formRef.value.open(queryParams.tenantIds[0], id,false)
+}
+
+const editRef = ref()
+const openFormEdit = (row: any = {}, id?: number) => {
+  formRef.value.open(row.tenantId, id,false)
+}
+
+
+const openFormDetail = (row: any = {},id?: number) => {
+  formRef.value.open(row.tenantId,id,true)
+}
+
+
+
+
+
+const openClose = async (item) => {
+  try {
+    console.log("任务ID",item)
+    const res = await message.confirm('确定要删除吗?', '提示')
+    if (res == 'confirm') {
+      // 发起
+      try {
+        const res = await restraintDelete(item.id)
+        if (res){
+          message.success(t('common.updateSuccess'))
+        }
+      }catch(err) {}
+    }
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 取消按钮操作 */
+const cancelDelete = async (id: number) => {
+  try {
+    // 取消的二次确认
+    await message.cancelConfirm()
+    // 发起取消
+    // await elderlyBakDel(id)
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+const route = useRoute()
+/** 初始化 **/
+onMounted(() => {
+  if(route.query && route.query.elderName){
+    queryParams.elderName = route.query.elderName as string
+  }
+  getList()
+})
+
+// 表头格式
+const tableHeaderColor = ({ rowIndex }: any) => {
+  if (rowIndex === 0) {
+    return {
+      backgroundColor: '#f8f8f9',
+      color: '#666666',
+      fontWeight: 'bold'
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss"></style>

+ 1255 - 0
src/views/social-worker/assessment/PerceptionAndCommunication/AddForm.vue

@@ -0,0 +1,1255 @@
+<template>
+  <el-drawer
+    v-model="dialogVisible"
+    :title="title"
+    resizable
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    :destroy-on-close="true"
+    size="70%"
+    :before-close="handleClosed"
+  >
+
+    <div class="mmse-form">
+      <h1 class="form-title">感知觉与沟通评估表</h1>
+      <!-- 基本信息 -->
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>长者姓名</text>
+          <search-the-elderly ref="selectElderRef" :disabled="isDetail" @update_elder="elderUp" v-model="dataForm.elderName" :tId="dataForm.tenantId"/>
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>档案号</text>
+          <el-input v-if="!isDetail" v-model="dataForm.contractNumber" disabled />
+          <el-text v-else disabled="">{{dataForm.contractNumber}}</el-text>
+        </el-col>
+      </el-row>
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>入院日期</text>
+          <el-input v-if="!isDetail" :model-value="dayjs(dataForm.checkInTime).format('YYYY-MM-DD')=='Invalid Date'?'':dayjs(dataForm.checkInTime).format('YYYY-MM-DD')" disabled />
+          <el-text v-else disabled="">{{dayjs(dataForm.checkInTime).format('YYYY-MM-DD')}}</el-text>
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>床位号</text>
+          <el-input v-if="!isDetail" v-model="dataForm.bedName" disabled />
+          <el-text v-else disabled="">{{dataForm.bedName}}</el-text>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>评估人</text>
+          <el-input v-model="form.assessor"  />
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>评估日期</text>
+          <el-date-picker v-model="form.assessDate" type="date" style="width: 100%;"/>
+
+        </el-col>
+      </el-row>
+
+      <!-- 表单内容区域 -->
+      <div class="form-body">
+        <!-- 总分显示 -->
+        <div class="total-score-section">
+          <div class="total-score">
+            <span class="score-label">总得分:</span>
+            <span class="score-value">{{ totalScore }}</span>
+            <span class="score-max">/ 4分</span>
+          </div>
+        </div>
+
+        <!-- 评估表格 -->
+        <div class="assessment-table">
+          <table>
+            <thead>
+              <tr>
+                <th class="criteria-col">评估准则</th>
+                <th class="score-col">分值</th>
+                <th class="select-col">选择</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr>
+                <td class="criteria">能看清书报上的标准字体</td>
+                <td class="score">0分</td>
+                <td class="select">
+                  <el-radio v-model="form.visionScore" :label="0" :disabled="isDetail"/>
+                </td>
+              </tr>
+              <tr>
+                <td class="criteria">能看清楚大字体;但看不清书报上的标准字体</td>
+                <td class="score">1分</td>
+                <td class="select">
+                  <el-radio v-model="form.visionScore" :label="1" :disabled="isDetail"/>
+                </td>
+              </tr>
+              <tr>
+                <td class="criteria">视力有限;看不清报纸大标题;但能辨认物体</td>
+                <td class="score">2分</td>
+                <td class="select">
+                  <el-radio v-model="form.visionScore" :label="2" :disabled="isDetail"/>
+                </td>
+              </tr>
+              <tr>
+                <td class="criteria">辨认物体有困难;但眼睛能跟随物体移动;只能看到光、颜色和形状</td>
+                <td class="score">3分</td>
+                <td class="select">
+                  <el-radio v-model="form.visionScore" :label="3" :disabled="isDetail"/>
+                </td>
+              </tr>
+              <tr>
+                <td class="criteria">没有视力;眼睛不能跟随物体移动</td>
+                <td class="score">4分</td>
+                <td class="select">
+                  <el-radio v-model="form.visionScore" :label="4" :disabled="isDetail"/>
+                </td>
+              </tr>
+            </tbody>
+          </table>
+        </div>
+
+        <!-- 备注 -->
+        <div class="remark-section">
+          <span class="remark-label">备注:</span>
+          <span class="remark-text">若平日戴老花镜或近视镜,应在佩戴眼镜的情况下评估。</span>
+        </div>
+
+        <!-- 风险程度判断 -->
+        <div class="risk-judgment-section">
+          <div class="risk-judgment-title">风险程度判断:</div>
+          <div class="risk-options">
+            <el-radio v-model="form.riskLevel" label="none" :disabled="isDetail">
+                无风险:0分
+            </el-radio>
+            <el-radio v-model="form.riskLevel" label="low" :disabled="isDetail">
+                低风险:1分
+            </el-radio>
+            <el-radio v-model="form.riskLevel" label="medium" :disabled="isDetail">
+                中风险:2分
+            </el-radio>
+            <el-radio v-model="form.riskLevel" label="high" :disabled="isDetail">
+                高风险:≥3分
+            </el-radio>
+          </div>
+        </div>
+
+        <!-- 预防措施 -->
+        <div class="preventive-section">
+          <div class="preventive-title">预防措施:</div>
+          <div class="preventive-options">
+            <el-checkbox v-model="form.preventiveMeasures" label="patrol" :disabled="isDetail">
+                加强巡查
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" label="food" :disabled="isDetail">
+                合理食物
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" label="expression" :disabled="isDetail">
+                观察表情
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" label="medication" :disabled="isDetail">
+                药物统一管控
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" label="feeding" :disabled="isDetail">
+                严格协助进食操作规程
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" label="card" :disabled="isDetail">
+                设立床头卡标识
+            </el-checkbox>
+            <el-checkbox v-model="form.preventiveMeasures" label="other" :disabled="isDetail">
+                其他
+            </el-checkbox>
+            <el-input v-if="form.preventiveMeasures.includes('other')" v-model="form.preventiveMeasuresOther" placeholder="请输入其他措施" :disabled="isDetail" class="other-input"/>
+          </div>
+        </div>
+
+        <!-- 签名区域 -->
+        <div class="signature-section">
+          <div class="signature-row">
+            <div class="signature-item">
+              <span class="signature-label">家属/监护人签名:</span>
+              <el-input v-model="form.familySignature" :disabled="isDetail" class="signature-input"/>
+            </div>
+<!--            <div class="signature-item date-item">-->
+<!--              <span class="signature-label">日期:</span>-->
+<!--              <el-date-picker v-model="form.familySignDate" type="date" :disabled="isDetail" class="date-picker"/>-->
+<!--            </div>-->
+          </div>
+        </div>
+
+        <!-- 说明 -->
+        <div class="note-section">
+          <div class="note-title">说明:</div>
+          <div class="note-content">
+            <p>1. 新入住长者应在长者入住24小时内完成首次评估;</p>
+            <p>2. 定期评估:</p>
+            <p class="indent">(1)认知照护专区:高风险1个月评估一次,中风险、低风险3个月评估一次;</p>
+            <p class="indent">(2)非认知照护专区:高风险1个月评估一次,中风险3个月评估一次,低风险6个月评估一次;</p>
+            <p>3. 当长者身体发生变化者,应及时进行动态评估。</p>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div><div style="font-weight: bold">这是提交字段,后端可照此字段创建数据表</div>:
+      {
+      "contractNumber": "NS20190098",
+      "elderName": "陈木娣",
+      "bedName": "养护楼-4层-407-04",
+      "checkInTime": 1562284800000,
+      "elderId": 17563,
+      "tenantId": 211,
+      "assessmentData": "{\"assessor\":\"啊啊\",\"assessDate\":\"2026-03-20\",\"visionScore\":3,\"totalScore\":3,\"riskLevel\":\"high\",\"preventiveMeasures\":[\"expression\",\"medication\"],\"preventiveMeasuresOther\":\"\",\"familySignature\":\"搜索\",\"familySignDate\":\"\"}",
+      "totalScore": 3,
+      "assessor": "啊啊",
+      "assessDate": "2026-03-20",
+      "orgType": 1
+      }
+    </div>
+
+    <template #footer>
+      <el-button @click="handleClosed">关闭</el-button>
+      <el-button style="margin-left: 22px;margin-right: 30px" v-loading="formLoading" type="primary" v-show="!isDetail" @click="submitForm">确定</el-button>
+      <el-button  type="success" @click="handleExport">打印</el-button>
+    </template>
+
+  </el-drawer>
+</template>
+
+<script lang="ts" setup>
+import { computed, ref } from 'vue'
+
+import dayjs from 'dayjs'
+
+import { perceptionCreate, perceptionGetById, perceptionUpdate, perceptionGetByElderId } from "@/api/social-work";
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+const title = ref('')
+const dialogVisible = ref(false) // 弹窗
+const formRef = ref() // 表单 Ref
+const selectElderRef = ref() // 表单 Ref
+const isDetail = ref(false) // 是否详情打开
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+let dataForm = ref({
+  // 表单字段
+  id: undefined,
+  idCard: '',
+  contractNumber: '', //档案号
+  elderName: '',//长者姓名
+  bedName: '', //床位号
+  elderAge: '', //年龄
+  elderSex: '', //性别
+  checkInTime: '', //入院日期
+  elderId: '',
+  tenantId: undefined
+})
+
+
+
+
+const elderUp = (e) => {
+  dataForm.value.elderName = e.elderName
+  dataForm.value.elderId = e.id
+  dataForm.value.elderSex = e.elderSex === 1 ? '男' : '女'
+  dataForm.value.bedName = e.bedName || ''
+  dataForm.value.checkInTime = e.checkInTime
+  dataForm.value.contractNumber = e.contractNumber
+  dataForm.value.elderAge = e.elderAge
+}
+
+// ========== 感知觉与沟通评估表 表单序列化方法 ==========
+
+/** 计算总分 */
+const totalScore = computed(() => {
+  return form.visionScore || 0
+})
+
+/** 风险程度文本 */
+const riskLevelText = computed(() => {
+  const score = totalScore.value
+  if (score === 0) return '无风险'
+  if (score === 1) return '低风险'
+  if (score === 2) return '中风险'
+  return '高风险'
+})
+
+/** 风险程度样式类 */
+const riskLevelClass = computed(() => {
+  const score = totalScore.value
+  if (score === 0) return 'risk-none'
+  if (score === 1) return 'risk-low'
+  if (score === 2) return 'risk-medium'
+  return 'risk-high'
+})
+
+/** 将表单数据序列化为 JSON 对象 */
+const serializeFormData = () => {
+  return {
+    // 基本信息
+    assessor: form.assessor || '',
+    assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : '',
+
+    // 视力评分
+    visionScore: form.visionScore || 0,
+
+    // 总分
+    totalScore: totalScore.value,
+
+    // 风险程度
+    riskLevel: form.riskLevel || '',
+
+    // 预防措施
+    preventiveMeasures: form.preventiveMeasures || [],
+    preventiveMeasuresOther: form.preventiveMeasuresOther || '',
+
+    // 签名
+    familySignature: form.familySignature || '',
+    familySignDate: form.familySignDate ? dayjs(form.familySignDate).format('YYYY-MM-DD') : ''
+  }
+}
+
+/** 将 JSON 对象反序列化为表单数据 */
+const deserializeFormData = (formData: Record<string, any>) => {
+  if (!formData) return
+
+  // 基本信息
+  form.assessor = formData.assessor || ''
+  form.assessDate = formData.assessDate ? dayjs(formData.assessDate).toDate() : ''
+
+  // 视力评分
+  form.visionScore = formData.visionScore ?? 0
+
+  // 风险程度
+  form.riskLevel = formData.riskLevel || ''
+
+  // 预防措施
+  form.preventiveMeasures = formData.preventiveMeasures || []
+  form.preventiveMeasuresOther = formData.preventiveMeasuresOther || ''
+
+  // 签名
+  form.familySignature = formData.familySignature || ''
+  form.familySignDate = formData.familySignDate ? dayjs(formData.familySignDate).toDate() : ''
+}
+
+/** 重置感知觉与沟通评估表表单数据 */
+const resetPerceptionForm = () => {
+  form.assessor = ''
+  form.assessDate = ''
+
+  // 视力评分
+  form.visionScore = 0
+
+  // 风险程度
+  form.riskLevel = ''
+
+  // 预防措施
+  form.preventiveMeasures = []
+  form.preventiveMeasuresOther = ''
+
+  // 签名
+  form.familySignature = ''
+  form.familySignDate = ''
+}
+
+/** 打开弹窗 */
+const open = async (tenantId, id?: any, detail: boolean = false) => {
+  resetForm()
+  dialogVisible.value = true
+  dataForm.value.id = id || undefined
+  dataForm.value.tenantId = tenantId
+  isDetail.value = detail
+  if (id) {
+    title.value = "编辑-感知觉与沟通评估"
+    // 加载评估数据
+    await loadPerceptionData(id)
+  } else {
+    title.value = "新增-感知觉与沟通评估"
+    // 如果选择了长者,尝试加载已有的评估数据
+    if (dataForm.value.elderId) {
+      await loadPerceptionByElderId(dataForm.value.elderId)
+    }
+  }
+}
+
+/** 加载评估数据 */
+const loadPerceptionData = async (id: number) => {
+  try {
+    const res = await perceptionGetById(id)
+    if (res) {
+      // 填充长者基本信息
+      dataForm.value.elderName = res.elderName || ''
+      dataForm.value.elderId = res.elderId || ''
+      dataForm.value.elderSex = res.elderSex || ''
+      dataForm.value.bedName = res.bedName || ''
+      dataForm.value.checkInTime = res.checkInTime || ''
+      dataForm.value.contractNumber = res.contractNumber || ''
+      dataForm.value.elderAge = res.elderAge || ''
+
+      // 解析 assessmentData
+      if (res.assessmentData) {
+        const formData = JSON.parse(res.assessmentData)
+        deserializeFormData(formData)
+      }
+    }
+  } catch (error) {
+    message.error('加载评估数据失败')
+  }
+}
+
+/** 根据长者ID加载评估数据 */
+const loadPerceptionByElderId = async (elderId: number) => {
+  try {
+    const res = await perceptionGetByElderId(elderId)
+    if (res && res.assessmentData) {
+      const formData = JSON.parse(res.assessmentData)
+      deserializeFormData(formData)
+    }
+  } catch (error) {
+    // 无历史数据,不处理
+  }
+}
+
+const form = reactive({
+  // 基本信息
+  assessor: '',
+  assessDate: '',
+
+  // 视力评分(0-4分)
+  visionScore: 0,
+
+  // 风险程度
+  riskLevel: '',
+
+  // 预防措施
+  preventiveMeasures: [],
+  preventiveMeasuresOther: '',
+
+  // 签名
+  familySignature: '',
+  familySignDate: ''
+})
+
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  if (formLoading.value) {
+    return
+  }
+  formLoading.value = true
+  // 提交请求
+  try {
+    const assessmentData = serializeFormData()
+    const tempParams = {
+      ...dataForm.value,
+      assessmentData: JSON.stringify(assessmentData),
+      totalScore: totalScore.value,
+      assessor: form.assessor,
+      assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''
+    }
+
+    if (dataForm.value.id) {
+      const res = await perceptionUpdate(tempParams)
+      if (res) {
+        message.success(t('common.updateSuccess'))
+        dialogVisible.value = false
+        // 发送操作成功的事件
+        emit('success')
+      }
+    } else {
+      const res = await perceptionCreate(tempParams)
+      if (res) {
+        message.success(t('common.createSuccess'))
+        dialogVisible.value = false
+        // 发送操作成功的事件
+        emit('success')
+      }
+    }
+  } finally {
+    setTimeout(() => {
+      formLoading.value = false
+    }, 500)
+  }
+}
+
+
+
+/** 重置表单 */
+const resetForm = () => {
+  dataForm.value = {
+    id: undefined,
+    idCard: '',
+    contractNumber: '', //档案号
+    elderName: '',//长者姓名
+    bedName: '', //床位号
+    elderAge: '', //年龄
+    elderSex: '', //性别
+    checkInTime: '', //入院日期
+    elderId: '',
+    tenantId: undefined
+  }
+  formRef.value?.resetFields()
+
+  // 重置感知觉与沟通评估表表单
+  resetPerceptionForm()
+}
+
+// 关闭表单
+const handleClosed = () => {
+  dialogVisible.value = false
+  resetForm()
+}
+
+/** 导出PDF */
+const handleExport = () => {
+  // 创建打印窗口
+  const printWindow = window.open('', '_blank')
+  if (!printWindow) {
+    message.error('请允许弹出窗口')
+    return
+  }
+
+  // 辅助函数:获取视力评分选项
+  const getVisionMark = (score) => {
+    const marks = [
+      { score: 0, text: '能看清书报上的标准字体(0分)' },
+      { score: 1, text: '能看清楚大字体(1分)' },
+      { score: 2, text: '视力有限,能辨认物体(2分)' },
+      { score: 3, text: '辨认物体有困难(3分)' },
+      { score: 4, text: '没有视力(4分)' }
+    ]
+    return marks.map(m => `${m.score === score ? '☑' : '☐'} ${m.text}`).join('<br>')
+  }
+
+  // 构建打印内容
+  const printContent = `
+    <!DOCTYPE html>
+    <html>
+    <head>
+      <meta charset="UTF-8">
+      <title>感知觉与沟通评估表 - ${dataForm.value.elderName || ''}</title>
+      <style>
+        @media print {
+          @page { size: A4 portrait; margin: 15mm; }
+        }
+        body {
+          font-family: 'SimSun', 'Microsoft YaHei', serif;
+          font-size: 11pt;
+          line-height: 1.5;
+          color: #333;
+        }
+        .header {
+          text-align: center;
+          margin-bottom: 20px;
+          border-bottom: 2px solid #333;
+          padding-bottom: 10px;
+        }
+        .header h1 {
+          font-size: 18pt;
+          margin: 0;
+          letter-spacing: 2px;
+        }
+        .info-section {
+          margin-bottom: 15px;
+          padding: 10px;
+          border: 1px solid #999;
+          background: #fafafa;
+        }
+        .info-row {
+          display: flex;
+          flex-wrap: wrap;
+          gap: 20px;
+        }
+        .info-item {
+          display: flex;
+          align-items: center;
+        }
+        .info-item .label {
+          font-weight: bold;
+          margin-right: 8px;
+          color: #555;
+        }
+        .info-item .value {
+          border-bottom: 1px solid #333;
+          min-width: 80px;
+          padding: 0 5px;
+          text-align: center;
+        }
+        .score-summary {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          padding: 10px 15px;
+          background: #f0f0f0;
+          border: 2px solid #333;
+          margin-bottom: 15px;
+        }
+        .total-score {
+          font-size: 14pt;
+          font-weight: bold;
+        }
+        .total-score .score-value {
+          color: #d9534f;
+          font-size: 18pt;
+        }
+        .risk-level {
+          font-size: 12pt;
+          font-weight: bold;
+          padding: 5px 15px;
+        }
+        .risk-none { color: #5cb85c; }
+        .risk-low { color: #f0ad4e; }
+        .risk-medium { color: #d9534f; }
+        .risk-high { color: #d9534f; background: #ffe6e6; padding: 5px 10px; border-radius: 3px; }
+
+        .assessment-table {
+          width: 100%;
+          border-collapse: collapse;
+          margin-bottom: 15px;
+        }
+        .assessment-table th, .assessment-table td {
+          border: 1px solid #333;
+          padding: 10px;
+          text-align: left;
+        }
+        .assessment-table th {
+          background: #e8e8e8;
+          font-weight: bold;
+          text-align: center;
+        }
+        .assessment-table .criteria-col {
+          width: 60%;
+        }
+        .assessment-table .score-col {
+          width: 15%;
+          text-align: center;
+        }
+        .assessment-table .select-col {
+          width: 25%;
+          text-align: center;
+        }
+        .assessment-table .criteria {
+          text-align: left;
+        }
+        .assessment-table .score {
+          text-align: center;
+          font-weight: bold;
+        }
+
+        .remark-section {
+          margin: 15px 0;
+          padding: 10px;
+          border: 1px solid #999;
+          background: #fafafa;
+        }
+        .remark-label {
+          font-weight: bold;
+        }
+
+        .risk-judgment-section {
+          margin: 15px 0;
+          padding: 10px;
+          border: 1px solid #999;
+        }
+        .risk-judgment-title {
+          font-weight: bold;
+          margin-bottom: 10px;
+        }
+        .risk-options {
+          display: flex;
+          flex-wrap: wrap;
+          gap: 20px;
+        }
+        .risk-option {
+          display: inline-block;
+        }
+
+        .measures-section {
+          margin: 15px 0;
+          border: 1px solid #999;
+        }
+        .measures-title {
+          font-weight: bold;
+          background: #e8e8e8;
+          padding: 8px 12px;
+          border-bottom: 1px solid #999;
+        }
+        .measures-content {
+          padding: 10px 12px;
+        }
+        .measure-item {
+          margin-bottom: 8px;
+          font-size: 10pt;
+        }
+        .measure-other {
+          margin-left: 10px;
+          border-bottom: 1px solid #333;
+          min-width: 200px;
+          display: inline-block;
+        }
+
+        .signature-section {
+          margin-top: 30px;
+          padding: 15px;
+          border: 1px solid #999;
+        }
+        .signature-row {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+        }
+        .signature-item {
+          display: flex;
+          align-items: center;
+          gap: 10px;
+        }
+        .signature-label {
+          font-weight: bold;
+        }
+        .signature-value {
+          border-bottom: 1px solid #333;
+          min-width: 150px;
+          height: 25px;
+        }
+
+        .note-section {
+          margin-top: 20px;
+          padding: 15px;
+          border: 1px solid #999;
+          background: #fafafa;
+        }
+        .note-title {
+          font-weight: bold;
+          margin-bottom: 10px;
+        }
+        .note-content {
+          font-size: 10pt;
+          line-height: 1.8;
+        }
+        .note-content p {
+          margin: 5px 0;
+        }
+        .note-content .indent {
+          margin-left: 20px;
+        }
+      </style>
+    </head>
+    <body>
+      <div class="header">
+        <h1>感知觉与沟通评估表</h1>
+      </div>
+
+      <div class="info-section">
+        <div class="info-row">
+          <div class="info-item">
+            <span class="label">长者姓名:</span>
+            <span class="value">${dataForm.value.elderName || ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">档案号:</span>
+            <span class="value">${dataForm.value.contractNumber || ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">床位号:</span>
+            <span class="value">${dataForm.value.bedName || ''}</span>
+          </div>
+        </div>
+        <div class="info-row" style="margin-top: 10px;">
+          <div class="info-item">
+            <span class="label">评估日期:</span>
+            <span class="value">${form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">评估人:</span>
+            <span class="value">${form.assessor || ''}</span>
+          </div>
+        </div>
+      </div>
+
+      <div class="score-summary">
+        <div class="total-score">
+          总得分:<span class="score-value">${totalScore.value}</span> / 4分
+        </div>
+      </div>
+
+      <!-- 评估表格 -->
+      <table class="assessment-table">
+        <thead>
+          <tr>
+            <th class="criteria-col">评估准则</th>
+            <th class="score-col">分值</th>
+            <th class="select-col">选择</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr>
+            <td class="criteria">能看清书报上的标准字体</td>
+            <td class="score">0分</td>
+            <td class="select">${form.visionScore === 0 ? '☑' : '☐'}</td>
+          </tr>
+          <tr>
+            <td class="criteria">能看清楚大字体;但看不清书报上的标准字体</td>
+            <td class="score">1分</td>
+            <td class="select">${form.visionScore === 1 ? '☑' : '☐'}</td>
+          </tr>
+          <tr>
+            <td class="criteria">视力有限;看不清报纸大标题;但能辨认物体</td>
+            <td class="score">2分</td>
+            <td class="select">${form.visionScore === 2 ? '☑' : '☐'}</td>
+          </tr>
+          <tr>
+            <td class="criteria">辨认物体有困难;但眼睛能跟随物体移动;只能看到光、颜色和形状</td>
+            <td class="score">3分</td>
+            <td class="select">${form.visionScore === 3 ? '☑' : '☐'}</td>
+          </tr>
+          <tr>
+            <td class="criteria">没有视力;眼睛不能跟随物体移动</td>
+            <td class="score">4分</td>
+            <td class="select">${form.visionScore === 4 ? '☑' : '☐'}</td>
+          </tr>
+        </tbody>
+      </table>
+
+      <!-- 备注 -->
+      <div class="remark-section">
+        <span class="remark-label">备注:</span>
+        <span>若平日戴老花镜或近视镜,应在佩戴眼镜的情况下评估。</span>
+      </div>
+
+      <!-- 风险程度判断 -->
+      <div class="risk-judgment-section">
+        <div class="risk-judgment-title">风险程度判断:</div>
+        <div class="risk-options">
+          <span class="risk-option">${form.riskLevel === 'none' ? '☑' : '☐'} 无风险:0分</span>
+          <span class="risk-option">${form.riskLevel === 'low' ? '☑' : '☐'} 低风险:1分</span>
+          <span class="risk-option">${form.riskLevel === 'medium' ? '☑' : '☐'} 中风险:2分</span>
+          <span class="risk-option">${form.riskLevel === 'high' ? '☑' : '☐'} 高风险:≥3分</span>
+        </div>
+      </div>
+
+      <!-- 预防措施 -->
+      <div class="measures-section">
+        <div class="measures-title">预防措施</div>
+        <div class="measures-content">
+          <div class="measure-item">${form.preventiveMeasures?.includes('patrol') ? '☑' : '☐'} 加强巡查</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('food') ? '☑' : '☐'} 合理食物</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('expression') ? '☑' : '☐'} 观察表情</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('medication') ? '☑' : '☐'} 药物统一管控</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('feeding') ? '☑' : '☐'} 严格协助进食操作规程</div>
+          <div class="measure-item">${form.preventiveMeasures?.includes('card') ? '☑' : '☐'} 设立床头卡标识</div>
+          <div class="measure-item">
+            ${form.preventiveMeasures?.includes('other') ? '☑' : '☐'} 其他
+            ${form.preventiveMeasures?.includes('other') ? '<span class="measure-other">' + (form.preventiveMeasuresOther || '') + '</span>' : ''}
+          </div>
+        </div>
+      </div>
+
+      <!-- 签名区域 -->
+      <div class="signature-section">
+        <div class="signature-row">
+          <div class="signature-item">
+            <span class="signature-label">家属/监护人签名:</span>
+            <span class="signature-value">${form.familySignature || ''}</span>
+          </div>
+        </div>
+      </div>
+
+      <!-- 说明 -->
+      <div class="note-section">
+        <div class="note-title">说明:</div>
+        <div class="note-content">
+          <p>1. 新入住长者应在长者入住24小时内完成首次评估;</p>
+          <p>2. 定期评估:</p>
+          <p class="indent">(1)认知照护专区:高风险1个月评估一次,中风险、低风险3个月评估一次;</p>
+          <p class="indent">(2)非认知照护专区:高风险1个月评估一次,中风险3个月评估一次,低风险6个月评估一次;</p>
+          <p>3. 当长者身体发生变化者,应及时进行动态评估。</p>
+        </div>
+      </div>
+    </body>
+    </html>
+  `
+
+  // 写入内容并打印
+  printWindow.document.write(printContent)
+  printWindow.document.close()
+
+  // 延迟打印,确保样式加载完成
+  setTimeout(() => {
+    printWindow.print()
+  }, 500)
+}
+
+</script>
+
+<style scoped lang="scss">
+.mmse-form {
+  max-width: 1200px;
+  margin: 0 auto;
+  background: #fff;
+
+  .form-title {
+    text-align: center;
+    font-size: 24px;
+    font-weight: bold;
+    margin-bottom: 20px;
+  }
+
+
+
+  .info-row {
+    display: flex;
+    gap: 40px;
+    width: 100%;
+    flex-direction: row;
+    align-items: center;
+    margin-bottom: 10px;
+
+    .info-item {
+      display: flex;
+      align-items: center;
+      gap: 8px;
+
+      .label {
+        width: 82px;
+        text-align: right;
+        margin-right: 4px;
+        white-space: nowrap;
+      }
+    }
+  }
+
+
+  .form-body {
+    border: 1px solid #333;
+    padding: 15px;
+  }
+
+  .section {
+    margin-bottom: 20px;
+
+    &:last-child {
+      margin-bottom: 0;
+    }
+
+    .section-title {
+      font-weight: bold;
+      margin-bottom: 10px;
+    }
+  }
+
+  .form-item {
+    display: flex;
+    align-items: center;
+    margin-bottom: 12px;
+    flex-wrap: wrap;
+    gap: 8px;
+
+    .item-number {
+      font-weight: bold;
+      min-width: 25px;
+    }
+
+    .item-label {
+      white-space: nowrap;
+      min-width: fit-content;
+    }
+
+  }
+
+  .other-input {
+    width: 200px;
+    margin-left: 10px;
+  }
+
+  // 调整 Element Plus 组件样式
+  :deep(.el-input__inner) {
+    height: 28px;
+    line-height: 28px;
+    border-top: none;
+    border-left: none;
+    border-right: none;
+    border-radius: 0;
+    padding: 0 4px;
+
+    &:focus {
+      border-color: #409eff;
+    }
+  }
+
+
+  :deep(.el-checkbox__label),
+  :deep(.el-radio__label) {
+    padding-left: 4px;
+  }
+}
+.row{
+  margin-bottom: 12px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  text{
+    text-align: right;
+    margin-right: 4px;
+    width: 82px;
+  }
+}
+
+// 感知觉与沟通评估表 特有样式
+.total-score-section {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  margin-bottom: 20px;
+
+  .total-score {
+    display: flex;
+    align-items: baseline;
+    gap: 4px;
+
+    .score-label {
+      font-size: 16px;
+      font-weight: bold;
+    }
+
+    .score-value {
+      font-size: 28px;
+      font-weight: bold;
+      color: #409eff;
+    }
+
+    .score-max {
+      font-size: 14px;
+      color: #909399;
+    }
+  }
+
+  .risk-level {
+    font-size: 16px;
+    font-weight: bold;
+    padding: 8px 16px;
+    border-radius: 4px;
+
+    &.risk-none {
+      color: #67c23a;
+      background: #f0f9eb;
+    }
+
+    &.risk-low {
+      color: #e6a23c;
+      background: #fdf6ec;
+    }
+
+    &.risk-medium {
+      color: #f56c6c;
+      background: #fef0f0;
+    }
+
+    &.risk-high {
+      color: #f56c6c;
+      background: #fef0f0;
+      border: 1px solid #f56c6c;
+    }
+  }
+}
+
+.assessment-table {
+  width: 100%;
+  border-collapse: collapse;
+  margin-bottom: 20px;
+
+  table {
+    width: 100%;
+    border: 1px solid #333;
+
+    th, td {
+      border: 1px solid #333;
+      padding: 12px;
+      text-align: left;
+    }
+
+    th {
+      background: #f5f7fa;
+      font-weight: bold;
+      text-align: center;
+    }
+
+    .criteria-col {
+      width: 60%;
+    }
+
+    .score-col {
+      width: 15%;
+      text-align: center;
+    }
+
+    .select-col {
+      width: 25%;
+      text-align: center;
+    }
+
+    .criteria {
+      text-align: left;
+    }
+
+    .score {
+      text-align: center;
+      font-weight: bold;
+    }
+
+    .select {
+      text-align: center;
+
+      :deep(.el-radio) {
+        margin-right: 0;
+      }
+    }
+  }
+}
+
+.remark-section {
+  margin: 15px 0;
+  padding: 12px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .remark-label {
+    font-weight: bold;
+    color: #606266;
+  }
+
+  .remark-text {
+    color: #606266;
+  }
+}
+
+.risk-judgment-section {
+  margin: 20px 0;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .risk-judgment-title {
+    font-weight: bold;
+    font-size: 16px;
+    margin-bottom: 12px;
+    color: #303133;
+  }
+
+  .risk-options {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 20px;
+
+    :deep(.el-radio) {
+      margin-right: 0;
+    }
+  }
+}
+
+.preventive-section {
+  margin: 20px 0;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .preventive-title {
+    font-weight: bold;
+    font-size: 16px;
+    margin-bottom: 12px;
+    color: #303133;
+  }
+
+  .preventive-options {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 15px;
+
+    :deep(.el-checkbox) {
+      margin-right: 20px;
+      margin-bottom: 8px;
+    }
+
+    .other-input {
+      width: 200px;
+      margin-left: 10px;
+    }
+  }
+}
+
+.signature-section {
+  margin: 20px 0;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .signature-row {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    gap: 20px;
+  }
+
+  .signature-item {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+
+    &.date-item {
+      :deep(.el-date-picker) {
+        width: 150px;
+      }
+    }
+  }
+
+  .signature-label {
+    font-weight: bold;
+    white-space: nowrap;
+  }
+
+  .signature-input {
+    width: 150px;
+  }
+
+  .date-picker {
+    width: 150px;
+  }
+}
+
+.note-section {
+  margin-top: 20px;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .note-title {
+    font-weight: bold;
+    font-size: 16px;
+    margin-bottom: 12px;
+    color: #303133;
+  }
+
+  .note-content {
+    font-size: 13px;
+    line-height: 1.8;
+    color: #606266;
+
+    p {
+      margin: 5px 0;
+    }
+
+    .indent {
+      margin-left: 20px;
+    }
+  }
+}
+</style>

+ 327 - 0
src/views/social-worker/assessment/PerceptionAndCommunication/index.vue

@@ -0,0 +1,327 @@
+<template>
+  <ContentWrap>
+    <!-- 保护性约束观察记录表 -->
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="110px"
+    >
+      <el-form-item label="长者姓名">
+        <el-input
+          v-model="queryParams.elderName"
+          placeholder="长者姓名"
+          class="!w-240px"
+          clearable
+        />
+      </el-form-item>
+
+
+
+      <el-form-item label="记录日期">
+        <el-date-picker
+          size="default"
+          ref="selectRef"
+          class="!w-240px"
+          v-model="queryParams.recordDate"
+          type="daterange"
+          :clearable="true"
+          :editable="false"
+          placeholder="选择记录日期"
+          value-format="YYYY-MM-DD"
+          format="YYYY-MM-DD"
+          date-format="YYYY-MM-DD"
+        />
+      </el-form-item>
+
+      <el-form-item>
+        <el-button @click="handleQuery" style="margin-left: 2vw"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <div class="mb-10px">
+
+      <ButtonAdd @click="openForm(undefined)"  />
+      <!--      <el-button @click="inputH" type="success"><Icon icon="fa:cloud-upload" :size="16" class="mr-1"/>导入</el-button>-->
+      <ButtonImport @click="handleImportCard"  />
+
+
+    </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">
+          {{
+            scope.$index + (queryParams.pageNo * queryParams.pageSize - queryParams.pageSize) + 1
+          }}
+        </template>
+      </el-table-column>
+
+
+      <el-table-column prop="elderName" header-align="center" align="center" label="长者姓名" min-width="150" show-overflow-tooltip/>
+      <el-table-column prop="bedName" header-align="center" align="center" label="床位号" min-width="200" show-overflow-tooltip/>
+      <el-table-column prop="recordDate" header-align="center" align="center" label="记录日期" min-width="200" show-overflow-tooltip/>
+
+      <el-table-column prop="creator" header-align="center" align="center" label="记录人" min-width="200" show-overflow-tooltip/>
+
+
+      <el-table-column label="操作" align="center" width="200" >
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            @click="openFormEdit(scope.row, scope.row.id)"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="warning"
+            @click="openFormDetail(scope.row,scope.row.id)"
+          >
+            详情
+          </el-button>
+          <el-button
+            link
+            type="danger"
+            @click="openClose(scope.row)"
+          >
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+  <AddForm ref="formRef" @success="getList" />
+
+  <!-- 通用批量导出弹窗 -->
+  <BatchExportDialog
+    :show="showBatchExport"
+    :title="exportConfig.title"
+    :loading="exportLoading"
+    :batch-min="exportConfig.batchMin"
+    :batch-max="exportConfig.batchMax"
+    :count-min="exportConfig.countMin"
+    :count-max="exportConfig.countMax"
+    :default-batch="exportConfig.defaultBatch"
+    :default-count="exportConfig.defaultCount"
+    :description="exportConfig.description"
+    @update:show="showBatchExport = $event"
+    @confirm="handleBatchExport"
+    @cancel="showBatchExport = false"
+  />
+
+
+  <Import
+    ref="importRef"
+    @success="getList"
+    :config="{
+      title: '导入',
+      downloadUrl: 'elderly-service-order/get-import-template',
+      excelTempName: '居家工单-【导入】模板',
+      importUrl: '/elderly-service-order/import',
+      failExportUrl: '',
+    }"
+  />
+
+</template>
+
+<script setup lang="ts">
+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 {formatTimestamp, getCurrentMonthRange} from "@/utils/dateUtil";
+import Import from "@/components/ImportFile/index.vue";
+import {restraintCreatePage, restraintDelete} from "@/api/elderly/nursing/keep-fit";
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+const userStore = useUserStore()
+const loading = ref(true) // 列表的加载中
+const detailRef = ref()
+const importRef = ref()
+const total = ref(0) // 列表的总页数
+const list = ref([]) // 列表的数据
+
+// 状态管理
+const showBatchExport = ref(false)
+const exportConfig = ref({
+  title: '',
+  batchMin: 1,
+  batchMax: 999,
+  countMin: 1,
+  countMax: 200,
+  defaultBatch: 1,
+  defaultCount: 200,
+  description: [] as string[]
+})
+const exportLoading = ref(false)
+
+let queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  elderName: '',
+  creator: '',
+  recordDate: getCurrentMonthRange(),
+  tenantIds: userStore.orgTenantId
+})
+const queryFormRef = ref() // 搜索的表单
+
+const inputH = () => {
+  importRef.value.open(queryParams.tenantIds[0])
+}
+// 打开导出弹窗
+const handleImportCard = async () => {
+
+  // showBatchExport.value = true
+}
+
+// 处理批量导出
+const handleBatchExport = async (batch: number, count: number) => {
+  exportLoading.value = true
+  console.log(batch,count)
+  // try {
+  //   let queryParams = {
+  //     pageNo: batch,
+  //     pageSize: count,
+  //     tenantId: userStore.orgTenantId[0]
+  //   }
+  //   const list = await careRecordsPage(queryParams)
+  //   if (list.length <= 0) {
+  //     message.error('暂无数据可以导出!')
+  //     return
+  //   }
+  //   const headers = [
+  //     { key: 'organizationName', title: '机构名称' },
+  //     { key: 'visitName', title: '姓名' },
+  //     { key: 'visitPhone', title: '手机号' },
+  //     { key: 'visitDate', title: '预约时间' },
+  //     { key: 'accompanyCount', title: '陪同人数' },
+  //     { key: 'reason', title: '理由' }
+  //   ]
+  //   exportWithExpandedObjectArrays(list, headers, `医疗护理记录${formatToDateTime()}.xlsx`, '医疗护理记录')
+  // } catch (_) {}
+
+}
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    //let queryP = {...queryParams,discoveryTime:queryParams.discoveryTime?[queryParams.discoveryTime[0]+" 00:00:00",queryParams.discoveryTime[1]+" 23:59:59"]:null}
+    const data = await restraintCreatePage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = async () => {
+  if (!queryFormRef.value) return
+  const valid = await queryFormRef.value.validate()
+  if (!valid) return
+  queryParams.pageNo = 1
+  await getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryParams.elderName = ''
+  queryParams.creator = ''
+  queryParams.tenantIds = userStore.orgTenantId
+  queryParams.recordDate= getCurrentMonthRange()
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+/** 添加/修改操作 */
+const formRef = ref()
+const openForm = (id?: number) => {
+  if(queryParams.tenantIds.length == 0 || queryParams.tenantIds.length > 1){
+    message.error('新增只能选择一个机构')
+    return
+  }
+  formRef.value.open(queryParams.tenantIds[0], id,false)
+}
+
+const editRef = ref()
+const openFormEdit = (row: any = {}, id?: number) => {
+  formRef.value.open(row.tenantId, id,false)
+}
+
+
+const openFormDetail = (row: any = {},id?: number) => {
+  formRef.value.open(row.tenantId,id,true)
+}
+
+
+
+
+
+const openClose = async (item) => {
+  try {
+    console.log("任务ID",item)
+    const res = await message.confirm('确定要删除吗?', '提示')
+    if (res == 'confirm') {
+      // 发起
+      try {
+        const res = await restraintDelete(item.id)
+        if (res){
+          message.success(t('common.updateSuccess'))
+        }
+      }catch(err) {}
+    }
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 取消按钮操作 */
+const cancelDelete = async (id: number) => {
+  try {
+    // 取消的二次确认
+    await message.cancelConfirm()
+    // 发起取消
+    // await elderlyBakDel(id)
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+const route = useRoute()
+/** 初始化 **/
+onMounted(() => {
+  if(route.query && route.query.elderName){
+    queryParams.elderName = route.query.elderName as string
+  }
+  getList()
+})
+
+// 表头格式
+const tableHeaderColor = ({ rowIndex }: any) => {
+  if (rowIndex === 0) {
+    return {
+      backgroundColor: '#f8f8f9',
+      color: '#666666',
+      fontWeight: 'bold'
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss"></style>

+ 944 - 0
src/views/social-worker/assessment/SAS/AddForm.vue

@@ -0,0 +1,944 @@
+<template>
+  <el-drawer
+    v-model="dialogVisible"
+    :title="title"
+    resizable
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    :destroy-on-close="true"
+    size="70%"
+    :before-close="handleClosed"
+  >
+
+    <div class="psychological-social-form">
+      <h1 class="form-title">长者心理社交情况</h1>
+        <!-- 基本信息 -->
+        <el-row :gutter="40">
+          <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+            <text>长者姓名</text>
+            <search-the-elderly ref="selectElderRef" :disabled="isDetail" @update_elder="elderUp" v-model="dataForm.elderName" :tId="dataForm.tenantId"/>
+          </el-col>
+          <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+            <text>档案号</text>
+            <el-input v-if="!isDetail" v-model="dataForm.fileNumber" disabled />
+            <el-text v-else disabled="">{{dataForm.fileNumber}}</el-text>
+          </el-col>
+        </el-row>
+        <el-row :gutter="40">
+          <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+            <text>入院日期</text>
+            <el-input v-if="!isDetail" :model-value="dayjs(dataForm.checkInTime).format('YYYY-MM-DD')=='Invalid Date'?'':dayjs(dataForm.checkInTime).format('YYYY-MM-DD')" disabled />
+            <el-text v-else disabled="">{{dayjs(dataForm.checkInTime).format('YYYY-MM-DD')}}</el-text>
+          </el-col>
+          <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+            <text>床位号</text>
+            <el-input v-if="!isDetail" v-model="dataForm.bedName" disabled />
+            <el-text v-else disabled="">{{dataForm.bedName}}</el-text>
+          </el-col>
+        </el-row>
+
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>评估人签字</text>
+          <el-input v-model="form.assessor"  />
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>评估日期</text>
+          <el-date-picker v-model="form.assessDate" type="date" style="width: 100%;"/>
+
+        </el-col>
+      </el-row>
+
+        <!-- 表单内容区域 -->
+        <div class="form-body">
+          <!-- (一) 经济状况 -->
+          <div class="section">
+            <div class="section-title">(一)经济状况:</div>
+
+            <div class="form-item">
+              <span class="item-number">1.</span>
+              <span class="item-label">收入来源:</span>
+              <el-checkbox-group v-model="form.incomeSource" class="inline-checkbox-group">
+                <el-checkbox v-for="opt in incomeSourceOptions" :key="opt.value" :value="opt.value">
+                  {{ opt.label }}
+                </el-checkbox>
+              </el-checkbox-group>
+              <template v-if="form.incomeSource.includes('其他')">
+                <el-input v-model="form.incomeSourceOther" class="other-input" />
+              </template>
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">2.</span>
+              <span class="item-label">财政处理:</span>
+              <el-checkbox-group v-model="form.financialManagement" class="inline-checkbox-group">
+                <el-checkbox v-for="opt in financialManagementOptions" :key="opt.value" :value="opt.value">
+                  {{ opt.label }}
+                </el-checkbox>
+              </el-checkbox-group>
+              <template v-if="form.financialManagement.includes('其他')">
+                <el-input v-model="form.financialManagementOther" class="other-input" />
+              </template>
+            </div>
+          </div>
+
+          <!-- (二) 婚姻家庭状况 -->
+          <div class="section">
+            <div class="section-title">(二)婚姻家庭状况:</div>
+
+            <div class="form-item">
+              <span class="item-number">3.</span>
+              <span class="item-label">婚姻状况:</span>
+              <el-radio-group v-model="form.maritalStatus" class="inline-radio-group">
+                <el-radio v-for="opt in maritalStatusOptions" :key="opt.value" :value="opt.value">
+                  {{ opt.label }}
+                </el-radio>
+              </el-radio-group>
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">4.</span>
+              <span class="item-label">近亲家属:</span>
+              <span class="sub-item">儿子<el-input v-model="form.familyMembers.son" class="tiny-input" />名</span>
+              <span class="sub-item">女儿<el-input v-model="form.familyMembers.daughter" class="tiny-input" />名</span>
+              <span class="sub-item">女婿<el-input v-model="form.familyMembers.sonInLaw" class="tiny-input" />名</span>
+              <span class="sub-item">儿媳<el-input v-model="form.familyMembers.daughterInLaw" class="tiny-input" />名</span>
+              <span class="sub-item">孙子女<el-input v-model="form.familyMembers.grandChildren" class="tiny-input" />名</span>
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">5.</span>
+              <span class="item-label">主要照顾亲属:</span>
+              <span class="sub-item">姓名:<el-input v-model="form.mainCaregiver.name" class="short-input" /></span>
+              <span class="sub-item">关系:<el-input v-model="form.mainCaregiver.relation" class="short-input" /></span>
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">6.</span>
+              <span class="item-label">入院前居住情况:</span>
+              <el-radio-group v-model="form.preAdmissionLiving" class="inline-radio-group">
+                <el-radio v-for="opt in preAdmissionLivingOptions" :key="opt.value" :value="opt.value">
+                  {{ opt.label }}
+                </el-radio>
+              </el-radio-group>
+              <template v-if="form.preAdmissionLiving === '其他'">
+                <el-input v-model="form.preAdmissionLivingOther" class="other-input" />
+              </template>
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">7.</span>
+              <span class="item-label">家人/亲友到访情况:</span>
+              <el-radio-group v-model="form.familyVisitFrequency" class="inline-radio-group">
+                <el-radio v-for="opt in familyVisitFrequencyOptions" :key="opt.value" :value="opt.value">
+                  {{ opt.label }}
+                </el-radio>
+              </el-radio-group>
+              <template v-if="form.familyVisitFrequency === 'not_applicable'">
+                <el-input v-model="form.familyVisitFrequencyOther" class="other-input" />
+              </template>
+            </div>
+          </div>
+
+          <!-- (三) 健康状况 -->
+          <div class="section">
+            <div class="section-title">(三)健康状况:</div>
+
+            <div class="form-item">
+              <span class="item-number">8.</span>
+              <span class="item-label">健康状况:</span>
+              <el-radio-group v-model="form.healthStatus" class="inline-radio-group">
+                <el-radio v-for="opt in healthStatusOptions" :key="opt.value" :value="opt.value">
+                  {{ opt.label }}
+                </el-radio>
+              </el-radio-group>
+              <template v-if="form.healthStatus === 'poor'">
+                <span class="sub-label">(请注明病类:</span>
+                <el-input v-model="form.healthStatusDisease" class="short-input" />
+                <span class="sub-label">)</span>
+              </template>
+            </div>
+          </div>
+
+          <!-- (四) 过往史 -->
+          <div class="section">
+            <div class="section-title">(四)过往史:</div>
+
+            <div class="form-item">
+              <span class="item-number">9.</span>
+              <span class="item-label">教育程度:</span>
+              <el-radio-group v-model="form.educationLevel" class="inline-radio-group">
+                <el-radio v-for="opt in educationLevelOptions" :key="opt.value" :value="opt.value">
+                  {{ opt.label }}
+                </el-radio>
+              </el-radio-group>
+              <template v-if="form.educationLevel === '其他'">
+                <el-input v-model="form.educationLevelOther" class="other-input" />
+              </template>
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">10.</span>
+              <span class="item-label">政治面貌:</span>
+              <el-input v-model="form.politicalStatus" class="medium-input" />
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">11.</span>
+              <span class="item-label">以往职业:</span>
+              <el-input v-model="form.previousOccupation" class="medium-input" />
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">12.</span>
+              <span class="item-label">以前是否入住过养老院:</span>
+              <el-radio-group v-model="form.hasStayedInNursingHome" class="inline-radio-group">
+                <el-radio v-for="opt in hasStayedInNursingHomeOptions" :key="opt.value" :value="opt.value">
+                  {{ opt.label }}
+                </el-radio>
+              </el-radio-group>
+              <template v-if="form.hasStayedInNursingHome === '有'">
+                <el-input v-model="form.nursingHomeStayDetail" class="other-input" />
+              </template>
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">13.</span>
+              <span class="item-label">来老人院的原因:</span>
+              <el-input v-model="form.reasonForAdmission" class="long-input" />
+            </div>
+          </div>
+
+          <!-- (五) 社交状况 -->
+          <div class="section">
+            <div class="section-title">(五)社交状况:</div>
+
+            <div class="form-item">
+              <span class="item-number">14.</span>
+              <span class="item-label">院内好友:</span>
+              <el-input v-model="form.friendsInHome" class="long-input" />
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">15.</span>
+              <span class="item-label">社交喜好:</span>
+              <el-radio-group v-model="form.socialPreference" class="inline-radio-group">
+                <el-radio v-for="opt in socialPreferenceOptions" :key="opt.value" :value="opt.value">
+                  {{ opt.label }}
+                </el-radio>
+              </el-radio-group>
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">16.</span>
+              <span class="item-label">心情不好时的反应:</span>
+              <el-input v-model="form.badMoodReaction" class="long-input" />
+            </div>
+
+            <div class="form-item hobby-item">
+              <div class="row">
+                <span class="item-number">17. </span>
+                <span class="item-label">兴趣爱好:</span>
+              </div>
+
+              <el-checkbox-group v-model="form.hobbies" class="hobby-checkbox-group">
+                <el-checkbox v-for="opt in hobbyOptions" :key="opt.value" :value="opt.value">
+                  {{ opt.label }}
+                </el-checkbox>
+              </el-checkbox-group>
+              <template v-if="form.hobbies.includes('其他')">
+                <div class="hobby-other">
+                  <span class="sub-label">(请注明:</span>
+                  <el-input v-model="form.hobbiesOther" class="short-input" />
+                  <span class="sub-label">)</span>
+                </div>
+              </template>
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">18.</span>
+              <span class="item-label">特别喜欢/重视的东西或节日等:</span>
+              <el-input v-model="form.specialFestival" class="long-input" />
+            </div>
+
+            <div class="form-item">
+              <span class="item-number">19.</span>
+              <span class="item-label">其他特别的事项记录:</span>
+              <el-input v-model="form.otherSpecialNotes" class="long-input" />
+            </div>
+          </div>
+        </div>
+
+    </div>
+
+    <template #footer>
+      <el-button @click="handleClosed">关闭</el-button>
+      <el-button style="margin-left: 22px;margin-right: 30px" v-loading="formLoading" type="primary" v-show="!isDetail" @click="submitForm">确定</el-button>
+    </template>
+
+  </el-drawer>
+</template>
+
+<script lang="ts" setup>
+import { computed, ref } from 'vue'
+import {FormRules} from 'element-plus'
+import { useMediaQuery } from '@vueuse/core'
+const { isValidNumberDis } = useValidator()
+import { useValidator } from '@/hooks/web/useValidator'
+import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
+import {tableHeaderColor} from "@/utils/table";
+import {InfoFilled} from "@element-plus/icons-vue";
+import {restraintCreate, restraintGetById, restraintUpdate} from "@/api/elderly/nursing/keep-fit";
+import {psychologicalSocialCreate, psychologicalSocialUpdate, psychologicalSocialGetById, psychologicalSocialGetByElderId} from "@/api/elderly/assessment/psychological-social";
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+const discountAmount = ref()
+const discount = ref()
+const selectBedRef = ref()
+const title = ref('')
+const dialogVisible = ref(false) // 弹窗
+const loading = ref(false) // 弹窗
+const formRef = ref() // 表单 Ref
+const radio = ref(1) // 表单 Ref
+const selectElderRef = ref() // 表单 Ref
+const isDetail = ref(false) // 是否详情打开
+const jsonDataList = ref([])
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const userStore = useUserStore()
+
+
+
+
+let dataForm = ref({
+  // 表单字段
+  id: undefined,
+  idCard: '',
+  fileNumber: '', //档案号
+  elderName: '',//长者姓名
+  bedName: '', //床位号
+  elderAge: '', //年龄
+  elderSex: '', //性别
+  checkInTime: '', //入院日期
+  elderId: '',
+  recordDate: dayjs().format('YYYY-MM-DD'), // 记录时间,默认当前时间
+  items: [], //时间数组
+  restraintReason: [], //约束原因
+  restraintType: [], //约束类型
+  tenantId: undefined
+})
+// 表单规则
+const dataRule = reactive<FormRules>({
+  recordTime: [{ required: true, message: '记录时间不能为空', trigger: 'blur' }],
+  elderId: [{ required: true, message: '长者姓名不能为空', trigger: 'blur' }],
+  phone: [{ required: true, message: '联系方式不能为空', trigger: 'blur' },
+    { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' }],
+  sourceChannel: [{ required: true, message: '来源渠道不能为空', trigger: 'blur' }],
+  elderId: [{ required: true, message: '长者姓名不能为空', trigger: 'blur' }],
+
+})
+
+
+
+const elderUp = (e) => {
+  dataForm.value.elderName = e.elderName
+  dataForm.value.elderId = e.id
+  dataForm.value.elderSex = e.elderSex === 1 ? '男' : '女'
+  dataForm.value.bedName = e.bedName||''
+  dataForm.value.checkInTime = e.checkInTime
+  dataForm.value.fileNumber = e.fileNumber
+  dataForm.value.elderAge = e.elderAge
+  dataForm.value.nurseLevelName = e.nurseLevelName
+
+}
+
+// ========== 心理社交情况表单序列化方法 ==========
+
+/** 将表单数据序列化为 JSON 对象 */
+const serializeFormData = () => {
+  return {
+    // 基本信息
+    assessor: form.assessor || '',
+    assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : '',
+
+    // (一) 经济状况
+    incomeSource: form.incomeSource || [],
+    incomeSourceOther: form.incomeSourceOther || '',
+    financialManagement: form.financialManagement || [],
+    financialManagementOther: form.financialManagementOther || '',
+
+    // (二) 婚姻家庭状况
+    maritalStatus: form.maritalStatus || '',
+    familyMembers: { ...form.familyMembers },
+    mainCaregiver: { ...form.mainCaregiver },
+    preAdmissionLiving: form.preAdmissionLiving || '',
+    preAdmissionLivingOther: form.preAdmissionLivingOther || '',
+    familyVisitFrequency: form.familyVisitFrequency || '',
+    familyVisitFrequencyOther: form.familyVisitFrequencyOther || '',
+
+    // (三) 健康状况
+    healthStatus: form.healthStatus || '',
+    healthStatusDisease: form.healthStatusDisease || '',
+
+    // (四) 过往史
+    educationLevel: form.educationLevel || '',
+    educationLevelOther: form.educationLevelOther || '',
+    politicalStatus: form.politicalStatus || '',
+    previousOccupation: form.previousOccupation || '',
+    hasStayedInNursingHome: form.hasStayedInNursingHome || '',
+    nursingHomeStayDetail: form.nursingHomeStayDetail || '',
+    reasonForAdmission: form.reasonForAdmission || '',
+
+    // (五) 社交状况
+    friendsInHome: form.friendsInHome || '',
+    socialPreference: form.socialPreference || '',
+    badMoodReaction: form.badMoodReaction || '',
+    hobbies: form.hobbies || [],
+    hobbiesOther: form.hobbiesOther || '',
+    specialFestival: form.specialFestival || '',
+    otherSpecialNotes: form.otherSpecialNotes || ''
+  }
+}
+
+/** 将 JSON 对象反序列化为表单数据 */
+const deserializeFormData = (formData: Record<string, any>) => {
+  if (!formData) return
+
+  // 基本信息
+  form.assessor = formData.assessor || ''
+  form.assessDate = formData.assessDate ? dayjs(formData.assessDate).toDate() : ''
+
+  // (一) 经济状况
+  form.incomeSource = formData.incomeSource || []
+  form.incomeSourceOther = formData.incomeSourceOther || ''
+  form.financialManagement = formData.financialManagement || []
+  form.financialManagementOther = formData.financialManagementOther || ''
+
+  // (二) 婚姻家庭状况
+  form.maritalStatus = formData.maritalStatus || ''
+  form.familyMembers = {
+    son: formData.familyMembers?.son || '',
+    daughter: formData.familyMembers?.daughter || '',
+    sonInLaw: formData.familyMembers?.sonInLaw || '',
+    daughterInLaw: formData.familyMembers?.daughterInLaw || '',
+    grandChildren: formData.familyMembers?.grandChildren || ''
+  }
+  form.mainCaregiver = {
+    name: formData.mainCaregiver?.name || '',
+    relation: formData.mainCaregiver?.relation || ''
+  }
+  form.preAdmissionLiving = formData.preAdmissionLiving || ''
+  form.preAdmissionLivingOther = formData.preAdmissionLivingOther || ''
+  form.familyVisitFrequency = formData.familyVisitFrequency || ''
+  form.familyVisitFrequencyOther = formData.familyVisitFrequencyOther || ''
+
+  // (三) 健康状况
+  form.healthStatus = formData.healthStatus || ''
+  form.healthStatusDisease = formData.healthStatusDisease || ''
+
+  // (四) 过往史
+  form.educationLevel = formData.educationLevel || ''
+  form.educationLevelOther = formData.educationLevelOther || ''
+  form.politicalStatus = formData.politicalStatus || ''
+  form.previousOccupation = formData.previousOccupation || ''
+  form.hasStayedInNursingHome = formData.hasStayedInNursingHome || ''
+  form.nursingHomeStayDetail = formData.nursingHomeStayDetail || ''
+  form.reasonForAdmission = formData.reasonForAdmission || ''
+
+  // (五) 社交状况
+  form.friendsInHome = formData.friendsInHome || ''
+  form.socialPreference = formData.socialPreference || ''
+  form.badMoodReaction = formData.badMoodReaction || ''
+  form.hobbies = formData.hobbies || []
+  form.hobbiesOther = formData.hobbiesOther || ''
+  form.specialFestival = formData.specialFestival || ''
+  form.otherSpecialNotes = formData.otherSpecialNotes || ''
+}
+
+/** 重置表单数据 */
+const resetPsychologicalForm = () => {
+  form.assessor = ''
+  form.assessDate = ''
+
+  // (一) 经济状况
+  form.incomeSource = []
+  form.incomeSourceOther = ''
+  form.financialManagement = []
+  form.financialManagementOther = ''
+
+  // (二) 婚姻家庭状况
+  form.maritalStatus = ''
+  form.familyMembers = {
+    son: '',
+    daughter: '',
+    sonInLaw: '',
+    daughterInLaw: '',
+    grandChildren: ''
+  }
+  form.mainCaregiver = {
+    name: '',
+    relation: ''
+  }
+  form.preAdmissionLiving = ''
+  form.preAdmissionLivingOther = ''
+  form.familyVisitFrequency = ''
+  form.familyVisitFrequencyOther = ''
+
+  // (三) 健康状况
+  form.healthStatus = ''
+  form.healthStatusDisease = ''
+
+  // (四) 过往史
+  form.educationLevel = ''
+  form.educationLevelOther = ''
+  form.politicalStatus = ''
+  form.previousOccupation = ''
+  form.hasStayedInNursingHome = ''
+  form.nursingHomeStayDetail = ''
+  form.reasonForAdmission = ''
+
+  // (五) 社交状况
+  form.friendsInHome = ''
+  form.socialPreference = ''
+  form.badMoodReaction = ''
+  form.hobbies = []
+  form.hobbiesOther = ''
+  form.specialFestival = ''
+  form.otherSpecialNotes = ''
+}
+
+// 计算窗口大小
+const currentWidth = useMediaQuery('(max-width: 800px)')
+// 计算文字大小
+const labelWidth = computed(() => {
+  return currentWidth.value ? '130px' : '130px'
+})
+
+
+
+/** 打开弹窗 */
+const open = async (tenantId, id?: any, detail: boolean = false) => {
+  resetForm()
+  dialogVisible.value = true
+  dataForm.value.id = id || undefined
+  dataForm.value.tenantId = tenantId
+  isDetail.value = detail
+  if (id) {
+    title.value = "编辑-长者心理社交情况"
+    // 加载心理社交情况数据(方案二)
+    await loadPsychologicalSocialData(id)
+  } else {
+    title.value = "新增-长者心理社交情况"
+    // 如果选择了长者,尝试加载已有的心理社交情况数据
+    if (dataForm.value.elderId) {
+      await loadPsychologicalSocialByElderId(dataForm.value.elderId)
+    }
+  }
+}
+
+
+const form = reactive({
+  // 基本信息
+  elderName: '',
+  birthDate: '',
+  bedNumber: '',
+  assessor: '',
+  assessDate: '',
+
+  // (一) 经济状况
+  incomeSource: [],
+  incomeSourceOther: '',
+  financialManagement: [],
+  financialManagementOther: '',
+
+  // (二) 婚姻家庭状况
+  maritalStatus: '',
+  familyMembers: {
+    son: '',
+    daughter: '',
+    sonInLaw: '',
+    daughterInLaw: '',
+    grandChildren: ''
+  },
+  mainCaregiver: {
+    name: '',
+    relation: ''
+  },
+  preAdmissionLiving: '',
+  preAdmissionLivingOther: '',
+  familyVisitFrequency: '',
+  familyVisitFrequencyOther: '',
+
+  // (三) 健康状况
+  healthStatus: '',
+  healthStatusDisease: '',
+
+  // (四) 过往史
+  educationLevel: '',
+  educationLevelOther: '',
+  politicalStatus: '',
+  previousOccupation: '',
+  hasStayedInNursingHome: '',
+  nursingHomeStayDetail: '',
+  reasonForAdmission: '',
+
+  // (五) 社交状况
+  friendsInHome: '',
+  socialPreference: '',
+  badMoodReaction: '',
+  hobbies: [],
+  hobbiesOther: '',
+  specialFestival: '',
+  otherSpecialNotes: ''
+})
+
+const incomeSourceOptions = [
+  { label: '退休金', value: '退休金' },
+  { label: '家人/亲友', value: '家人/亲友' },
+  { label: '个人储蓄', value: '个人储蓄' },
+  { label: '低保金', value: '低保金' },
+  { label: '政府供养', value: '政府供养' },
+  { label: '其他', value: '其他' }
+]
+
+const financialManagementOptions = [
+  { label: '家人代理', value: '家人代理' },
+  { label: '个人处理', value: '个人处理' },
+  { label: '委托人处理', value: '委托人处理' },
+  { label: '政府拨付', value: '政府拨付' },
+  { label: '其他', value: '其他' }
+]
+
+const maritalStatusOptions = [
+  { label: '独身', value: '独身' },
+  { label: '已婚', value: '已婚' },
+  { label: '鳏寡', value: '鳏寡' }
+]
+
+const preAdmissionLivingOptions = [
+  { label: '独居', value: '独居' },
+  { label: '与家属同住', value: '与家属同住' },
+  { label: '其他', value: '其他' }
+]
+
+const familyVisitFrequencyOptions = [
+  { label: '没有', value: '没有' },
+  { label: '很少', value: '很少' },
+  { label: '一般', value: '一般' },
+  { label: '经常', value: '经常' },
+  { label: '不适用', value: '不适用' }
+]
+
+const healthStatusOptions = [
+  { label: '良好', value: '良好' },
+  { label: '一般,但影响不大', value: '一般,但影响不大' },
+  { label: '较差', value: '较差' }
+]
+
+const educationLevelOptions = [
+  { label: '文盲', value: '文盲' },
+  { label: '扫盲班', value: '扫盲班' },
+  { label: '小学', value: '小学' },
+  { label: '初中', value: '初中' },
+  { label: '高中', value: '高中' },
+  { label: '大专', value: '大专' },
+  { label: '本科及以上', value: '本科及以上' },
+  { label: '其他', value: '其他' }
+]
+
+const hasStayedInNursingHomeOptions = [
+  { label: '没有', value: '没有' },
+  { label: '有', value: '有' }
+]
+
+const socialPreferenceOptions = [
+  { label: '喜欢独处', value: '喜欢独处' },
+  { label: '喜欢交友', value: '喜欢交友' },
+  { label: '乐于群体生活', value: '乐于群体生活' }
+]
+
+const hobbyOptions = [
+  { label: '饮茶', value: '饮茶' },
+  { label: '参观旅行', value: '参观旅行' },
+  { label: '闲谈', value: '闲谈' },
+  { label: '看电视', value: '看电视' },
+  { label: '唱歌', value: '唱歌' },
+  { label: '跳舞', value: '跳舞' },
+  { label: '做手工', value: '做手工' },
+  { label: '打麻将、天九', value: '打麻将、天九' },
+  { label: '下棋', value: '下棋' },
+  { label: '书画', value: '书画' },
+  { label: '做义工', value: '做义工' },
+  { label: '参加运动和活动', value: '参加运动和活动' },
+  { label: '阅读', value: '阅读' },
+  { label: '上老年大学', value: '上老年大学' },
+  { label: '参加宗教活动', value: '参加宗教活动' },
+  { label: '其他', value: '其他' }
+]
+
+
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  if(formLoading.value){
+    return
+  }
+  formLoading.value = true
+  // 提交请求
+  try {
+
+    const aa = serializeFormData()
+    console.log("AASSS",aa)
+    deserializeFormData(aa)
+    return
+    let tempParams = {...dataForm.value,restraintReason:dataForm.value.restraintReason.join(','),restraintType:dataForm.value.restraintType.join(',')}
+    if(dataForm.value.id) {
+      const res = await restraintUpdate(tempParams)
+      if (res) {
+        message.success(t('common.updateSuccess'))
+        dialogVisible.value = false
+        // 发送操作成功的事件
+        emit('success')
+      }
+    }else {
+      console.log("AAAAA",tempParams)
+      const res = await restraintCreate(tempParams)
+      if (res) {
+        message.success(t('common.updateSuccess'))
+        dialogVisible.value = false
+        // 发送操作成功的事件
+        emit('success')
+      }
+    }
+
+  } finally {
+    setTimeout(()=>{
+      formLoading.value = false
+    },500)
+  }
+}
+
+
+
+/** 重置表单 */
+const resetForm = () => {
+  dataForm.value = {
+    id: undefined,
+    idCard: '',
+    fileNumber: '', //档案号
+    elderName: '',//长者姓名
+    bedName: '', //床位号
+    elderAge: '', //年龄
+    elderSex: '', //性别
+    checkInTime: '', //入院日期
+    elderId: '',
+    recordDate: dayjs().format('YYYY-MM-DD'), // 记录时间,默认当前时间
+    items: [], //时间数组
+    restraintReason: [], //约束原因
+    restraintType: [], //约束类型
+    tenantId: undefined
+  }
+  formRef.value?.resetFields()
+
+  jsonDataList.value=[]
+  radio.value=1
+
+  // 重置心理社交情况表单(方案二)
+  resetPsychologicalForm()
+}
+
+// 关闭表单
+const handleClosed = () => {
+  dialogVisible.value = false
+  resetForm()
+}
+
+</script>
+
+<style scoped lang="scss">
+.psychological-social-form {
+  max-width: 1200px;
+  margin: 0 auto;
+  background: #fff;
+
+  .form-title {
+    text-align: center;
+    font-size: 24px;
+    font-weight: bold;
+    margin-bottom: 20px;
+  }
+
+
+
+    .info-row {
+      display: flex;
+      gap: 40px;
+      width: 100%;
+      flex-direction: row;
+      align-items: center;
+      margin-bottom: 10px;
+
+      .info-item {
+        display: flex;
+        align-items: center;
+        gap: 8px;
+
+        .label {
+          width: 82px;
+          text-align: right;
+          margin-right: 4px;
+          white-space: nowrap;
+        }
+      }
+    }
+
+
+  .form-body {
+    border: 1px solid #333;
+    padding: 15px;
+  }
+
+  .section {
+    margin-bottom: 20px;
+
+    &:last-child {
+      margin-bottom: 0;
+    }
+
+    .section-title {
+      font-weight: bold;
+      margin-bottom: 10px;
+    }
+  }
+
+  .form-item {
+    display: flex;
+    align-items: center;
+    margin-bottom: 12px;
+    flex-wrap: wrap;
+    gap: 8px;
+
+    .item-number {
+      font-weight: bold;
+      min-width: 25px;
+    }
+
+    .item-label {
+      white-space: nowrap;
+      min-width: fit-content;
+    }
+
+    .sub-item {
+      display: inline-flex;
+      align-items: center;
+      gap: 4px;
+      margin-right: 15px;
+    }
+
+    .sub-label {
+      white-space: nowrap;
+    }
+  }
+
+  .hobby-item {
+    flex-direction: column;
+    align-items: flex-start;
+
+    .hobby-checkbox-group {
+      display: flex;
+      flex-wrap: wrap;
+      gap: 8px 20px;
+      margin-left: 35px;
+
+      :deep(.el-checkbox) {
+        margin-right: 0;
+        min-width: 100px;
+      }
+    }
+
+    .hobby-other {
+      display: flex;
+      align-items: center;
+      gap: 4px;
+      margin-left: 35px;
+      margin-top: 8px;
+    }
+  }
+
+  .inline-checkbox-group,
+  .inline-radio-group {
+    display: inline-flex;
+    flex-wrap: wrap;
+    gap: 8px 15px;
+
+    :deep(.el-checkbox),
+    :deep(.el-radio) {
+      margin-right: 0;
+    }
+  }
+
+  // 输入框样式
+  .tiny-input {
+    width: 50px;
+
+    :deep(.el-input__inner) {
+      padding: 0 4px;
+      text-align: center;
+    }
+  }
+
+  .short-input {
+    width: 100px;
+  }
+
+  .medium-input {
+    width: 200px;
+  }
+
+  .long-input {
+    width: 400px;
+  }
+
+  .other-input {
+    width: 120px;
+  }
+
+  .date-input {
+    width: 140px;
+  }
+
+  // 调整 Element Plus 组件样式
+  :deep(.el-input__inner) {
+    height: 28px;
+    line-height: 28px;
+    border-top: none;
+    border-left: none;
+    border-right: none;
+    border-radius: 0;
+    padding: 0 4px;
+
+    &:focus {
+      border-color: #409eff;
+    }
+  }
+
+
+  :deep(.el-checkbox__label),
+  :deep(.el-radio__label) {
+    padding-left: 4px;
+  }
+}
+.row{
+  margin-bottom: 12px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  text{
+    text-align: right;
+    margin-right: 4px;
+    width: 82px;
+  }
+}
+</style>

+ 327 - 0
src/views/social-worker/assessment/SAS/index.vue

@@ -0,0 +1,327 @@
+<template>
+  <ContentWrap>
+    <!-- 保护性约束观察记录表 -->
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="110px"
+    >
+      <el-form-item label="长者姓名">
+        <el-input
+          v-model="queryParams.elderName"
+          placeholder="长者姓名"
+          class="!w-240px"
+          clearable
+        />
+      </el-form-item>
+
+
+
+      <el-form-item label="记录日期">
+        <el-date-picker
+          size="default"
+          ref="selectRef"
+          class="!w-240px"
+          v-model="queryParams.recordDate"
+          type="daterange"
+          :clearable="true"
+          :editable="false"
+          placeholder="选择记录日期"
+          value-format="YYYY-MM-DD"
+          format="YYYY-MM-DD"
+          date-format="YYYY-MM-DD"
+        />
+      </el-form-item>
+
+      <el-form-item>
+        <el-button @click="handleQuery" style="margin-left: 2vw"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <div class="mb-10px">
+
+      <ButtonAdd @click="openForm(undefined)"  />
+      <!--      <el-button @click="inputH" type="success"><Icon icon="fa:cloud-upload" :size="16" class="mr-1"/>导入</el-button>-->
+      <ButtonImport @click="handleImportCard"  />
+
+
+    </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">
+          {{
+            scope.$index + (queryParams.pageNo * queryParams.pageSize - queryParams.pageSize) + 1
+          }}
+        </template>
+      </el-table-column>
+
+
+      <el-table-column prop="elderName" header-align="center" align="center" label="长者姓名" min-width="150" show-overflow-tooltip/>
+      <el-table-column prop="bedName" header-align="center" align="center" label="床位号" min-width="200" show-overflow-tooltip/>
+      <el-table-column prop="recordDate" header-align="center" align="center" label="记录日期" min-width="200" show-overflow-tooltip/>
+
+      <el-table-column prop="creator" header-align="center" align="center" label="记录人" min-width="200" show-overflow-tooltip/>
+
+
+      <el-table-column label="操作" align="center" width="200" >
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            @click="openFormEdit(scope.row, scope.row.id)"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="warning"
+            @click="openFormDetail(scope.row,scope.row.id)"
+          >
+            详情
+          </el-button>
+          <el-button
+            link
+            type="danger"
+            @click="openClose(scope.row)"
+          >
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+  <AddForm ref="formRef" @success="getList" />
+
+  <!-- 通用批量导出弹窗 -->
+  <BatchExportDialog
+    :show="showBatchExport"
+    :title="exportConfig.title"
+    :loading="exportLoading"
+    :batch-min="exportConfig.batchMin"
+    :batch-max="exportConfig.batchMax"
+    :count-min="exportConfig.countMin"
+    :count-max="exportConfig.countMax"
+    :default-batch="exportConfig.defaultBatch"
+    :default-count="exportConfig.defaultCount"
+    :description="exportConfig.description"
+    @update:show="showBatchExport = $event"
+    @confirm="handleBatchExport"
+    @cancel="showBatchExport = false"
+  />
+
+
+  <Import
+    ref="importRef"
+    @success="getList"
+    :config="{
+      title: '导入',
+      downloadUrl: 'elderly-service-order/get-import-template',
+      excelTempName: '居家工单-【导入】模板',
+      importUrl: '/elderly-service-order/import',
+      failExportUrl: '',
+    }"
+  />
+
+</template>
+
+<script setup lang="ts">
+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 {formatTimestamp, getCurrentMonthRange} from "@/utils/dateUtil";
+import Import from "@/components/ImportFile/index.vue";
+import {restraintCreatePage, restraintDelete} from "@/api/elderly/nursing/keep-fit";
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+const userStore = useUserStore()
+const loading = ref(true) // 列表的加载中
+const detailRef = ref()
+const importRef = ref()
+const total = ref(0) // 列表的总页数
+const list = ref([]) // 列表的数据
+
+// 状态管理
+const showBatchExport = ref(false)
+const exportConfig = ref({
+  title: '',
+  batchMin: 1,
+  batchMax: 999,
+  countMin: 1,
+  countMax: 200,
+  defaultBatch: 1,
+  defaultCount: 200,
+  description: [] as string[]
+})
+const exportLoading = ref(false)
+
+let queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  elderName: '',
+  creator: '',
+  recordDate: getCurrentMonthRange(),
+  tenantIds: userStore.orgTenantId
+})
+const queryFormRef = ref() // 搜索的表单
+
+const inputH = () => {
+  importRef.value.open(queryParams.tenantIds[0])
+}
+// 打开导出弹窗
+const handleImportCard = async () => {
+
+  // showBatchExport.value = true
+}
+
+// 处理批量导出
+const handleBatchExport = async (batch: number, count: number) => {
+  exportLoading.value = true
+  console.log(batch,count)
+  // try {
+  //   let queryParams = {
+  //     pageNo: batch,
+  //     pageSize: count,
+  //     tenantId: userStore.orgTenantId[0]
+  //   }
+  //   const list = await careRecordsPage(queryParams)
+  //   if (list.length <= 0) {
+  //     message.error('暂无数据可以导出!')
+  //     return
+  //   }
+  //   const headers = [
+  //     { key: 'organizationName', title: '机构名称' },
+  //     { key: 'visitName', title: '姓名' },
+  //     { key: 'visitPhone', title: '手机号' },
+  //     { key: 'visitDate', title: '预约时间' },
+  //     { key: 'accompanyCount', title: '陪同人数' },
+  //     { key: 'reason', title: '理由' }
+  //   ]
+  //   exportWithExpandedObjectArrays(list, headers, `医疗护理记录${formatToDateTime()}.xlsx`, '医疗护理记录')
+  // } catch (_) {}
+
+}
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    //let queryP = {...queryParams,discoveryTime:queryParams.discoveryTime?[queryParams.discoveryTime[0]+" 00:00:00",queryParams.discoveryTime[1]+" 23:59:59"]:null}
+    const data = await restraintCreatePage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = async () => {
+  if (!queryFormRef.value) return
+  const valid = await queryFormRef.value.validate()
+  if (!valid) return
+  queryParams.pageNo = 1
+  await getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryParams.elderName = ''
+  queryParams.creator = ''
+  queryParams.tenantIds = userStore.orgTenantId
+  queryParams.recordDate= getCurrentMonthRange()
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+/** 添加/修改操作 */
+const formRef = ref()
+const openForm = (id?: number) => {
+  if(queryParams.tenantIds.length == 0 || queryParams.tenantIds.length > 1){
+    message.error('新增只能选择一个机构')
+    return
+  }
+  formRef.value.open(queryParams.tenantIds[0], id,false)
+}
+
+const editRef = ref()
+const openFormEdit = (row: any = {}, id?: number) => {
+  formRef.value.open(row.tenantId, id,false)
+}
+
+
+const openFormDetail = (row: any = {},id?: number) => {
+  formRef.value.open(row.tenantId,id,true)
+}
+
+
+
+
+
+const openClose = async (item) => {
+  try {
+    console.log("任务ID",item)
+    const res = await message.confirm('确定要删除吗?', '提示')
+    if (res == 'confirm') {
+      // 发起
+      try {
+        const res = await restraintDelete(item.id)
+        if (res){
+          message.success(t('common.updateSuccess'))
+        }
+      }catch(err) {}
+    }
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 取消按钮操作 */
+const cancelDelete = async (id: number) => {
+  try {
+    // 取消的二次确认
+    await message.cancelConfirm()
+    // 发起取消
+    // await elderlyBakDel(id)
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+const route = useRoute()
+/** 初始化 **/
+onMounted(() => {
+  if(route.query && route.query.elderName){
+    queryParams.elderName = route.query.elderName as string
+  }
+  getList()
+})
+
+// 表头格式
+const tableHeaderColor = ({ rowIndex }: any) => {
+  if (rowIndex === 0) {
+    return {
+      backgroundColor: '#f8f8f9',
+      color: '#666666',
+      fontWeight: 'bold'
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss"></style>

+ 1117 - 0
src/views/social-worker/assessment/SDS/AddForm.vue

@@ -0,0 +1,1117 @@
+<template>
+  <el-drawer
+    v-model="dialogVisible"
+    :title="title"
+    resizable
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    :destroy-on-close="true"
+    size="70%"
+    :before-close="handleClosed"
+  >
+
+    <div class="attack-risk-form">
+      <h1 class="form-title">抑郁自评量表</h1>
+      <!-- 基本信息 -->
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>长者姓名</text>
+          <search-the-elderly ref="selectElderRef" :disabled="isDetail" @update_elder="elderUp" v-model="dataForm.elderName" :tId="dataForm.tenantId"/>
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>档案号</text>
+          <el-input v-if="!isDetail" v-model="dataForm.contractNumber" disabled />
+          <el-text v-else disabled="">{{dataForm.contractNumber}}</el-text>
+        </el-col>
+      </el-row>
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>入院日期</text>
+          <el-input v-if="!isDetail" :model-value="dayjs(dataForm.checkInTime).format('YYYY-MM-DD')=='Invalid Date'?'':dayjs(dataForm.checkInTime).format('YYYY-MM-DD')" disabled />
+          <el-text v-else disabled="">{{dayjs(dataForm.checkInTime).format('YYYY-MM-DD')}}</el-text>
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>床位号</text>
+          <el-input v-if="!isDetail" v-model="dataForm.bedName" disabled />
+          <el-text v-else disabled="">{{dataForm.bedName}}</el-text>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="40">
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>评估人</text>
+          <el-input v-model="form.assessor"  />
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
+          <text>评估日期</text>
+          <el-date-picker v-model="form.assessDate" type="date" style="width: 100%;"/>
+
+        </el-col>
+      </el-row>
+
+      <!-- 表单内容区域 -->
+      <div class="form-body">
+        <!-- 说明文字 -->
+        <div class="instruction-section">
+          <p>下面有20条文字,请仔细阅读每一条,把意思弄明白,然后根据您一周来的实际感觉,在分数栏"1~4分"下选择与您的情况相符的画"√"。每道题不需要花费太多时间思考,根据您的第一印象选择最适合您的答案。(评定时间为过去一周内或现在)。</p>
+        </div>
+
+        <!-- 总分显示 -->
+        <div class="total-score-section">
+          <div class="score-row">
+            <div class="score-item">
+              <span class="score-label">粗分:</span>
+              <span class="score-value">{{ rawScore }}</span>
+              <span class="score-unit">分</span>
+            </div>
+            <div class="score-item" style="margin-left: 30px">
+              <span class="score-label">标准分:</span>
+              <span class="score-value">{{ standardScore }}</span>
+              <span class="score-unit">分</span>
+              <span class="score-formula">(粗分×1.25)</span>
+            </div>
+          </div>
+          <div class="depression-level" :class="depressionLevelClass">
+            {{ depressionLevelText }}
+          </div>
+        </div>
+
+        <!-- 评估表格 -->
+        <div class="assessment-table">
+          <table>
+            <thead>
+              <tr>
+                <th class="no-col">题号</th>
+                <th class="question-col">实际感觉</th>
+                <th class="option-col">很少有</th>
+                <th class="option-col">有时有</th>
+                <th class="option-col">大部分时间有</th>
+                <th class="option-col">绝大多数时间有</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr v-for="(item, index) in sdsQuestions" :key="index" :class="{ 'reverse': item.isReverse }">
+                <td class="no">{{ item.isReverse ? '*' : '' }}{{ index + 1 }}</td>
+                <td class="question">{{ item.question }}</td>
+                <td class="option">
+                  <el-radio v-model="form.answers[index]" :value="item.isReverse ? 4 : 1" :disabled="isDetail">
+                      {{ item.isReverse ? 4 : 1 }}
+                  </el-radio>
+                </td>
+                <td class="option">
+                  <el-radio v-model="form.answers[index]" :value="item.isReverse ? 3 : 2" :disabled="isDetail">
+                      {{ item.isReverse ? 3 : 2 }}
+                  </el-radio>
+                </td>
+                <td class="option">
+                  <el-radio v-model="form.answers[index]" :value="item.isReverse ? 2 : 3" :disabled="isDetail">
+                      {{ item.isReverse ? 2 : 3 }}
+                  </el-radio>
+                </td>
+                <td class="option">
+                  <el-radio v-model="form.answers[index]" :value="item.isReverse ? 1 : 4" :disabled="isDetail">
+                      {{ item.isReverse ? 1 : 4 }}
+                  </el-radio>
+                </td>
+              </tr>
+            </tbody>
+          </table>
+        </div>
+
+        <!-- 评分说明 -->
+        <div class="scoring-note">
+          <div class="note-title">评分说明:</div>
+          <div class="note-content">
+            <p>① 评分方法:抑郁自评量表采取4级评分方法,主要评定症状出现的频率。1分代表没有或很少时间有;2分代表有时有;3分代表大部分时间有;4分代表绝大部分时间或全部时间有。其中前缀*号的题目为反序评分,按照4~1分顺序计分。</p>
+            <p>② 分析指标:将20个项目得分相加即得粗分,将粗分乘以1.25后取整数即得标准分。</p>
+            <p>③ 结果解释:标准分值越低状态越好,50~59分为轻度抑郁;60~69分为中度抑郁;≥70分为重度抑郁。</p>
+          </div>
+        </div>
+
+        <!-- 签名区域 -->
+        <div class="signature-section">
+          <div class="signature-row">
+            <div class="signature-item">
+              <span class="signature-label">家属/监护人签名:</span>
+              <el-input v-model="form.familySignature" :disabled="isDetail" class="signature-input"/>
+            </div>
+
+          </div>
+        </div>
+      </div>
+
+    </div>
+
+    <div><div style="font-weight: bold">这是提交字段,后端可照此字段创建数据表</div>:
+      {
+      "contractNumber": "",
+      "elderName": "",
+      "bedName": "",
+      "checkInTime": "",
+      "elderId": "",
+      "tenantId": 211,
+      "assessmentData": "{\"assessor\":\"\",\"assessDate\":\"\",\"answers\":[4,3,2,2,3,3,2,2,0,0,0,0,0,0,0,0,0,2,3,3],\"rawScore\":29,\"standardScore\":36,\"depressionLevel\":\"正常\",\"familySignature\":\"\",\"familySignDate\":\"\"}",
+      "assessor": "",
+      "assessDate": "",
+      "orgType": 1
+      }
+    </div>
+
+    <template #footer>
+      <el-button @click="handleClosed">关闭</el-button>
+      <el-button   type="success" @click="handleExport">打印</el-button>
+      <el-button style="margin-left: 22px;margin-right: 30px" v-loading="formLoading" type="primary" v-show="!isDetail" @click="submitForm">确定</el-button>
+    </template>
+
+  </el-drawer>
+</template>
+
+<script lang="ts" setup>
+import { computed, ref, watch } from 'vue'
+
+import dayjs from 'dayjs'
+
+import { sdsCreate, sdsGetById, sdsUpdate, sdsGetByElderId } from "@/api/social-work";
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+const title = ref('')
+const dialogVisible = ref(false) // 弹窗
+const formRef = ref() // 表单 Ref
+const selectElderRef = ref() // 表单 Ref
+const isDetail = ref(false) // 是否详情打开
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+let dataForm = ref({
+  // 表单字段
+  id: undefined,
+  idCard: '',
+  contractNumber: '', //档案号
+  elderName: '',//长者姓名
+  bedName: '', //床位号
+  elderAge: '', //年龄
+  elderSex: '', //性别
+  checkInTime: '', //入院日期
+  elderId: '',
+  tenantId: undefined
+})
+
+
+
+
+const elderUp = (e) => {
+  dataForm.value.elderName = e.elderName
+  dataForm.value.elderId = e.id
+  dataForm.value.elderSex = e.elderSex === 1 ? '男' : '女'
+  dataForm.value.bedName = e.bedName || ''
+  dataForm.value.checkInTime = e.checkInTime
+  dataForm.value.contractNumber = e.contractNumber
+  dataForm.value.elderAge = e.elderAge
+}
+
+// ========== 抑郁自评量表(SDS) 表单序列化方法 ==========
+
+// SDS问题列表(带*号的为反向计分)
+const sdsQuestions = [
+  { question: '我觉得闷闷不乐,情绪低沉', isReverse: false },
+  { question: '我觉得一天之中早晨最好', isReverse: true },
+  { question: '我一阵阵哭出来或觉得想哭', isReverse: false },
+  { question: '我晚上睡眠不好', isReverse: false },
+  { question: '我吃得和平常一样多', isReverse: true },
+  { question: '我与异性密切接触时和以往一样感到愉快', isReverse: true },
+  { question: '我发觉我的体重在下降', isReverse: false },
+  { question: '我有便秘的苦恼', isReverse: false },
+  { question: '我心跳比平时快', isReverse: false },
+  { question: '我无缘无故地感到疲乏', isReverse: false },
+  { question: '我的头脑跟平常一样清楚', isReverse: true },
+  { question: '我觉得经常做的事情并没有困难', isReverse: true },
+  { question: '我觉得不安而平静不下来', isReverse: false },
+  { question: '我对将来抱有希望', isReverse: true },
+  { question: '我比平常容易生气激动', isReverse: false },
+  { question: '我觉得做出决定是容易的', isReverse: true },
+  { question: '我觉得自己是个有用的人,有人需要我', isReverse: true },
+  { question: '我的生活过得很有意思', isReverse: true },
+  { question: '我认为如果我死了别人会生活得好些', isReverse: false },
+  { question: '平常感兴趣的事我仍然照样感兴趣', isReverse: true }
+]
+
+/** 计算粗分 */
+const rawScore = computed(() => {
+  if (!form.answers || form.answers.length === 0) return 0
+  return form.answers.reduce((sum, score) => sum + (score || 0), 0)
+})
+
+/** 计算标准分(粗分×1.25,取整数) */
+const standardScore = computed(() => {
+  return Math.round(rawScore.value * 1.25)
+})
+
+/** 抑郁程度文本 */
+const depressionLevelText = computed(() => {
+  const score = standardScore.value
+  if (score < 50) return '正常'
+  if (score >= 50 && score <= 59) return '轻度抑郁'
+  if (score >= 60 && score <= 69) return '中度抑郁'
+  return '重度抑郁'
+})
+
+/** 抑郁程度样式类 */
+const depressionLevelClass = computed(() => {
+  const score = standardScore.value
+  if (score < 50) return 'level-normal'
+  if (score >= 50 && score <= 59) return 'level-mild'
+  if (score >= 60 && score <= 69) return 'level-moderate'
+  return 'level-severe'
+})
+
+
+
+/** 将表单数据序列化为 JSON 对象 */
+const serializeFormData = () => {
+  return {
+    // 基本信息
+    assessor: form.assessor || '',
+    assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : '',
+
+    // 各题答案
+    answers: form.answers || [],
+
+    // 粗分
+    rawScore: rawScore.value,
+
+    // 标准分
+    standardScore: standardScore.value,
+
+    // 抑郁程度
+    depressionLevel: depressionLevelText.value,
+
+    // 签名
+    familySignature: form.familySignature || '',
+    familySignDate: form.familySignDate ? dayjs(form.familySignDate).format('YYYY-MM-DD') : ''
+  }
+}
+
+/** 将 JSON 对象反序列化为表单数据 */
+const deserializeFormData = (formData: Record<string, any>) => {
+  if (!formData) return
+
+  // 基本信息
+  form.assessor = formData.assessor || ''
+  form.assessDate = formData.assessDate ? dayjs(formData.assessDate).toDate() : ''
+
+  // 各题答案
+  form.answers = formData.answers || new Array(20).fill(0)
+
+  // 签名
+  form.familySignature = formData.familySignature || ''
+  form.familySignDate = formData.familySignDate ? dayjs(formData.familySignDate).toDate() : ''
+}
+
+/** 重置抑郁自评量表表单数据 */
+const resetSDSForm = () => {
+  form.assessor = ''
+  form.assessDate = ''
+
+  // 各题答案(20题,初始为0)
+  form.answers = new Array(20).fill(0)
+
+  // 签名
+  form.familySignature = ''
+  form.familySignDate = ''
+}
+
+/** 打开弹窗 */
+const open = async (tenantId, id?: any, detail: boolean = false) => {
+  resetForm()
+  dialogVisible.value = true
+  dataForm.value.id = id || undefined
+  dataForm.value.tenantId = tenantId
+  isDetail.value = detail
+  if (id) {
+    title.value = "编辑-抑郁自评量表"
+    // 加载评估数据
+    await loadSDSData(id)
+  } else {
+    title.value = "新增-抑郁自评量表"
+    // 如果选择了长者,尝试加载已有的评估数据
+    if (dataForm.value.elderId) {
+      await loadSDSByElderId(dataForm.value.elderId)
+    }
+  }
+}
+
+/** 加载评估数据 */
+const loadSDSData = async (id: number) => {
+  try {
+    const res = await sdsGetById(id)
+    if (res) {
+      // 填充长者基本信息
+      dataForm.value.elderName = res.elderName || ''
+      dataForm.value.elderId = res.elderId || ''
+      dataForm.value.elderSex = res.elderSex || ''
+      dataForm.value.bedName = res.bedName || ''
+      dataForm.value.checkInTime = res.checkInTime || ''
+      dataForm.value.contractNumber = res.contractNumber || ''
+      dataForm.value.elderAge = res.elderAge || ''
+
+      // 解析 assessmentData
+      if (res.assessmentData) {
+        const formData = JSON.parse(res.assessmentData)
+        deserializeFormData(formData)
+      }
+    }
+  } catch (error) {
+    message.error('加载评估数据失败')
+  }
+}
+
+/** 根据长者ID加载评估数据 */
+const loadSDSByElderId = async (elderId: number) => {
+  try {
+    const res = await sdsGetByElderId(elderId)
+    if (res && res.assessmentData) {
+      const formData = JSON.parse(res.assessmentData)
+      deserializeFormData(formData)
+    }
+  } catch (error) {
+    // 无历史数据,不处理
+  }
+}
+
+const form = reactive({
+  // 基本信息
+  assessor: '',
+  assessDate: '',
+
+  // 各题答案(20题)
+  answers: new Array(20).fill(0),
+
+  // 签名
+  familySignature: '',
+  familySignDate: ''
+})
+
+
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  if (formLoading.value) {
+    return
+  }
+  formLoading.value = true
+  // 提交请求
+  try {
+    const assessmentData = serializeFormData()
+    const tempParams = {
+      ...dataForm.value,
+      assessmentData: JSON.stringify(assessmentData),
+      attackLevel: form.attackLevel,
+      riskLevel: form.riskLevel,
+      assessor: form.assessor,
+      assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''
+    }
+
+    if (dataForm.value.id) {
+      const res = await sdsUpdate(tempParams)
+      if (res) {
+        message.success(t('common.updateSuccess'))
+        dialogVisible.value = false
+        // 发送操作成功的事件
+        emit('success')
+      }
+    } else {
+      const res = await sdsCreate(tempParams)
+      if (res) {
+        message.success(t('common.createSuccess'))
+        dialogVisible.value = false
+        // 发送操作成功的事件
+        emit('success')
+      }
+    }
+  } finally {
+    setTimeout(() => {
+      formLoading.value = false
+    }, 500)
+  }
+}
+
+
+
+/** 重置表单 */
+const resetForm = () => {
+  dataForm.value = {
+    id: undefined,
+    idCard: '',
+    contractNumber: '', //档案号
+    elderName: '',//长者姓名
+    bedName: '', //床位号
+    elderAge: '', //年龄
+    elderSex: '', //性别
+    checkInTime: '', //入院日期
+    elderId: '',
+    tenantId: undefined
+  }
+  formRef.value?.resetFields()
+
+  // 重置抑郁自评量表表单
+  resetSDSForm()
+}
+
+// 关闭表单
+const handleClosed = () => {
+  dialogVisible.value = false
+  resetForm()
+}
+
+/** 导出打印 */
+const handleExport = () => {
+  // 创建打印窗口
+  const printWindow = window.open('', '_blank')
+  if (!printWindow) {
+    message.error('请允许弹出窗口')
+    return
+  }
+
+  // 生成问题行HTML
+  const questionRows = sdsQuestions.map((item, index) => {
+    const answer = form.answers[index] || 0
+    const score1 = item.isReverse ? 4 : 1
+    const score2 = item.isReverse ? 3 : 2
+    const score3 = item.isReverse ? 2 : 3
+    const score4 = item.isReverse ? 1 : 4
+    return `
+      <tr class="${item.isReverse ? 'reverse' : ''}">
+        <td class="no">${item.isReverse ? '*' : ''}${index + 1}</td>
+        <td class="question">${item.question}</td>
+        <td class="option">${answer === score1 ? '☑' : '☐'} ${score1}</td>
+        <td class="option">${answer === score2 ? '☑' : '☐'} ${score2}</td>
+        <td class="option">${answer === score3 ? '☑' : '☐'} ${score3}</td>
+        <td class="option">${answer === score4 ? '☑' : '☐'} ${score4}</td>
+      </tr>
+    `
+  }).join('')
+
+  // 构建打印内容
+  const printContent = `
+    <!DOCTYPE html>
+    <html>
+    <head>
+      <meta charset="UTF-8">
+      <title>抑郁自评量表 - ${dataForm.value.elderName || ''}</title>
+      <style>
+        @media print {
+          @page { size: A4 portrait; margin: 10mm; }
+        }
+        body {
+          font-family: 'SimSun', 'Microsoft YaHei', serif;
+          font-size: 9pt;
+          line-height: 1.4;
+          color: #333;
+        }
+        .header {
+          text-align: center;
+          margin-bottom: 10px;
+          border-bottom: 2px solid #333;
+          padding-bottom: 8px;
+        }
+        .header h1 {
+          font-size: 14pt;
+          margin: 0;
+          letter-spacing: 2px;
+        }
+        .instruction {
+          font-size: 8pt;
+          margin-bottom: 10px;
+          padding: 8px;
+          background: #f5f5f5;
+          border: 1px solid #999;
+        }
+        .info-section {
+          margin-bottom: 10px;
+          padding: 8px;
+          border: 1px solid #999;
+          background: #fafafa;
+        }
+        .info-row {
+          display: flex;
+          flex-wrap: wrap;
+          gap: 20px;
+        }
+        .info-item {
+          display: flex;
+          align-items: center;
+        }
+        .info-item .label {
+          font-weight: bold;
+          margin-right: 8px;
+          color: #555;
+        }
+        .info-item .value {
+          border-bottom: 1px solid #333;
+          min-width: 80px;
+          padding: 0 5px;
+          text-align: center;
+        }
+        .score-summary {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          padding: 8px 12px;
+          background: #f0f0f0;
+          border: 2px solid #333;
+          margin-bottom: 10px;
+        }
+        .score-item {
+          font-size: 11pt;
+        }
+        .score-value {
+          font-weight: bold;
+          color: #d9534f;
+          font-size: 14pt;
+        }
+        .depression-level {
+          font-size: 12pt;
+          font-weight: bold;
+          padding: 5px 15px;
+          border-radius: 4px;
+        }
+        .level-normal { color: #28a745; }
+        .level-mild { color: #ffc107; }
+        .level-moderate { color: #fd7e14; }
+        .level-severe { color: #dc3545; }
+
+        .assessment-table {
+          width: 100%;
+          border-collapse: collapse;
+          margin-bottom: 10px;
+          font-size: 8pt;
+        }
+        .assessment-table th, .assessment-table td {
+          border: 1px solid #333;
+          padding: 5px;
+          text-align: center;
+          vertical-align: middle;
+        }
+        .assessment-table th {
+          background: #e8e8e8;
+          font-weight: bold;
+        }
+        .assessment-table .no-col { width: 6%; }
+        .assessment-table .question-col { width: 40%; text-align: left; }
+        .assessment-table .option-col { width: 13.5%; }
+        .assessment-table .no { text-align: center; }
+        .assessment-table .question { text-align: left; }
+        .assessment-table .reverse { background: #f9f9f9; }
+
+        .scoring-note {
+          margin: 10px 0;
+          padding: 8px;
+          border: 1px solid #999;
+          background: #fafafa;
+          font-size: 8pt;
+        }
+        .scoring-note-title {
+          font-weight: bold;
+          margin-bottom: 5px;
+        }
+        .scoring-note p {
+          margin: 3px 0;
+        }
+
+        .signature-section {
+          margin-top: 15px;
+          padding: 10px;
+          border: 1px solid #999;
+        }
+        .signature-row {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+        }
+        .signature-item {
+          display: flex;
+          align-items: center;
+          gap: 10px;
+        }
+        .signature-label {
+          font-weight: bold;
+        }
+        .signature-value {
+          border-bottom: 1px solid #333;
+          min-width: 150px;
+          height: 20px;
+        }
+      </style>
+    </head>
+    <body>
+      <div class="header">
+        <h1>抑郁自评量表</h1>
+      </div>
+
+      <div class="instruction">
+        下面有20条文字,请仔细阅读每一条,把意思弄明白,然后根据您一周来的实际感觉,在分数栏"1~4分"下选择与您的情况相符的画"√"。每道题不需要花费太多时间思考,根据您的第一印象选择最适合您的答案。(评定时间为过去一周内或现在)。
+      </div>
+
+      <div class="info-section">
+        <div class="info-row">
+          <div class="info-item">
+            <span class="label">长者姓名:</span>
+            <span class="value">${dataForm.value.elderName || ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">档案号:</span>
+            <span class="value">${dataForm.value.contractNumber || ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">床位号:</span>
+            <span class="value">${dataForm.value.bedName || ''}</span>
+          </div>
+        </div>
+        <div class="info-row" style="margin-top: 8px;">
+          <div class="info-item">
+            <span class="label">评估日期:</span>
+            <span class="value">${form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">评估人:</span>
+            <span class="value">${form.assessor || ''}</span>
+          </div>
+        </div>
+      </div>
+
+      <div class="score-summary">
+        <div class="score-item">
+          <span class="label">粗分:</span>
+          <span class="score-value">${rawScore.value}</span>
+          <span class="unit">分</span>
+        </div>
+        <div class="score-item">
+          <span class="label">标准分:</span>
+          <span class="score-value">${standardScore.value}</span>
+          <span class="unit">分</span>
+          <span class="formula">(粗分×1.25)</span>
+        </div>
+        <div class="depression-level ${depressionLevelClass.value}">
+          ${depressionLevelText.value}
+        </div>
+      </div>
+
+      <!-- 评估表格 -->
+      <table class="assessment-table">
+        <thead>
+          <tr>
+            <th class="no-col">题号</th>
+            <th class="question-col">实际感觉</th>
+            <th class="option-col">很少有</th>
+            <th class="option-col">有时有</th>
+            <th class="option-col">大部分时间有</th>
+            <th class="option-col">绝大多数时间有</th>
+          </tr>
+        </thead>
+        <tbody>
+          ${questionRows}
+        </tbody>
+      </table>
+
+      <div class="scoring-note">
+        <div class="scoring-note-title">评分说明:</div>
+        <p>① 评分方法:抑郁自评量表采取4级评分方法,主要评定症状出现的频率。1分代表没有或很少时间有;2分代表有时有;3分代表大部分时间有;4分代表绝大部分时间或全部时间有。其中前缀*号的题目为反序评分,按照4~1分顺序计分。</p>
+        <p>② 分析指标:将20个项目得分相加即得粗分,将粗分乘以1.25后取整数即得标准分。</p>
+        <p>③ 结果解释:标准分值越低状态越好,50~59分为轻度抑郁;60~69分为中度抑郁;≥70分为重度抑郁。</p>
+      </div>
+
+      <!-- 签名区域 -->
+      <div class="signature-section">
+        <div class="signature-row">
+          <div class="signature-item">
+            <span class="signature-label">家属/监护人签名:</span>
+            <span class="signature-value">${form.familySignature || ''}</span>
+          </div>
+
+        </div>
+      </div>
+    </body>
+    </html>
+  `
+
+  // 写入内容并打印
+  printWindow.document.write(printContent)
+  printWindow.document.close()
+
+  // 延迟打印,确保样式加载完成
+  setTimeout(() => {
+    printWindow.print()
+  }, 500)
+}
+
+</script>
+
+<style scoped lang="scss">
+
+.form-title {
+  text-align: center;
+  font-size: 20px;
+  width: 100%;
+  margin-bottom: 20px;
+}
+
+.sds-form {
+  max-width: 1200px;
+  margin: 0 auto;
+  background: #fff;
+
+
+
+
+
+  .info-row {
+    display: flex;
+    gap: 40px;
+    width: 100%;
+    flex-direction: row;
+    align-items: center;
+    margin-bottom: 10px;
+
+    .info-item {
+      display: flex;
+      align-items: center;
+      gap: 8px;
+
+      .label {
+        width: 82px;
+        text-align: right;
+        margin-right: 4px;
+        white-space: nowrap;
+      }
+    }
+  }
+
+
+  .form-body {
+    border: 1px solid #333;
+    padding: 15px;
+  }
+
+  // 调整 Element Plus 组件样式
+  :deep(.el-input__inner) {
+    height: 28px;
+    line-height: 28px;
+    border-top: none;
+    border-left: none;
+    border-right: none;
+    border-radius: 0;
+    padding: 0 4px;
+
+    &:focus {
+      border-color: #409eff;
+    }
+  }
+
+  :deep(.el-checkbox__label),
+  :deep(.el-radio__label) {
+    padding-left: 4px;
+  }
+}
+.row{
+  margin-bottom: 12px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  text{
+    text-align: right;
+    margin-right: 4px;
+    width: 82px;
+  }
+}
+
+// NGASR自杀风险评估量表 特有样式
+.total-score-section {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  margin-bottom: 20px;
+
+  .total-score {
+    display: flex;
+    align-items: baseline;
+    gap: 4px;
+
+    .score-label {
+      font-size: 16px;
+      font-weight: bold;
+    }
+
+    .score-value {
+      font-size: 28px;
+      font-weight: bold;
+      color: #409eff;
+    }
+
+    .score-max {
+      font-size: 14px;
+      color: #909399;
+    }
+  }
+
+  .risk-level {
+    font-size: 16px;
+    font-weight: bold;
+    padding: 8px 16px;
+    border-radius: 4px;
+
+    &.risk-none {
+      color: #67c23a;
+      background: #f0f9eb;
+    }
+
+    &.risk-low {
+      color: #e6a23c;
+      background: #fdf6ec;
+    }
+
+    &.risk-medium {
+      color: #f56c6c;
+      background: #fef0f0;
+    }
+
+    &.risk-high {
+      color: #f56c6c;
+      background: #fef0f0;
+      border: 1px solid #f56c6c;
+    }
+  }
+}
+
+.instruction-section {
+  margin-bottom: 15px;
+  padding: 12px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+  font-size: 13px;
+  line-height: 1.6;
+  color: #606266;
+}
+
+.total-score-section {
+  margin: 15px 0;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .score-row {
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    margin-bottom: 10px;
+
+    .score-item {
+      font-size: 14px;
+
+      .score-label {
+        font-weight: bold;
+      }
+
+      .score-value {
+        font-size: 18px;
+        font-weight: bold;
+        color: #d9534f;
+        margin: 0 5px;
+      }
+
+      .score-unit {
+        font-size: 12px;
+      }
+
+      .score-formula {
+        color: #909399;
+        font-size: 12px;
+        margin-left: 5px;
+      }
+    }
+  }
+
+  .depression-level {
+    text-align: center;
+    font-size: 16px;
+    font-weight: bold;
+    padding: 8px;
+    border-radius: 4px;
+    margin-top: 10px;
+
+    &.level-normal {
+      color: #67c23a;
+      background: #f0f9eb;
+    }
+
+    &.level-mild {
+      color: #e6a23c;
+      background: #fdf6ec;
+    }
+
+    &.level-moderate {
+      color: #f56c6c;
+      background: #fef0f0;
+    }
+
+    &.level-severe {
+      color: #f56c6c;
+      background: #fef0f0;
+    }
+  }
+}
+
+.assessment-table {
+  width: 100%;
+  border-collapse: collapse;
+  margin-bottom: 20px;
+
+  table {
+    width: 100%;
+    border: 1px solid #333;
+
+    th, td {
+      border: 1px solid #333;
+      padding: 10px 8px;
+      text-align: center;
+      vertical-align: middle;
+    }
+
+    th {
+      background: #f5f7fa;
+      font-weight: bold;
+      font-size: 13px;
+    }
+
+    .no-col {
+      width: 6%;
+    }
+
+    .question-col {
+      width: 40%;
+    }
+
+    .option-col {
+      width: 13.5%;
+    }
+
+    .no {
+      text-align: center;
+      font-size: 13px;
+    }
+
+    .question {
+      text-align: left;
+      font-size: 13px;
+    }
+
+    .option {
+      text-align: center;
+
+      :deep(.el-radio) {
+        margin-right: 0;
+      }
+    }
+
+    tr.reverse {
+      background: #f9f9f9;
+    }
+  }
+}
+
+.scoring-note {
+  margin: 20px 0;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .risk-judgment-title {
+    font-weight: bold;
+    font-size: 16px;
+    margin-bottom: 12px;
+    color: #303133;
+  }
+
+  .risk-options {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 20px;
+
+    :deep(.el-radio) {
+      margin-right: 0;
+    }
+  }
+}
+
+.scoring-note {
+  margin: 15px 0;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .note-title {
+    font-weight: bold;
+    font-size: 16px;
+    margin-bottom: 12px;
+    color: #303133;
+  }
+
+  .note-content {
+    font-size: 13px;
+    line-height: 1.8;
+    color: #606266;
+
+    p {
+      margin: 5px 0;
+    }
+  }
+}
+
+.signature-section {
+  margin: 20px 0;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+
+  .signature-row {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    gap: 20px;
+  }
+
+  .signature-item {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+
+    &.date-item {
+      :deep(.el-date-picker) {
+        width: 150px;
+      }
+    }
+  }
+
+  .signature-label {
+    font-weight: bold;
+    white-space: nowrap;
+  }
+
+  .signature-input {
+    width: 150px;
+  }
+
+  .date-picker {
+    width: 150px;
+  }
+}
+
+
+</style>

+ 327 - 0
src/views/social-worker/assessment/SDS/index.vue

@@ -0,0 +1,327 @@
+<template>
+  <ContentWrap>
+    <!-- 保护性约束观察记录表 -->
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="110px"
+    >
+      <el-form-item label="长者姓名">
+        <el-input
+          v-model="queryParams.elderName"
+          placeholder="长者姓名"
+          class="!w-240px"
+          clearable
+        />
+      </el-form-item>
+
+
+
+      <el-form-item label="记录日期">
+        <el-date-picker
+          size="default"
+          ref="selectRef"
+          class="!w-240px"
+          v-model="queryParams.recordDate"
+          type="daterange"
+          :clearable="true"
+          :editable="false"
+          placeholder="选择记录日期"
+          value-format="YYYY-MM-DD"
+          format="YYYY-MM-DD"
+          date-format="YYYY-MM-DD"
+        />
+      </el-form-item>
+
+      <el-form-item>
+        <el-button @click="handleQuery" style="margin-left: 2vw"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <div class="mb-10px">
+
+      <ButtonAdd @click="openForm(undefined)"  />
+      <!--      <el-button @click="inputH" type="success"><Icon icon="fa:cloud-upload" :size="16" class="mr-1"/>导入</el-button>-->
+      <ButtonImport @click="handleImportCard"  />
+
+
+    </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">
+          {{
+            scope.$index + (queryParams.pageNo * queryParams.pageSize - queryParams.pageSize) + 1
+          }}
+        </template>
+      </el-table-column>
+
+
+      <el-table-column prop="elderName" header-align="center" align="center" label="长者姓名" min-width="150" show-overflow-tooltip/>
+      <el-table-column prop="bedName" header-align="center" align="center" label="床位号" min-width="200" show-overflow-tooltip/>
+      <el-table-column prop="recordDate" header-align="center" align="center" label="记录日期" min-width="200" show-overflow-tooltip/>
+
+      <el-table-column prop="creator" header-align="center" align="center" label="记录人" min-width="200" show-overflow-tooltip/>
+
+
+      <el-table-column label="操作" align="center" width="200" >
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            @click="openFormEdit(scope.row, scope.row.id)"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="warning"
+            @click="openFormDetail(scope.row,scope.row.id)"
+          >
+            详情
+          </el-button>
+          <el-button
+            link
+            type="danger"
+            @click="openClose(scope.row)"
+          >
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+  <AddForm ref="formRef" @success="getList" />
+
+  <!-- 通用批量导出弹窗 -->
+  <BatchExportDialog
+    :show="showBatchExport"
+    :title="exportConfig.title"
+    :loading="exportLoading"
+    :batch-min="exportConfig.batchMin"
+    :batch-max="exportConfig.batchMax"
+    :count-min="exportConfig.countMin"
+    :count-max="exportConfig.countMax"
+    :default-batch="exportConfig.defaultBatch"
+    :default-count="exportConfig.defaultCount"
+    :description="exportConfig.description"
+    @update:show="showBatchExport = $event"
+    @confirm="handleBatchExport"
+    @cancel="showBatchExport = false"
+  />
+
+
+  <Import
+    ref="importRef"
+    @success="getList"
+    :config="{
+      title: '导入',
+      downloadUrl: 'elderly-service-order/get-import-template',
+      excelTempName: '居家工单-【导入】模板',
+      importUrl: '/elderly-service-order/import',
+      failExportUrl: '',
+    }"
+  />
+
+</template>
+
+<script setup lang="ts">
+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 {formatTimestamp, getCurrentMonthRange} from "@/utils/dateUtil";
+import Import from "@/components/ImportFile/index.vue";
+import {restraintCreatePage, restraintDelete} from "@/api/elderly/nursing/keep-fit";
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+const userStore = useUserStore()
+const loading = ref(true) // 列表的加载中
+const detailRef = ref()
+const importRef = ref()
+const total = ref(0) // 列表的总页数
+const list = ref([]) // 列表的数据
+
+// 状态管理
+const showBatchExport = ref(false)
+const exportConfig = ref({
+  title: '',
+  batchMin: 1,
+  batchMax: 999,
+  countMin: 1,
+  countMax: 200,
+  defaultBatch: 1,
+  defaultCount: 200,
+  description: [] as string[]
+})
+const exportLoading = ref(false)
+
+let queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  elderName: '',
+  creator: '',
+  recordDate: getCurrentMonthRange(),
+  tenantIds: userStore.orgTenantId
+})
+const queryFormRef = ref() // 搜索的表单
+
+const inputH = () => {
+  importRef.value.open(queryParams.tenantIds[0])
+}
+// 打开导出弹窗
+const handleImportCard = async () => {
+
+  // showBatchExport.value = true
+}
+
+// 处理批量导出
+const handleBatchExport = async (batch: number, count: number) => {
+  exportLoading.value = true
+  console.log(batch,count)
+  // try {
+  //   let queryParams = {
+  //     pageNo: batch,
+  //     pageSize: count,
+  //     tenantId: userStore.orgTenantId[0]
+  //   }
+  //   const list = await careRecordsPage(queryParams)
+  //   if (list.length <= 0) {
+  //     message.error('暂无数据可以导出!')
+  //     return
+  //   }
+  //   const headers = [
+  //     { key: 'organizationName', title: '机构名称' },
+  //     { key: 'visitName', title: '姓名' },
+  //     { key: 'visitPhone', title: '手机号' },
+  //     { key: 'visitDate', title: '预约时间' },
+  //     { key: 'accompanyCount', title: '陪同人数' },
+  //     { key: 'reason', title: '理由' }
+  //   ]
+  //   exportWithExpandedObjectArrays(list, headers, `医疗护理记录${formatToDateTime()}.xlsx`, '医疗护理记录')
+  // } catch (_) {}
+
+}
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    //let queryP = {...queryParams,discoveryTime:queryParams.discoveryTime?[queryParams.discoveryTime[0]+" 00:00:00",queryParams.discoveryTime[1]+" 23:59:59"]:null}
+    const data = await restraintCreatePage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = async () => {
+  if (!queryFormRef.value) return
+  const valid = await queryFormRef.value.validate()
+  if (!valid) return
+  queryParams.pageNo = 1
+  await getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryParams.elderName = ''
+  queryParams.creator = ''
+  queryParams.tenantIds = userStore.orgTenantId
+  queryParams.recordDate= getCurrentMonthRange()
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+/** 添加/修改操作 */
+const formRef = ref()
+const openForm = (id?: number) => {
+  if(queryParams.tenantIds.length == 0 || queryParams.tenantIds.length > 1){
+    message.error('新增只能选择一个机构')
+    return
+  }
+  formRef.value.open(queryParams.tenantIds[0], id,false)
+}
+
+const editRef = ref()
+const openFormEdit = (row: any = {}, id?: number) => {
+  formRef.value.open(row.tenantId, id,false)
+}
+
+
+const openFormDetail = (row: any = {},id?: number) => {
+  formRef.value.open(row.tenantId,id,true)
+}
+
+
+
+
+
+const openClose = async (item) => {
+  try {
+    console.log("任务ID",item)
+    const res = await message.confirm('确定要删除吗?', '提示')
+    if (res == 'confirm') {
+      // 发起
+      try {
+        const res = await restraintDelete(item.id)
+        if (res){
+          message.success(t('common.updateSuccess'))
+        }
+      }catch(err) {}
+    }
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 取消按钮操作 */
+const cancelDelete = async (id: number) => {
+  try {
+    // 取消的二次确认
+    await message.cancelConfirm()
+    // 发起取消
+    // await elderlyBakDel(id)
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+const route = useRoute()
+/** 初始化 **/
+onMounted(() => {
+  if(route.query && route.query.elderName){
+    queryParams.elderName = route.query.elderName as string
+  }
+  getList()
+})
+
+// 表头格式
+const tableHeaderColor = ({ rowIndex }: any) => {
+  if (rowIndex === 0) {
+    return {
+      backgroundColor: '#f8f8f9',
+      color: '#666666',
+      fontWeight: 'bold'
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss"></style>

+ 373 - 92
src/views/social-worker/assessment/psychological-social-situation/AddForm.vue

@@ -270,9 +270,24 @@
         </div>
 
     </div>
+    <div><div style="font-weight: bold">这是提交字段,后端可照此字段创建数据表</div>:
+      {
+      "fileNumber": "NS20190098",
+      "elderName": "陈木娣",
+      "bedName": "养护楼-4层-407-04",
+      "checkInTime": 1562284800000,
+      "elderId": 17563,
+      "tenantId": 211,
+      "assessmentData": "{\"assessor\":\"啊啊\",\"assessDate\":\"2026-03-14\",\"incomeSource\":[],\"incomeSourceOther\":\"\",\"financialManagement\":[],\"financialManagementOther\":\"\",\"maritalStatus\":\"已婚\",\"familyMembers\":{\"son\":\"1\",\"daughter\":\"\",\"sonInLaw\":\"\",\"daughterInLaw\":\"\",\"grandChildren\":\"\"},\"mainCaregiver\":{\"name\":\"2\",\"relation\":\"\"},\"preAdmissionLiving\":\"\",\"preAdmissionLivingOther\":\"\",\"familyVisitFrequency\":\"\",\"familyVisitFrequencyOther\":\"\",\"healthStatus\":\"\",\"healthStatusDisease\":\"\",\"educationLevel\":\"高中\",\"educationLevelOther\":\"\",\"politicalStatus\":\"\",\"previousOccupation\":\"\",\"hasStayedInNursingHome\":\"\",\"nursingHomeStayDetail\":\"\",\"reasonForAdmission\":\"\",\"friendsInHome\":\"\",\"socialPreference\":\"\",\"badMoodReaction\":\"\",\"hobbies\":[],\"hobbiesOther\":\"\",\"specialFestival\":\"\",\"otherSpecialNotes\":\"\"}",
+      "assessor": "啊啊",
+      "assessDate": "2026-03-14",
+      "orgType": 1
+      }
+    </div>
 
     <template #footer>
       <el-button @click="handleClosed">关闭</el-button>
+      <el-button  type="success" @click="handleExport">打印</el-button>
       <el-button style="margin-left: 22px;margin-right: 30px" v-loading="formLoading" type="primary" v-show="!isDetail" @click="submitForm">确定</el-button>
     </template>
 
@@ -280,35 +295,17 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, ref } from 'vue'
-import {FormRules} from 'element-plus'
-import { useMediaQuery } from '@vueuse/core'
-const { isValidNumberDis } = useValidator()
-import { useValidator } from '@/hooks/web/useValidator'
+import { ref } from 'vue'
 import dayjs from 'dayjs'
-import { useUserStore } from '@/store/modules/user'
-import {tableHeaderColor} from "@/utils/table";
-import {InfoFilled} from "@element-plus/icons-vue";
-import {restraintCreate, restraintGetById, restraintUpdate} from "@/api/elderly/nursing/keep-fit";
 import {psychologicalSocialCreate, psychologicalSocialUpdate, psychologicalSocialGetById, psychologicalSocialGetByElderId} from "@/api/elderly/assessment/psychological-social";
 const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
-const discountAmount = ref()
-const discount = ref()
-const selectBedRef = ref()
 const title = ref('')
 const dialogVisible = ref(false) // 弹窗
-const loading = ref(false) // 弹窗
 const formRef = ref() // 表单 Ref
-const radio = ref(1) // 表单 Ref
 const selectElderRef = ref() // 表单 Ref
 const isDetail = ref(false) // 是否详情打开
-const jsonDataList = ref([])
 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
-const userStore = useUserStore()
-
-
-
 
 let dataForm = ref({
   // 表单字段
@@ -321,35 +318,17 @@ let dataForm = ref({
   elderSex: '', //性别
   checkInTime: '', //入院日期
   elderId: '',
-  recordDate: dayjs().format('YYYY-MM-DD'), // 记录时间,默认当前时间
-  items: [], //时间数组
-  restraintReason: [], //约束原因
-  restraintType: [], //约束类型
   tenantId: undefined
 })
-// 表单规则
-const dataRule = reactive<FormRules>({
-  recordTime: [{ required: true, message: '记录时间不能为空', trigger: 'blur' }],
-  elderId: [{ required: true, message: '长者姓名不能为空', trigger: 'blur' }],
-  phone: [{ required: true, message: '联系方式不能为空', trigger: 'blur' },
-    { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' }],
-  sourceChannel: [{ required: true, message: '来源渠道不能为空', trigger: 'blur' }],
-  elderId: [{ required: true, message: '长者姓名不能为空', trigger: 'blur' }],
-
-})
-
-
 
 const elderUp = (e) => {
   dataForm.value.elderName = e.elderName
   dataForm.value.elderId = e.id
   dataForm.value.elderSex = e.elderSex === 1 ? '男' : '女'
-  dataForm.value.bedName = e.bedName||''
+  dataForm.value.bedName = e.bedName || ''
   dataForm.value.checkInTime = e.checkInTime
   dataForm.value.fileNumber = e.fileNumber
   dataForm.value.elderAge = e.elderAge
-  dataForm.value.nurseLevelName = e.nurseLevelName
-
 }
 
 // ========== 心理社交情况表单序列化方法 ==========
@@ -507,15 +486,6 @@ const resetPsychologicalForm = () => {
   form.otherSpecialNotes = ''
 }
 
-// 计算窗口大小
-const currentWidth = useMediaQuery('(max-width: 800px)')
-// 计算文字大小
-const labelWidth = computed(() => {
-  return currentWidth.value ? '130px' : '130px'
-})
-
-
-
 /** 打开弹窗 */
 const open = async (tenantId, id?: any, detail: boolean = false) => {
   resetForm()
@@ -679,6 +649,44 @@ const hobbyOptions = [
 
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 
+/** 加载心理社交情况数据 */
+const loadPsychologicalSocialData = async (id: number) => {
+  try {
+    const res = await psychologicalSocialGetById(id)
+    if (res) {
+      // 填充长者基本信息
+      dataForm.value.elderName = res.elderName || ''
+      dataForm.value.elderId = res.elderId || ''
+      dataForm.value.elderSex = res.elderSex || ''
+      dataForm.value.bedName = res.bedName || ''
+      dataForm.value.checkInTime = res.checkInTime || ''
+      dataForm.value.fileNumber = res.fileNumber || ''
+      dataForm.value.elderAge = res.elderAge || ''
+
+      // 解析 assessmentData
+      if (res.assessmentData) {
+        const formData = JSON.parse(res.assessmentData)
+        deserializeFormData(formData)
+      }
+    }
+  } catch (error) {
+    message.error('加载数据失败')
+  }
+}
+
+/** 根据长者ID加载心理社交情况数据 */
+const loadPsychologicalSocialByElderId = async (elderId: number) => {
+  try {
+    const res = await psychologicalSocialGetByElderId(elderId)
+    if (res && res.assessmentData) {
+      const formData = JSON.parse(res.assessmentData)
+      deserializeFormData(formData)
+    }
+  } catch (error) {
+    // 无历史数据,不处理
+  }
+}
+
 /** 提交表单 */
 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
 const submitForm = async () => {
@@ -688,14 +696,16 @@ const submitForm = async () => {
   formLoading.value = true
   // 提交请求
   try {
+    const assessmentData = serializeFormData()
+    const tempParams = {
+      ...dataForm.value,
+      assessmentData: JSON.stringify(assessmentData),
+      assessor: form.assessor,
+      assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''
+    }
 
-    const aa = serializeFormData()
-    console.log("AASSS",aa)
-    deserializeFormData(aa)
-    return
-    let tempParams = {...dataForm.value,restraintReason:dataForm.value.restraintReason.join(','),restraintType:dataForm.value.restraintType.join(',')}
     if(dataForm.value.id) {
-      const res = await restraintUpdate(tempParams)
+      const res = await psychologicalSocialUpdate(tempParams)
       if (res) {
         message.success(t('common.updateSuccess'))
         dialogVisible.value = false
@@ -703,16 +713,14 @@ const submitForm = async () => {
         emit('success')
       }
     }else {
-      console.log("AAAAA",tempParams)
-      const res = await restraintCreate(tempParams)
+      const res = await psychologicalSocialCreate(tempParams)
       if (res) {
-        message.success(t('common.updateSuccess'))
+        message.success(t('common.createSuccess'))
         dialogVisible.value = false
         // 发送操作成功的事件
         emit('success')
       }
     }
-
   } finally {
     setTimeout(()=>{
       formLoading.value = false
@@ -720,6 +728,312 @@ const submitForm = async () => {
   }
 }
 
+/** 导出打印 */
+const handleExport = () => {
+  // 创建打印窗口
+  const printWindow = window.open('', '_blank')
+  if (!printWindow) {
+    message.error('请允许弹出窗口')
+    return
+  }
+
+  // 辅助函数:格式化数组显示
+  const formatArray = (arr) => {
+    if (!arr || arr.length === 0) return '无'
+    return arr.join('、')
+  }
+
+  // 辅助函数:格式化家庭成员
+  const formatFamilyMembers = (members) => {
+    const parts = []
+    if (members.son) parts.push(`儿子${members.son}名`)
+    if (members.daughter) parts.push(`女儿${members.daughter}名`)
+    if (members.sonInLaw) parts.push(`女婿${members.sonInLaw}名`)
+    if (members.daughterInLaw) parts.push(`儿媳${members.daughterInLaw}名`)
+    if (members.grandChildren) parts.push(`孙子女${members.grandChildren}名`)
+    return parts.length > 0 ? parts.join(',') : '无'
+  }
+
+  // 构建打印内容
+  const printContent = `
+    <!DOCTYPE html>
+    <html>
+    <head>
+      <meta charset="UTF-8">
+      <title>长者心理社交情况 - ${dataForm.value.elderName || ''}</title>
+      <style>
+        @media print {
+          @page { size: A4 portrait; margin: 15mm; }
+        }
+        body {
+          font-family: 'SimSun', 'Microsoft YaHei', serif;
+          font-size: 11pt;
+          line-height: 1.6;
+          color: #333;
+        }
+        .header {
+          text-align: center;
+          margin-bottom: 20px;
+          border-bottom: 2px solid #333;
+          padding-bottom: 10px;
+        }
+        .header h1 {
+          font-size: 18pt;
+          margin: 0;
+          letter-spacing: 2px;
+        }
+        .info-section {
+          margin-bottom: 15px;
+          padding: 10px;
+          border: 1px solid #999;
+          background: #fafafa;
+        }
+        .info-row {
+          display: flex;
+          flex-wrap: wrap;
+          gap: 20px;
+        }
+        .info-item {
+          display: flex;
+          align-items: center;
+        }
+        .info-item .label {
+          font-weight: bold;
+          margin-right: 8px;
+          color: #555;
+        }
+        .info-item .value {
+          border-bottom: 1px solid #333;
+          min-width: 80px;
+          padding: 0 5px;
+          text-align: center;
+        }
+        .section {
+          margin-bottom: 15px;
+          border: 1px solid #999;
+        }
+        .section-title {
+          font-weight: bold;
+          background: #e8e8e8;
+          padding: 8px 12px;
+          border-bottom: 1px solid #999;
+          font-size: 12pt;
+        }
+        .form-item {
+          padding: 8px 12px;
+          border-bottom: 1px dashed #ccc;
+          display: flex;
+          align-items: flex-start;
+        }
+        .form-item:last-child {
+          border-bottom: none;
+        }
+        .item-number {
+          font-weight: bold;
+          margin-right: 8px;
+          min-width: 25px;
+        }
+        .item-label {
+          font-weight: bold;
+          margin-right: 8px;
+          white-space: nowrap;
+        }
+        .item-content {
+          flex: 1;
+        }
+        .signature-section {
+          margin-top: 30px;
+          display: flex;
+          justify-content: space-between;
+        }
+        .signature-item {
+          width: 45%;
+        }
+        .signature-label {
+          margin-bottom: 5px;
+        }
+        .signature-line {
+          border-bottom: 1px solid #333;
+          height: 30px;
+        }
+      </style>
+    </head>
+    <body>
+      <div class="header">
+        <h1>长者心理社交情况</h1>
+      </div>
+
+      <div class="info-section">
+        <div class="info-row">
+          <div class="info-item">
+            <span class="label">长者姓名:</span>
+            <span class="value">${dataForm.value.elderName || ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">档案号:</span>
+            <span class="value">${dataForm.value.fileNumber || ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">床位号:</span>
+            <span class="value">${dataForm.value.bedName || ''}</span>
+          </div>
+        </div>
+        <div class="info-row" style="margin-top: 10px;">
+          <div class="info-item">
+            <span class="label">评估日期:</span>
+            <span class="value">${form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''}</span>
+          </div>
+          <div class="info-item">
+            <span class="label">评估人:</span>
+            <span class="value">${form.assessor || ''}</span>
+          </div>
+        </div>
+      </div>
+
+      <!-- (一) 经济状况 -->
+      <div class="section">
+        <div class="section-title">(一)经济状况</div>
+        <div class="form-item">
+          <span class="item-number">1.</span>
+          <span class="item-label">收入来源:</span>
+          <span class="item-content">${formatArray(form.incomeSource)}${form.incomeSource.includes('其他') ? '(' + form.incomeSourceOther + ')' : ''}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">2.</span>
+          <span class="item-label">财政处理:</span>
+          <span class="item-content">${formatArray(form.financialManagement)}${form.financialManagement.includes('其他') ? '(' + form.financialManagementOther + ')' : ''}</span>
+        </div>
+      </div>
+
+      <!-- (二) 婚姻家庭状况 -->
+      <div class="section">
+        <div class="section-title">(二)婚姻家庭状况</div>
+        <div class="form-item">
+          <span class="item-number">3.</span>
+          <span class="item-label">婚姻状况:</span>
+          <span class="item-content">${form.maritalStatus || '未填写'}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">4.</span>
+          <span class="item-label">近亲家属:</span>
+          <span class="item-content">${formatFamilyMembers(form.familyMembers)}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">5.</span>
+          <span class="item-label">主要照顾亲属:</span>
+          <span class="item-content">姓名:${form.mainCaregiver.name || '无'},关系:${form.mainCaregiver.relation || '无'}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">6.</span>
+          <span class="item-label">入院前居住情况:</span>
+          <span class="item-content">${form.preAdmissionLiving || '未填写'}${form.preAdmissionLiving === '其他' ? '(' + form.preAdmissionLivingOther + ')' : ''}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">7.</span>
+          <span class="item-label">家人/亲友到访情况:</span>
+          <span class="item-content">${form.familyVisitFrequency || '未填写'}${form.familyVisitFrequency === '不适用' ? '(' + form.familyVisitFrequencyOther + ')' : ''}</span>
+        </div>
+      </div>
+
+      <!-- (三) 健康状况 -->
+      <div class="section">
+        <div class="section-title">(三)健康状况</div>
+        <div class="form-item">
+          <span class="item-number">8.</span>
+          <span class="item-label">健康状况:</span>
+          <span class="item-content">${form.healthStatus || '未填写'}${form.healthStatus === '较差' ? '(病类:' + form.healthStatusDisease + ')' : ''}</span>
+        </div>
+      </div>
+
+      <!-- (四) 过往史 -->
+      <div class="section">
+        <div class="section-title">(四)过往史</div>
+        <div class="form-item">
+          <span class="item-number">9.</span>
+          <span class="item-label">教育程度:</span>
+          <span class="item-content">${form.educationLevel || '未填写'}${form.educationLevel === '其他' ? '(' + form.educationLevelOther + ')' : ''}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">10.</span>
+          <span class="item-label">政治面貌:</span>
+          <span class="item-content">${form.politicalStatus || '未填写'}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">11.</span>
+          <span class="item-label">以往职业:</span>
+          <span class="item-content">${form.previousOccupation || '未填写'}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">12.</span>
+          <span class="item-label">以前是否入住过养老院:</span>
+          <span class="item-content">${form.hasStayedInNursingHome || '未填写'}${form.hasStayedInNursingHome === '有' ? '(' + form.nursingHomeStayDetail + ')' : ''}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">13.</span>
+          <span class="item-label">来老人院的原因:</span>
+          <span class="item-content">${form.reasonForAdmission || '未填写'}</span>
+        </div>
+      </div>
+
+      <!-- (五) 社交状况 -->
+      <div class="section">
+        <div class="section-title">(五)社交状况</div>
+        <div class="form-item">
+          <span class="item-number">14.</span>
+          <span class="item-label">院内好友:</span>
+          <span class="item-content">${form.friendsInHome || '未填写'}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">15.</span>
+          <span class="item-label">社交喜好:</span>
+          <span class="item-content">${form.socialPreference || '未填写'}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">16.</span>
+          <span class="item-label">心情不好时的反应:</span>
+          <span class="item-content">${form.badMoodReaction || '未填写'}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">17.</span>
+          <span class="item-label">兴趣爱好:</span>
+          <span class="item-content">${formatArray(form.hobbies)}${form.hobbies.includes('其他') ? '(' + form.hobbiesOther + ')' : ''}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">18.</span>
+          <span class="item-label">特别喜欢/重视的东西或节日等:</span>
+          <span class="item-content">${form.specialFestival || '未填写'}</span>
+        </div>
+        <div class="form-item">
+          <span class="item-number">19.</span>
+          <span class="item-label">其他特别的事项记录:</span>
+          <span class="item-content">${form.otherSpecialNotes || '无'}</span>
+        </div>
+      </div>
+
+      <div class="signature-section">
+        <div class="signature-item">
+          <div class="signature-label">家属/评估员签名:</div>
+          <div class="signature-line"></div>
+        </div>
+        <div class="signature-item">
+          <div class="signature-label">日期:</div>
+          <div class="signature-line"></div>
+        </div>
+      </div>
+    </body>
+    </html>
+  `
+
+  // 写入内容并打印
+  printWindow.document.write(printContent)
+  printWindow.document.close()
+
+  // 延迟打印,确保样式加载完成
+  setTimeout(() => {
+    printWindow.print()
+  }, 500)
+}
+
 
 
 /** 重置表单 */
@@ -734,18 +1048,11 @@ const resetForm = () => {
     elderSex: '', //性别
     checkInTime: '', //入院日期
     elderId: '',
-    recordDate: dayjs().format('YYYY-MM-DD'), // 记录时间,默认当前时间
-    items: [], //时间数组
-    restraintReason: [], //约束原因
-    restraintType: [], //约束类型
     tenantId: undefined
   }
   formRef.value?.resetFields()
 
-  jsonDataList.value=[]
-  radio.value=1
-
-  // 重置心理社交情况表单(方案二)
+  // 重置心理社交情况表单
   resetPsychologicalForm()
 }
 
@@ -770,31 +1077,6 @@ const handleClosed = () => {
     margin-bottom: 20px;
   }
 
-
-
-    .info-row {
-      display: flex;
-      gap: 40px;
-      width: 100%;
-      flex-direction: row;
-      align-items: center;
-      margin-bottom: 10px;
-
-      .info-item {
-        display: flex;
-        align-items: center;
-        gap: 8px;
-
-        .label {
-          width: 82px;
-          text-align: right;
-          margin-right: 4px;
-          white-space: nowrap;
-        }
-      }
-    }
-
-
   .form-body {
     border: 1px solid #333;
     padding: 15px;
@@ -881,8 +1163,7 @@ const handleClosed = () => {
 
   // 输入框样式
   .tiny-input {
-    width: 50px;
-
+    width: 90px;
     :deep(.el-input__inner) {
       padding: 0 4px;
       text-align: center;

+ 10 - 10
src/views/social-worker/floor-activity-record/photo/AddForm.vue

@@ -36,7 +36,7 @@
           <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
             <el-form-item label="楼栋" prop="buildName">
               <el-select v-if="!isDetail" v-model="dataForm.buildName" placeholder="选择楼栋" style="width: 100%">
-                <el-option @click="handleBuildChange(item)" v-for="(item,index) in buildList" :key="index" :label="item.buildName" :value="item.buildName" />
+                <el-option @click="handleBuildChange(item)" v-for="(item,index) in buildList" :key="index" :label="item.buildName" :value="item.id" />
               </el-select>
               <el-text v-else>{{dataForm.buildName}}</el-text>
             </el-form-item>
@@ -46,7 +46,7 @@
           <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
             <el-form-item label="楼层" prop="floorName">
               <el-select v-if="!isDetail" v-model="dataForm.floorName" placeholder="选择楼层" style="width: 100%">
-                <el-option v-for="(item,index) in floorList" :key="index" :label="item.floorName" :value="item.floorName" />
+                <el-option v-for="(item,index) in floorList" :key="index" :label="item.floorName" :value="item.id" />
               </el-select>
               <el-text v-else>{{dataForm.floorName}}</el-text>
             </el-form-item>
@@ -223,15 +223,15 @@ const photoList = ref<Array<{ url: string; description: string }>>([
 // 表单数据
 let dataForm = ref({
   id: undefined,
-  recordYear: dayjs().format('YYYY-MM'), // 记录年份
-  recordMonth: dayjs().month() + 1, // 记录月份
-  weekNumber: 1, // 第几周
-  buildName: '', // 楼栋
-  floorName: '', // 楼层
+  recordMonth: dayjs().format('YYYY-MM'), // 记录年份
+  week: 1, // 第几周
+  elderName: '', //
+  buildId: '', // 楼栋
+  floorId: '', // 楼层
+  belongFloor: '', // 楼层
+  activityDate: '', // 楼层
+  activityContent: '', // 楼层
   recordTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), // 记录时间
-  startDate: '', // 开始日期
-  endDate: '', // 结束日期
-  activityContent: '', // 活动内容
   photos: '', // 照片JSON
   tenantId: undefined
 })

+ 14 - 12
src/views/social-worker/floor-activity-record/text/AddForm.vue

@@ -16,28 +16,28 @@
             <el-form-item label="记录年月" prop="recordYear">
               <el-date-picker
                 v-if="!isDetail"
-                v-model="dataForm.recordYear"
+                v-model="dataForm.recordMonth"
                 type="month"
                 placeholder="选择年月"
                 value-format="YYYY-MM"
                 style="width: 100%"
                 @change="handleYearChange"
               />
-              <el-text v-else>{{dataForm.recordYear}}</el-text>
+              <el-text v-else>{{dataForm.recordMonth}}</el-text>
             </el-form-item>
           </el-col>
           <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
-            <el-form-item label="第几周" prop="weekNumber">
-              <el-select v-if="!isDetail" v-model="dataForm.weekNumber" placeholder="选择周次" style="width: 100%">
-                <el-option v-for="w in 5" :key="w" :label="'第' + ['一', '二', '三', '四', '五'][w-1] + '周'" :value="w" />
+            <el-form-item label="第几周" prop="week">
+              <el-select v-if="!isDetail" v-model="dataForm.week" placeholder="选择周次" style="width: 100%">
+                <el-option v-for="(w,index) in 5" :key="w" :label="'第' + ['一', '二', '三', '四', '五'][w-1] + '周'" :value="(index+1)" />
               </el-select>
-              <el-text v-else>第{{['一', '二', '三', '四', '五'][dataForm.weekNumber-1]}}周</el-text>
+              <el-text v-else>第{{dataForm.week}}周</el-text>
             </el-form-item>
           </el-col>
           <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
             <el-form-item label="楼栋" prop="floorName">
               <el-select  v-if="!isDetail" v-model="dataForm.buildName" placeholder="选择楼栋" style="width: 100%">
-                <el-option @click="handleBuildChange(item)" v-for="(item,index) in buildList" :key="index" :label="item.buildName" :value="item.buildName" />
+                <el-option @click="handleBuildChange(item)" v-for="(item,index) in buildList" :key="index" :label="item.buildName" :value="item.id" />
               </el-select>
               <el-text v-else>{{dataForm.buildName}}</el-text>
             </el-form-item>
@@ -47,7 +47,7 @@
           <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
             <el-form-item label="楼层" prop="weekNumber">
               <el-select v-if="!isDetail" v-model="dataForm.floorName" placeholder="选择楼层" style="width: 100%">
-                <el-option v-for="(item,index) in floorList" :key="index" :label="item.floorName" :value="item.floorName" />
+                <el-option v-for="(item,index) in floorList" :key="index" :label="item.floorName" :value="item.id" />
               </el-select>
               <el-text v-else>{{dataForm.floorName}}</el-text>
             </el-form-item>
@@ -71,7 +71,7 @@
 
           <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
             <el-form-item label="参与长者">
-              <el-input type="textarea" placeholder="需要注意,这里的长者会用于列表页的长者名称模糊搜索" maxlength="500" show-word-limit :rows="4">{{ dateRangeText }}</el-input>
+              <el-input type="textarea" placeholder="输入参与长者,逗号分开" maxlength="500" show-word-limit :rows="4">{{ dateRangeText }}</el-input>
             </el-form-item>
           </el-col>
         </el-row>
@@ -255,9 +255,11 @@ const initExecutionRecord = () => {
 // 表单数据
 let dataForm = ref({
   id: undefined,
-  recordYear: dayjs().format('YYYY-MM'), // 记录年份
-  recordMonth: dayjs().month() + 1, // 记录月份
-  weekNumber: 1, // 第几周
+  recordMonth: dayjs().format('YYYY-MM'), // 记录年份
+  week: 1, // 第几周
+  buidId: '',
+  floorId: '',
+  elderName: '',
   floorName: '', // 养护楼层
   recordTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), // 记录时间
   startDate: '', // 开始日期