AddForm.vue 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. <template>
  2. <el-drawer v-model="dialogVisible" :title="title" size="95%" :before-close="handleClosed">
  3. <div class="assessment-form">
  4. <div class="form-header">
  5. <el-form :model="dataForm" :rules="rules" ref="formRef" label-width="80px">
  6. <el-row :gutter="20">
  7. <el-col :span="6">
  8. <el-form-item label="姓名" prop="elderName">
  9. <SelectElder
  10. ref="selectElderRef" :tId="dataForm.tenantId" @elder="elderUp" :disabled="isDetail"
  11. v-model="dataForm.elderId" />
  12. </el-form-item>
  13. </el-col>
  14. <el-col :span="6">
  15. <el-form-item label="床号">
  16. <el-input v-model="dataForm.bedName" disabled />
  17. </el-form-item>
  18. </el-col>
  19. <el-col :span="6">
  20. <el-form-item label="性别">
  21. <el-input v-model="dataForm.elderSex" disabled />
  22. </el-form-item>
  23. </el-col>
  24. <el-col :span="6">
  25. <el-form-item label="年龄">
  26. <el-input v-model="dataForm.elderAge" disabled />
  27. </el-form-item>
  28. </el-col>
  29. </el-row>
  30. <el-row :gutter="20">
  31. <el-col :span="6">
  32. <el-form-item label="评估日期">
  33. <el-date-picker
  34. v-model="form.assessDate"
  35. type="date"
  36. placeholder="选择日期"
  37. value-format="YYYY-MM-DD"
  38. :disabled="isDetail"
  39. style="width: 100%"
  40. />
  41. </el-form-item>
  42. </el-col>
  43. </el-row>
  44. </el-form>
  45. </div>
  46. <!-- Barthel指数评分表 -->
  47. <div class="barthel-section">
  48. <div class="section-title">日常生活活动能力评估表(Barthel指数评分标准)</div>
  49. <table class="assessment-table">
  50. <thead>
  51. <tr>
  52. <th class="col-item">项目</th>
  53. <th class="col-score">分数</th>
  54. <th class="col-content">内容</th>
  55. <th class="col-result">得分</th>
  56. </tr>
  57. </thead>
  58. <tbody>
  59. <!-- 1. 大便控制 -->
  60. <tr>
  61. <td class="col-item" rowspan="3">1. 大便控制</td>
  62. <td class="col-score">10</td>
  63. <td class="col-content">
  64. <el-radio :label="10" v-model="form.scores[0]" :disabled="isDetail" @change="calculateTotal">无大便失禁,并可自行使用塞剂。</el-radio>
  65. </td>
  66. <td class="col-result" rowspan="3">
  67. <span class="score-display">{{ form.scores[0] }}</span>
  68. </td>
  69. </tr>
  70. <tr>
  71. <td class="col-score">5</td>
  72. <td class="col-content">
  73. <el-radio :label="5" v-model="form.scores[0]" :disabled="isDetail" @change="calculateTotal">偶有失禁(每周不超过一次)或使用塞剂时需人帮助。</el-radio>
  74. </td>
  75. </tr>
  76. <tr>
  77. <td class="col-score">0</td>
  78. <td class="col-content">
  79. <el-radio :label="0" v-model="form.scores[0]" :disabled="isDetail" @change="calculateTotal">需别人处理。</el-radio>
  80. </td>
  81. </tr>
  82. <!-- 2. 小便控制 -->
  83. <tr>
  84. <td class="col-item" rowspan="3">2. 小便控制</td>
  85. <td class="col-score">10</td>
  86. <td class="col-content">
  87. <el-radio :label="10" v-model="form.scores[1]" :disabled="isDetail" @change="calculateTotal">日夜皆不会尿失禁,或可自行使用并清理尿套。</el-radio>
  88. </td>
  89. <td class="col-result" rowspan="3">
  90. <span class="score-display">{{ form.scores[1] }}</span>
  91. </td>
  92. </tr>
  93. <tr>
  94. <td class="col-score">5</td>
  95. <td class="col-content">
  96. <el-radio :label="5" v-model="form.scores[1]" :disabled="isDetail" @change="calculateTotal">偶尔会尿失禁(每周不超过一次)或尿急(无法等待便盆或无法及时赶到厕所)或需别人帮助处理尿套。</el-radio>
  97. </td>
  98. </tr>
  99. <tr>
  100. <td class="col-score">0</td>
  101. <td class="col-content">
  102. <el-radio :label="0" v-model="form.scores[1]" :disabled="isDetail" @change="calculateTotal">需别人处理。</el-radio>
  103. </td>
  104. </tr>
  105. <!-- 3. 个人卫生 -->
  106. <tr>
  107. <td class="col-item" rowspan="2">3. 个人卫生</td>
  108. <td class="col-score">5</td>
  109. <td class="col-content">
  110. <el-radio :label="5" v-model="form.scores[2]" :disabled="isDetail" @change="calculateTotal">可独立完成洗脸、洗手、刷牙及梳头发。</el-radio>
  111. </td>
  112. <td class="col-result" rowspan="2">
  113. <span class="score-display">{{ form.scores[2] }}</span>
  114. </td>
  115. </tr>
  116. <tr>
  117. <td class="col-score">0</td>
  118. <td class="col-content">
  119. <el-radio :label="0" v-model="form.scores[2]" :disabled="isDetail" @change="calculateTotal">需别人处理。</el-radio>
  120. </td>
  121. </tr>
  122. <!-- 4. 入厕 -->
  123. <tr>
  124. <td class="col-item" rowspan="3">4. 入厕</td>
  125. <td class="col-score">10</td>
  126. <td class="col-content">
  127. <el-radio :label="10" v-model="form.scores[3]" :disabled="isDetail" @change="calculateTotal">可自行进出厕所,不会弄脏衣物,并能穿好衣服,使用便盆者,可自行清理便盆。</el-radio>
  128. </td>
  129. <td class="col-result" rowspan="3">
  130. <span class="score-display">{{ form.scores[3] }}</span>
  131. </td>
  132. </tr>
  133. <tr>
  134. <td class="col-score">5</td>
  135. <td class="col-content">
  136. <el-radio :label="5" v-model="form.scores[3]" :disabled="isDetail" @change="calculateTotal">需帮助保持姿势平衡、整理衣物或使用卫生纸。使用便盆者,可自行取放,但须依赖他人清理。</el-radio>
  137. </td>
  138. </tr>
  139. <tr>
  140. <td class="col-score">0</td>
  141. <td class="col-content">
  142. <el-radio :label="0" v-model="form.scores[3]" :disabled="isDetail" @change="calculateTotal">需他人帮助。</el-radio>
  143. </td>
  144. </tr>
  145. <!-- 5. 进食 -->
  146. <tr>
  147. <td class="col-item" rowspan="3">5. 进食</td>
  148. <td class="col-score">10</td>
  149. <td class="col-content">
  150. <el-radio :label="10" v-model="form.scores[4]" :disabled="isDetail" @change="calculateTotal">自己在合理的时间内(约10s 吃一口)可用筷子取眼前的食物。若需进食辅具时,应自行穿脱。</el-radio>
  151. </td>
  152. <td class="col-result" rowspan="3">
  153. <span class="score-display">{{ form.scores[4] }}</span>
  154. </td>
  155. </tr>
  156. <tr>
  157. <td class="col-score">5</td>
  158. <td class="col-content">
  159. <el-radio :label="5" v-model="form.scores[4]" :disabled="isDetail" @change="calculateTotal">需别人帮助穿脱进食辅具或只会用汤匙进食。</el-radio>
  160. </td>
  161. </tr>
  162. <tr>
  163. <td class="col-score">0</td>
  164. <td class="col-content">
  165. <el-radio :label="0" v-model="form.scores[4]" :disabled="isDetail" @change="calculateTotal">无法自行取食或耗费时间过长。</el-radio>
  166. </td>
  167. </tr>
  168. <!-- 6. 床和椅转移 -->
  169. <tr>
  170. <td class="col-item" rowspan="4">6. 床和椅转移</td>
  171. <td class="col-score">15</td>
  172. <td class="col-content">
  173. <el-radio :label="15" v-model="form.scores[5]" :disabled="isDetail" @change="calculateTotal">可独立完成,包括轮椅的煞车及移开脚踏板。</el-radio>
  174. </td>
  175. <td class="col-result" rowspan="4">
  176. <span class="score-display">{{ form.scores[5] }}</span>
  177. </td>
  178. </tr>
  179. <tr>
  180. <td class="col-score">10</td>
  181. <td class="col-content">
  182. <el-radio :label="10" v-model="form.scores[5]" :disabled="isDetail" @change="calculateTotal">需要稍微的协助(例如:予以轻扶以保持平衡)或需要口头指导。</el-radio>
  183. </td>
  184. </tr>
  185. <tr>
  186. <td class="col-score">5</td>
  187. <td class="col-content">
  188. <el-radio :label="5" v-model="form.scores[5]" :disabled="isDetail" @change="calculateTotal">可自行从床上坐起,但移位时仍需要别人帮助。</el-radio>
  189. </td>
  190. </tr>
  191. <tr>
  192. <td class="col-score">0</td>
  193. <td class="col-content">
  194. <el-radio :label="0" v-model="form.scores[5]" :disabled="isDetail" @change="calculateTotal">需别人帮助方可坐起来或需别人帮助方可移位。</el-radio>
  195. </td>
  196. </tr>
  197. <!-- 7. 行走于平地上 -->
  198. <tr>
  199. <td class="col-item" rowspan="4">7. 行走于平地上</td>
  200. <td class="col-score">15</td>
  201. <td class="col-content">
  202. <el-radio :label="15" v-model="form.scores[6]" :disabled="isDetail" @change="calculateTotal">使用或不使用辅具皆可独立行走50m 以上。</el-radio>
  203. </td>
  204. <td class="col-result" rowspan="4">
  205. <span class="score-display">{{ form.scores[6] }}</span>
  206. </td>
  207. </tr>
  208. <tr>
  209. <td class="col-score">10</td>
  210. <td class="col-content">
  211. <el-radio :label="10" v-model="form.scores[6]" :disabled="isDetail" @change="calculateTotal">需要稍微的扶持或口头指导方可行走50m 以上。</el-radio>
  212. </td>
  213. </tr>
  214. <tr>
  215. <td class="col-score">5</td>
  216. <td class="col-content">
  217. <el-radio :label="5" v-model="form.scores[6]" :disabled="isDetail" @change="calculateTotal">虽无法行走,但可独立操纵轮椅(包括转弯、进门、接近桌子)。</el-radio>
  218. </td>
  219. </tr>
  220. <tr>
  221. <td class="col-score">0</td>
  222. <td class="col-content">
  223. <el-radio :label="0" v-model="form.scores[6]" :disabled="isDetail" @change="calculateTotal">需别人帮助方可坐起来或需别人帮助方可移位。</el-radio>
  224. </td>
  225. </tr>
  226. <!-- 8. 穿脱衣服 -->
  227. <tr>
  228. <td class="col-item" rowspan="3">8. 穿脱衣服</td>
  229. <td class="col-score">10</td>
  230. <td class="col-content">
  231. <el-radio :label="10" v-model="form.scores[7]" :disabled="isDetail" @change="calculateTotal">可自行穿脱衣服、鞋子及辅具。</el-radio>
  232. </td>
  233. <td class="col-result" rowspan="3">
  234. <span class="score-display">{{ form.scores[7] }}</span>
  235. </td>
  236. </tr>
  237. <tr>
  238. <td class="col-score">5</td>
  239. <td class="col-content">
  240. <el-radio :label="5" v-model="form.scores[7]" :disabled="isDetail" @change="calculateTotal">在别人帮助下,可完成一半以上的上述动作。</el-radio>
  241. </td>
  242. </tr>
  243. <tr>
  244. <td class="col-score">0</td>
  245. <td class="col-content">
  246. <el-radio :label="0" v-model="form.scores[7]" :disabled="isDetail" @change="calculateTotal">不能自行穿脱衣服。</el-radio>
  247. </td>
  248. </tr>
  249. <!-- 9. 上下楼梯 -->
  250. <tr>
  251. <td class="col-item" rowspan="3">9. 上下楼梯</td>
  252. <td class="col-score">10</td>
  253. <td class="col-content">
  254. <el-radio :label="10" v-model="form.scores[8]" :disabled="isDetail" @change="calculateTotal">可自行上下楼梯(包括抓扶手、使用拐杖)。</el-radio>
  255. </td>
  256. <td class="col-result" rowspan="3">
  257. <span class="score-display">{{ form.scores[8] }}</span>
  258. </td>
  259. </tr>
  260. <tr>
  261. <td class="col-score">5</td>
  262. <td class="col-content">
  263. <el-radio :label="5" v-model="form.scores[8]" :disabled="isDetail" @change="calculateTotal">需要稍微帮助或口头指导。</el-radio>
  264. </td>
  265. </tr>
  266. <tr>
  267. <td class="col-score">0</td>
  268. <td class="col-content">
  269. <el-radio :label="0" v-model="form.scores[8]" :disabled="isDetail" @change="calculateTotal">无法上下楼梯。</el-radio>
  270. </td>
  271. </tr>
  272. <!-- 10. 洗澡 -->
  273. <tr>
  274. <td class="col-item" rowspan="2">10. 洗澡</td>
  275. <td class="col-score">5</td>
  276. <td class="col-content">
  277. <el-radio :label="5" v-model="form.scores[9]" :disabled="isDetail" @change="calculateTotal">可独立完成(不论是盆浴或沐浴)。</el-radio>
  278. </td>
  279. <td class="col-result" rowspan="2">
  280. <span class="score-display">{{ form.scores[9] }}</span>
  281. </td>
  282. </tr>
  283. <tr>
  284. <td class="col-score">0</td>
  285. <td class="col-content">
  286. <el-radio :label="0" v-model="form.scores[9]" :disabled="isDetail" @change="calculateTotal">需要别人帮助。</el-radio>
  287. </td>
  288. </tr>
  289. <!-- 总分 -->
  290. <tr class="total-row">
  291. <td class="col-item">总分:</td>
  292. <td class="col-score"></td>
  293. <td class="col-content"></td>
  294. <td class="col-result">
  295. <span class="total-score">{{ form.totalScore }} 分</span>
  296. </td>
  297. </tr>
  298. </tbody>
  299. </table>
  300. <!-- 评分结果 -->
  301. <div class="result-section">
  302. <div class="result-title">评分结果:</div>
  303. <div class="result-rules">
  304. <el-tag :type="form.totalScore < 20 ? 'danger' : ''" class="rule-tag">&lt;20分:生活完全依赖</el-tag>
  305. <el-tag :type="form.totalScore >= 20 && form.totalScore <= 40 ? 'warning' : ''" class="rule-tag">20~40分:生活需要很大帮助</el-tag>
  306. <el-tag :type="form.totalScore > 40 && form.totalScore <= 60 ? 'info' : ''" class="rule-tag">40~60分:生活需要帮忙</el-tag>
  307. <el-tag :type="form.totalScore > 60 ? 'success' : ''" class="rule-tag">&gt;60分:生活基本自理</el-tag>
  308. </div>
  309. <div class="current-result" v-if="form.resultLevel">
  310. <span class="result-label">当前评估结果:</span>
  311. <el-tag :type="getResultTagType(form.resultLevel)" size="large">
  312. {{ getResultText(form.resultLevel) }}
  313. </el-tag>
  314. </div>
  315. </div>
  316. <!-- 评估人签名 -->
  317. <div class="assessor-section">
  318. <el-form-item label="评估人签名:" label-width="100px">
  319. <el-input v-model="form.assessor" :disabled="isDetail" style="width: 300px" />
  320. </el-form-item>
  321. </div>
  322. </div>
  323. </div>
  324. <template #footer>
  325. <el-button @click="handleClosed">关闭</el-button>
  326. <el-button v-if="isDetail" type="success" @click="handleExport">打印</el-button>
  327. <el-button style="margin-left: 22px;margin-right: 30px" v-loading="formLoading" type="primary"
  328. v-show="!isDetail" @click="submitForm">确定</el-button>
  329. </template>
  330. </el-drawer>
  331. </template>
  332. <script lang="ts" setup>
  333. import { computed, ref, reactive } from 'vue'
  334. import dayjs from 'dayjs'
  335. import { useUserStore } from '@/store/modules/user'
  336. import {
  337. dailyLifeCreate,
  338. dailyLifeGetById,
  339. dailyLifeUpdate
  340. } from "@/api/social-work";
  341. const message = useMessage()
  342. const userStore = useUserStore()
  343. const { t } = useI18n()
  344. const title = ref('')
  345. const dialogVisible = ref(false)
  346. const formRef = ref()
  347. const selectElderRef = ref()
  348. const isDetail = ref(false)
  349. const formLoading = ref(false)
  350. let dataForm = ref({
  351. id: undefined,
  352. elderName: '',
  353. elderSex: '',
  354. elderAge: '',
  355. bedName: '',
  356. elderId: '',
  357. tenantId: undefined
  358. })
  359. const elderUp = (e: any) => {
  360. dataForm.value.elderName = e.elderName
  361. dataForm.value.elderId = e.id
  362. dataForm.value.elderSex = e.elderSex === 1 ? '男' : '女'
  363. dataForm.value.bedName = e.bedName || ''
  364. dataForm.value.elderAge = e.elderAge
  365. }
  366. // 表单数据 - 10项评估
  367. const form = reactive({
  368. scores: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // 10项评分
  369. totalScore: 0,
  370. resultLevel: '',
  371. assessDate: '',
  372. assessor: ''
  373. })
  374. // 计算总得分
  375. const calculateTotal = () => {
  376. const total = form.scores.reduce((sum, score) => sum + (score || 0), 0)
  377. form.totalScore = total
  378. // 自动判断结果等级
  379. if (total < 20) {
  380. form.resultLevel = 'complete_dependence'
  381. } else if (total >= 20 && total <= 40) {
  382. form.resultLevel = 'large_help'
  383. } else if (total > 40 && total <= 60) {
  384. form.resultLevel = 'need_help'
  385. } else if (total > 60) {
  386. form.resultLevel = 'basic_independent'
  387. }
  388. }
  389. // 获取结果等级文本
  390. const getResultText = (resultLevel: string) => {
  391. switch (resultLevel) {
  392. case 'complete_dependence': return '生活完全依赖'
  393. case 'large_help': return '生活需要很大帮助'
  394. case 'need_help': return '生活需要帮忙'
  395. case 'basic_independent': return '生活基本自理'
  396. default: return '-'
  397. }
  398. }
  399. // 获取结果等级标签类型
  400. const getResultTagType = (resultLevel: string) => {
  401. switch (resultLevel) {
  402. case 'complete_dependence': return 'danger'
  403. case 'large_help': return 'warning'
  404. case 'need_help': return 'info'
  405. case 'basic_independent': return 'success'
  406. default: return ''
  407. }
  408. }
  409. /** 将表单数据序列化为 JSON 对象 */
  410. const serializeFormData = () => {
  411. return {
  412. scores: form.scores || [],
  413. totalScore: form.totalScore || 0,
  414. resultLevel: form.resultLevel || ''
  415. }
  416. }
  417. /** 将 JSON 对象反序列化为表单数据 */
  418. const deserializeFormData = (formData: Record<string, any>) => {
  419. if (!formData) return
  420. if (formData.scores && formData.scores.length > 0) {
  421. form.scores = formData.scores
  422. } else {
  423. form.scores = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  424. }
  425. form.totalScore = formData.totalScore || 0
  426. form.resultLevel = formData.resultLevel || ''
  427. // assessor 和 assessDate 从 res 直接读取,不从 assessData 中解析
  428. }
  429. /** 重置表单数据 */
  430. const resetForm = () => {
  431. dataForm.value = {
  432. id: undefined,
  433. elderName: '',
  434. elderSex: '',
  435. elderAge: '',
  436. bedName: '',
  437. elderId: '',
  438. tenantId: undefined
  439. }
  440. formRef.value?.resetFields()
  441. form.scores = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  442. form.totalScore = 0
  443. form.resultLevel = ''
  444. form.assessDate = ''
  445. form.assessor = ''
  446. }
  447. /** 打开弹窗 */
  448. const open = async (tenantId: any, id?: any, detail: boolean = false) => {
  449. resetForm()
  450. dialogVisible.value = true
  451. dataForm.value.id = id || undefined
  452. dataForm.value.tenantId = tenantId
  453. isDetail.value = detail
  454. if (id) {
  455. title.value = "编辑-日常生活活动能力评估表"
  456. await loadData(id)
  457. } else {
  458. title.value = "新增-日常生活活动能力评估表"
  459. }
  460. }
  461. /** 加载评估数据 */
  462. const loadData = async (id: number) => {
  463. try {
  464. const res = await dailyLifeGetById(id)
  465. if (res) {
  466. dataForm.value.elderName = res.elderName || ''
  467. dataForm.value.elderId = res.elderId || ''
  468. dataForm.value.elderSex = res.elderSex || ''
  469. dataForm.value.bedName = res.bedName || ''
  470. dataForm.value.elderAge = res.elderAge || ''
  471. form.assessDate = res.assessDate || ''
  472. form.assessor = res.assessor || ''
  473. await selectElderRef.value.upData(res.elderName, res.elderId)
  474. if (res.assessData) {
  475. const formData = JSON.parse(res.assessData)
  476. deserializeFormData(formData)
  477. calculateTotal()
  478. }
  479. }
  480. } catch (error) {
  481. message.error('加载评估数据失败')
  482. }
  483. }
  484. defineExpose({ open })
  485. const emit = defineEmits(['success'])
  486. /** 提交表单 */
  487. const submitForm = async () => {
  488. if (!dataForm.value.elderId) {
  489. message.error('请选择长者')
  490. return
  491. }
  492. formLoading.value = true
  493. try {
  494. const formData = serializeFormData()
  495. const payload = {
  496. id: dataForm.value.id,
  497. elderId: dataForm.value.elderId,
  498. tenantId: dataForm.value.tenantId,
  499. assessData: JSON.stringify(formData),
  500. riskLevel: getResultText(form.resultLevel),
  501. assessScore: form.totalScore || 0,
  502. assessor: form.assessor,
  503. assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''
  504. }
  505. if (dataForm.value.id) {
  506. await dailyLifeUpdate(payload)
  507. message.success(t('common.updateSuccess'))
  508. } else {
  509. await dailyLifeCreate(payload)
  510. message.success(t('common.createSuccess'))
  511. }
  512. dialogVisible.value = false
  513. emit('success')
  514. } catch (error) {
  515. message.error('提交失败')
  516. } finally {
  517. formLoading.value = false
  518. }
  519. }
  520. /** 关闭弹窗 */
  521. const handleClosed = () => {
  522. dialogVisible.value = false
  523. }
  524. /** 导出/打印 */
  525. const handleExport = () => {
  526. // 创建打印窗口
  527. const printWindow = window.open('', '_blank')
  528. if (!printWindow) {
  529. message.error('请允许弹出窗口')
  530. return
  531. }
  532. // 评估项目数据
  533. const assessmentItems = [
  534. { name: '1. 大便控制', options: [{ score: 10, text: '无大便失禁,并可自行使用塞剂' }, { score: 5, text: '偶有失禁(每周不超过一次)或使用塞剂时需人帮助' }, { score: 0, text: '需别人处理' }] },
  535. { name: '2. 小便控制', options: [{ score: 10, text: '日夜皆不会尿失禁,或可自行使用并清理尿套' }, { score: 5, text: '偶尔会尿失禁(每周不超过一次)或尿急或需别人帮助处理尿套' }, { score: 0, text: '需别人处理' }] },
  536. { name: '3. 个人卫生', options: [{ score: 5, text: '可独立完成洗脸、洗手、刷牙及梳头发' }, { score: 0, text: '需别人处理' }] },
  537. { name: '4. 入厕', options: [{ score: 10, text: '可自行进出厕所,不会弄脏衣物,并能穿好衣服,使用便盆者可自行清理便盆' }, { score: 5, text: '需帮助保持姿势平衡、整理衣物或使用卫生纸,使用便盆者可自行取放,但须依赖他人清理' }, { score: 0, text: '需他人帮助' }] },
  538. { name: '5. 进食', options: [{ score: 10, text: '自己在合理的时间内(约10s吃一口)可用筷子取眼前的食物' }, { score: 5, text: '需别人帮助穿脱进食辅具或只会用汤匙进食' }, { score: 0, text: '无法自行取食或耗费时间过长' }] },
  539. { name: '6. 床和椅转移', options: [{ score: 15, text: '可独立完成,包括轮椅的煞车及移开脚踏板' }, { score: 10, text: '需要稍微的协助(例如:予以轻扶以保持平衡)或需要口头指导' }, { score: 5, text: '可自行从床上坐起,但移位时仍需要别人帮助' }, { score: 0, text: '需别人帮助方可坐起来或需别人帮助方可移位' }] },
  540. { name: '7. 行走于平地上', options: [{ score: 15, text: '使用或不使用辅具皆可独立行走50m以上' }, { score: 10, text: '需要稍微的扶持或口头指导方可行走50m以上' }, { score: 5, text: '虽无法行走,但可独立操纵轮椅(包括转弯、进门、接近桌子)' }, { score: 0, text: '需别人帮助方可坐起来或需别人帮助方可移位' }] },
  541. { name: '8. 穿脱衣服', options: [{ score: 10, text: '可自行穿脱衣服、鞋子及辅具' }, { score: 5, text: '在别人帮助下,可完成一半以上的上述动作' }, { score: 0, text: '不能自行穿脱衣服' }] },
  542. { name: '9. 上下楼梯', options: [{ score: 10, text: '可自行上下楼梯(包括抓扶手、使用拐杖)' }, { score: 5, text: '需要稍微帮助或口头指导' }, { score: 0, text: '无法上下楼梯' }] },
  543. { name: '10. 洗澡', options: [{ score: 5, text: '可独立完成(不论是盆浴或沐浴)' }, { score: 0, text: '需要别人帮助' }] }
  544. ]
  545. // 构建打印内容
  546. const tenantName = userStore.getTenantName || '' // 当前登录的机构名称
  547. const printContent = `
  548. <!DOCTYPE html>
  549. <html>
  550. <head>
  551. <meta charset="UTF-8">
  552. <title>日常生活活动能力评估表 - ${dataForm.value.elderName || ''}</title>
  553. <style>
  554. @media print {
  555. @page { size: A4 portrait; margin: 15mm; }
  556. }
  557. body {
  558. font-family: 'SimSun', 'Microsoft YaHei', serif;
  559. font-size: 9pt;
  560. line-height: 1.3;
  561. color: #333;
  562. }
  563. .header {
  564. text-align: center;
  565. margin-bottom: 15px;
  566. border-bottom: 2px solid #333;
  567. padding-bottom: 10px;
  568. }
  569. .header h1 {
  570. font-size: 14pt;
  571. margin: 0;
  572. letter-spacing: 2px;
  573. }
  574. .info-section {
  575. margin-bottom: 15px;
  576. padding: 10px;
  577. border: 1px solid #999;
  578. background: #fafafa;
  579. }
  580. .info-row {
  581. display: flex;
  582. flex-wrap: wrap;
  583. gap: 20px;
  584. }
  585. .info-item {
  586. display: flex;
  587. align-items: center;
  588. }
  589. .info-item .label {
  590. font-weight: bold;
  591. margin-right: 8px;
  592. color: #555;
  593. }
  594. .info-item .value {
  595. border-bottom: 1px solid #333;
  596. min-width: 80px;
  597. padding: 0 5px;
  598. text-align: center;
  599. }
  600. .assessment-table {
  601. width: 100%;
  602. border-collapse: collapse;
  603. margin-bottom: 15px;
  604. font-size: 8pt;
  605. }
  606. .assessment-table th, .assessment-table td {
  607. border: 1px solid #333;
  608. padding: 6px;
  609. text-align: center;
  610. vertical-align: middle;
  611. }
  612. .assessment-table th {
  613. background: #e8e8e8;
  614. font-weight: bold;
  615. }
  616. .assessment-table .col-item {
  617. width: 12%;
  618. font-weight: bold;
  619. background: #f5f5f5;
  620. }
  621. .assessment-table .col-score {
  622. width: 6%;
  623. font-weight: bold;
  624. }
  625. .assessment-table .col-content {
  626. width: 70%;
  627. text-align: left;
  628. }
  629. .assessment-table .col-result {
  630. width: 12%;
  631. font-weight: bold;
  632. }
  633. .total-row {
  634. background: #fff3cd;
  635. font-weight: bold;
  636. }
  637. .result-section {
  638. margin: 15px 0;
  639. padding: 10px;
  640. border: 1px solid #999;
  641. background: #fafafa;
  642. }
  643. .result-title {
  644. font-weight: bold;
  645. margin-bottom: 10px;
  646. }
  647. .result-rules {
  648. display: flex;
  649. flex-wrap: wrap;
  650. gap: 10px;
  651. margin-bottom: 10px;
  652. }
  653. .result-rule {
  654. padding: 5px 10px;
  655. border-radius: 4px;
  656. }
  657. .current-result {
  658. display: flex;
  659. align-items: center;
  660. gap: 10px;
  661. padding-top: 10px;
  662. border-top: 1px solid #ccc;
  663. }
  664. .result-label {
  665. font-weight: bold;
  666. }
  667. .score-value {
  668. color: #d9534f;
  669. font-weight: bold;
  670. font-size: 14pt;
  671. }
  672. .assessor-section {
  673. margin: 15px 0;
  674. padding: 10px;
  675. border: 1px solid #999;
  676. background: #fafafa;
  677. }
  678. .assessor-row {
  679. display: flex;
  680. gap: 30px;
  681. }
  682. .assessor-item {
  683. display: flex;
  684. align-items: center;
  685. }
  686. .assessor-item .label {
  687. font-weight: bold;
  688. margin-right: 8px;
  689. }
  690. .assessor-item .value {
  691. border-bottom: 1px solid #333;
  692. min-width: 120px;
  693. padding: 0 5px;
  694. text-align: center;
  695. }
  696. </style>
  697. </head>
  698. <body>
  699. <div class="tenant-name" style="text-align: end;width: 100%;font-size: 16px; font-weight: bold; margin-bottom: 10px;">${tenantName}</div>
  700. <div class="header">
  701. <h1>日常生活活动能力评估表(Barthel指数评分标准)</h1>
  702. </div>
  703. <div class="info-section">
  704. <div class="info-row">
  705. <div class="info-item">
  706. <span class="label">长者姓名:</span>
  707. <span class="value">${dataForm.value.elderName || ''}</span>
  708. </div>
  709. <div class="info-item">
  710. <span class="label">性别:</span>
  711. <span class="value">${dataForm.value.elderSex || ''}</span>
  712. </div>
  713. <div class="info-item">
  714. <span class="label">年龄:</span>
  715. <span class="value">${dataForm.value.elderAge || ''}</span>
  716. </div>
  717. <div class="info-item">
  718. <span class="label">床号:</span>
  719. <span class="value">${dataForm.value.bedName || ''}</span>
  720. </div>
  721. <div class="info-item">
  722. <span class="label">评估日期:</span>
  723. <span class="value">${form.assessDate || ''}</span>
  724. </div>
  725. </div>
  726. </div>
  727. <!-- Barthel指数评分表 -->
  728. <table class="assessment-table">
  729. <thead>
  730. <tr>
  731. <th class="col-item">项目</th>
  732. <th class="col-score">分数</th>
  733. <th class="col-content">内容</th>
  734. <th class="col-result">得分</th>
  735. </tr>
  736. </thead>
  737. <tbody>
  738. ${assessmentItems.map((item, index) => {
  739. const currentScore = form.scores[index] || 0
  740. return `
  741. ${item.options.map((opt, optIndex) => `
  742. <tr>
  743. ${optIndex === 0 ? `<td class="col-item" rowspan="${item.options.length}">${item.name}</td>` : ''}
  744. <td class="col-score">${opt.score}</td>
  745. <td class="col-content">${currentScore === opt.score ? '☑' : '☐'} ${opt.text}</td>
  746. ${optIndex === 0 ? `<td class="col-result" rowspan="${item.options.length}">${currentScore}</td>` : ''}
  747. </tr>
  748. `).join('')}
  749. `
  750. }).join('')}
  751. <tr class="total-row">
  752. <td class="col-item">总分:</td>
  753. <td class="col-score"></td>
  754. <td class="col-content"></td>
  755. <td class="col-result">${form.totalScore} 分</td>
  756. </tr>
  757. </tbody>
  758. </table>
  759. <!-- 评分结果 -->
  760. <div class="result-section">
  761. <div class="result-title">评分结果:</div>
  762. <div class="result-rules">
  763. <span class="result-rule" style="background: ${form.totalScore < 20 ? '#f8d7da' : '#e8e8e8'}">${form.totalScore < 20 ? '☑' : '☐'} &lt;20分:生活完全依赖</span>
  764. <span class="result-rule" style="background: ${form.totalScore >= 20 && form.totalScore <= 40 ? '#fff3cd' : '#e8e8e8'}">${form.totalScore >= 20 && form.totalScore <= 40 ? '☑' : '☐'} 20~40分:生活需要很大帮助</span>
  765. <span class="result-rule" style="background: ${form.totalScore > 40 && form.totalScore <= 60 ? '#d1ecf1' : '#e8e8e8'}">${form.totalScore > 40 && form.totalScore <= 60 ? '☑' : '☐'} 40~60分:生活需要帮忙</span>
  766. <span class="result-rule" style="background: ${form.totalScore > 60 ? '#d4edda' : '#e8e8e8'}">${form.totalScore > 60 ? '☑' : '☐'} &gt;60分:生活基本自理</span>
  767. </div>
  768. ${form.resultLevel ? `
  769. <div class="current-result">
  770. <span class="result-label">当前评估结果:</span>
  771. <span class="score-value">${getResultText(form.resultLevel)}</span>
  772. </div>
  773. ` : ''}
  774. </div>
  775. <!-- 评估人签名 -->
  776. <div class="assessor-section">
  777. <div class="assessor-row">
  778. <div class="assessor-item">
  779. <span class="label">评估人签名:</span>
  780. <span class="value">${form.assessor || ''}</span>
  781. </div>
  782. </div>
  783. </div>
  784. </body>
  785. </html>
  786. `
  787. // 写入内容并打印
  788. printWindow.document.write(printContent)
  789. printWindow.document.close()
  790. // 延迟打印,确保样式加载完成
  791. setTimeout(() => {
  792. printWindow.print()
  793. }, 500)
  794. }
  795. const rules = {
  796. elderName: [{ required: true, message: '请选择长者', trigger: 'change' }]
  797. }
  798. </script>
  799. <style scoped lang="scss">
  800. .assessment-form {
  801. padding: 0 20px;
  802. .form-header {
  803. margin-bottom: 20px;
  804. }
  805. .barthel-section {
  806. margin-bottom: 20px;
  807. .section-title {
  808. font-size: 16px;
  809. font-weight: bold;
  810. margin-bottom: 15px;
  811. color: #333;
  812. border-left: 4px solid #409eff;
  813. padding-left: 10px;
  814. }
  815. .assessment-table {
  816. width: 100%;
  817. border: 1px solid #e4e7ed;
  818. border-radius: 4px;
  819. border-collapse: collapse;
  820. thead {
  821. background-color: #f5f7fa;
  822. font-weight: bold;
  823. th {
  824. padding: 12px;
  825. border: 1px solid #e4e7ed;
  826. text-align: center;
  827. }
  828. }
  829. tbody {
  830. tr {
  831. border-bottom: 1px solid #e4e7ed;
  832. &:last-child {
  833. border-bottom: none;
  834. }
  835. td {
  836. padding: 12px;
  837. border: 1px solid #e4e7ed;
  838. }
  839. .col-item {
  840. width: 15%;
  841. text-align: center;
  842. font-weight: bold;
  843. vertical-align: middle;
  844. }
  845. .col-score {
  846. width: 10%;
  847. text-align: center;
  848. vertical-align: middle;
  849. }
  850. .col-content {
  851. width: 65%;
  852. vertical-align: middle;
  853. .el-radio {
  854. white-space: normal;
  855. line-height: 1.5;
  856. height: auto;
  857. margin-right: 0;
  858. }
  859. }
  860. .col-result {
  861. width: 10%;
  862. text-align: center;
  863. vertical-align: middle;
  864. .score-display {
  865. font-size: 16px;
  866. font-weight: bold;
  867. color: #409eff;
  868. }
  869. }
  870. }
  871. .total-row {
  872. background-color: #f5f7fa;
  873. font-weight: bold;
  874. .total-score {
  875. font-size: 18px;
  876. font-weight: bold;
  877. color: #f56c6c;
  878. }
  879. }
  880. }
  881. }
  882. .result-section {
  883. margin-top: 15px;
  884. padding: 15px;
  885. background-color: #f5f7fa;
  886. border-radius: 4px;
  887. .result-title {
  888. font-weight: bold;
  889. margin-bottom: 10px;
  890. }
  891. .result-rules {
  892. margin-bottom: 15px;
  893. .rule-tag {
  894. margin-right: 10px;
  895. margin-bottom: 5px;
  896. }
  897. }
  898. .current-result {
  899. .result-label {
  900. font-weight: bold;
  901. margin-right: 10px;
  902. }
  903. }
  904. }
  905. .assessor-section {
  906. margin-top: 20px;
  907. padding: 15px;
  908. border: 1px solid #e4e7ed;
  909. border-radius: 4px;
  910. }
  911. }
  912. .api-params-section {
  913. margin-top: 30px;
  914. padding: 20px;
  915. background-color: #f5f7fa;
  916. border: 1px solid #e4e7ed;
  917. border-radius: 4px;
  918. .section-title {
  919. font-size: 16px;
  920. font-weight: bold;
  921. margin-bottom: 15px;
  922. color: #333;
  923. border-left: 4px solid #67c23a;
  924. padding-left: 10px;
  925. }
  926. .risk-rules {
  927. margin-top: 15px;
  928. padding: 10px;
  929. background-color: #fff;
  930. border-radius: 4px;
  931. .rules-title {
  932. font-weight: bold;
  933. margin-bottom: 10px;
  934. color: #606266;
  935. }
  936. .rule-tag {
  937. margin-right: 10px;
  938. margin-bottom: 5px;
  939. }
  940. }
  941. }
  942. }
  943. </style>