AddForm.vue 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020
  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 {
  336. dailyLifeCreate,
  337. dailyLifeGetById,
  338. dailyLifeUpdate
  339. } from "@/api/social-work";
  340. const message = useMessage()
  341. const { t } = useI18n()
  342. const title = ref('')
  343. const dialogVisible = ref(false)
  344. const formRef = ref()
  345. const selectElderRef = ref()
  346. const isDetail = ref(false)
  347. const formLoading = ref(false)
  348. let dataForm = ref({
  349. id: undefined,
  350. elderName: '',
  351. elderSex: '',
  352. elderAge: '',
  353. bedName: '',
  354. elderId: '',
  355. tenantId: undefined
  356. })
  357. const elderUp = (e: any) => {
  358. dataForm.value.elderName = e.elderName
  359. dataForm.value.elderId = e.id
  360. dataForm.value.elderSex = e.elderSex === 1 ? '男' : '女'
  361. dataForm.value.bedName = e.bedName || ''
  362. dataForm.value.elderAge = e.elderAge
  363. }
  364. // 表单数据 - 10项评估
  365. const form = reactive({
  366. scores: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // 10项评分
  367. totalScore: 0,
  368. resultLevel: '',
  369. assessDate: '',
  370. assessor: ''
  371. })
  372. // 计算总得分
  373. const calculateTotal = () => {
  374. const total = form.scores.reduce((sum, score) => sum + (score || 0), 0)
  375. form.totalScore = total
  376. // 自动判断结果等级
  377. if (total < 20) {
  378. form.resultLevel = 'complete_dependence'
  379. } else if (total >= 20 && total <= 40) {
  380. form.resultLevel = 'large_help'
  381. } else if (total > 40 && total <= 60) {
  382. form.resultLevel = 'need_help'
  383. } else if (total > 60) {
  384. form.resultLevel = 'basic_independent'
  385. }
  386. }
  387. // 获取结果等级文本
  388. const getResultText = (resultLevel: string) => {
  389. switch (resultLevel) {
  390. case 'complete_dependence': return '生活完全依赖'
  391. case 'large_help': return '生活需要很大帮助'
  392. case 'need_help': return '生活需要帮忙'
  393. case 'basic_independent': return '生活基本自理'
  394. default: return '-'
  395. }
  396. }
  397. // 获取结果等级标签类型
  398. const getResultTagType = (resultLevel: string) => {
  399. switch (resultLevel) {
  400. case 'complete_dependence': return 'danger'
  401. case 'large_help': return 'warning'
  402. case 'need_help': return 'info'
  403. case 'basic_independent': return 'success'
  404. default: return ''
  405. }
  406. }
  407. /** 将表单数据序列化为 JSON 对象 */
  408. const serializeFormData = () => {
  409. return {
  410. scores: form.scores || [],
  411. totalScore: form.totalScore || 0,
  412. resultLevel: form.resultLevel || ''
  413. }
  414. }
  415. /** 将 JSON 对象反序列化为表单数据 */
  416. const deserializeFormData = (formData: Record<string, any>) => {
  417. if (!formData) return
  418. if (formData.scores && formData.scores.length > 0) {
  419. form.scores = formData.scores
  420. } else {
  421. form.scores = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  422. }
  423. form.totalScore = formData.totalScore || 0
  424. form.resultLevel = formData.resultLevel || ''
  425. // assessor 和 assessDate 从 res 直接读取,不从 assessData 中解析
  426. }
  427. /** 重置表单数据 */
  428. const resetForm = () => {
  429. dataForm.value = {
  430. id: undefined,
  431. elderName: '',
  432. elderSex: '',
  433. elderAge: '',
  434. bedName: '',
  435. elderId: '',
  436. tenantId: undefined
  437. }
  438. formRef.value?.resetFields()
  439. form.scores = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  440. form.totalScore = 0
  441. form.resultLevel = ''
  442. form.assessDate = ''
  443. form.assessor = ''
  444. }
  445. /** 打开弹窗 */
  446. const open = async (tenantId: any, id?: any, detail: boolean = false) => {
  447. resetForm()
  448. dialogVisible.value = true
  449. dataForm.value.id = id || undefined
  450. dataForm.value.tenantId = tenantId
  451. isDetail.value = detail
  452. if (id) {
  453. title.value = "编辑-日常生活活动能力评估表"
  454. await loadData(id)
  455. } else {
  456. title.value = "新增-日常生活活动能力评估表"
  457. }
  458. }
  459. /** 加载评估数据 */
  460. const loadData = async (id: number) => {
  461. try {
  462. const res = await dailyLifeGetById(id)
  463. if (res) {
  464. dataForm.value.elderName = res.elderName || ''
  465. dataForm.value.elderId = res.elderId || ''
  466. dataForm.value.elderSex = res.elderSex || ''
  467. dataForm.value.bedName = res.bedName || ''
  468. dataForm.value.elderAge = res.elderAge || ''
  469. form.assessDate = res.assessDate || ''
  470. form.assessor = res.assessor || ''
  471. await selectElderRef.value.upData(res.elderName, res.elderId)
  472. if (res.assessData) {
  473. const formData = JSON.parse(res.assessData)
  474. deserializeFormData(formData)
  475. calculateTotal()
  476. }
  477. }
  478. } catch (error) {
  479. message.error('加载评估数据失败')
  480. }
  481. }
  482. defineExpose({ open })
  483. const emit = defineEmits(['success'])
  484. /** 提交表单 */
  485. const submitForm = async () => {
  486. if (!dataForm.value.elderId) {
  487. message.error('请选择长者')
  488. return
  489. }
  490. formLoading.value = true
  491. try {
  492. const formData = serializeFormData()
  493. const payload = {
  494. id: dataForm.value.id,
  495. elderId: dataForm.value.elderId,
  496. tenantId: dataForm.value.tenantId,
  497. assessData: JSON.stringify(formData),
  498. riskLevel: getResultText(form.resultLevel),
  499. assessScore: form.totalScore || 0,
  500. assessor: form.assessor,
  501. assessDate: form.assessDate ? dayjs(form.assessDate).format('YYYY-MM-DD') : ''
  502. }
  503. if (dataForm.value.id) {
  504. await dailyLifeUpdate(payload)
  505. message.success(t('common.updateSuccess'))
  506. } else {
  507. await dailyLifeCreate(payload)
  508. message.success(t('common.createSuccess'))
  509. }
  510. dialogVisible.value = false
  511. emit('success')
  512. } catch (error) {
  513. message.error('提交失败')
  514. } finally {
  515. formLoading.value = false
  516. }
  517. }
  518. /** 关闭弹窗 */
  519. const handleClosed = () => {
  520. dialogVisible.value = false
  521. }
  522. /** 导出/打印 */
  523. const handleExport = () => {
  524. // 创建打印窗口
  525. const printWindow = window.open('', '_blank')
  526. if (!printWindow) {
  527. message.error('请允许弹出窗口')
  528. return
  529. }
  530. // 评估项目数据
  531. const assessmentItems = [
  532. { name: '1. 大便控制', options: [{ score: 10, text: '无大便失禁,并可自行使用塞剂' }, { score: 5, text: '偶有失禁(每周不超过一次)或使用塞剂时需人帮助' }, { score: 0, text: '需别人处理' }] },
  533. { name: '2. 小便控制', options: [{ score: 10, text: '日夜皆不会尿失禁,或可自行使用并清理尿套' }, { score: 5, text: '偶尔会尿失禁(每周不超过一次)或尿急或需别人帮助处理尿套' }, { score: 0, text: '需别人处理' }] },
  534. { name: '3. 个人卫生', options: [{ score: 5, text: '可独立完成洗脸、洗手、刷牙及梳头发' }, { score: 0, text: '需别人处理' }] },
  535. { name: '4. 入厕', options: [{ score: 10, text: '可自行进出厕所,不会弄脏衣物,并能穿好衣服,使用便盆者可自行清理便盆' }, { score: 5, text: '需帮助保持姿势平衡、整理衣物或使用卫生纸,使用便盆者可自行取放,但须依赖他人清理' }, { score: 0, text: '需他人帮助' }] },
  536. { name: '5. 进食', options: [{ score: 10, text: '自己在合理的时间内(约10s吃一口)可用筷子取眼前的食物' }, { score: 5, text: '需别人帮助穿脱进食辅具或只会用汤匙进食' }, { score: 0, text: '无法自行取食或耗费时间过长' }] },
  537. { name: '6. 床和椅转移', options: [{ score: 15, text: '可独立完成,包括轮椅的煞车及移开脚踏板' }, { score: 10, text: '需要稍微的协助(例如:予以轻扶以保持平衡)或需要口头指导' }, { score: 5, text: '可自行从床上坐起,但移位时仍需要别人帮助' }, { score: 0, text: '需别人帮助方可坐起来或需别人帮助方可移位' }] },
  538. { name: '7. 行走于平地上', options: [{ score: 15, text: '使用或不使用辅具皆可独立行走50m以上' }, { score: 10, text: '需要稍微的扶持或口头指导方可行走50m以上' }, { score: 5, text: '虽无法行走,但可独立操纵轮椅(包括转弯、进门、接近桌子)' }, { score: 0, text: '需别人帮助方可坐起来或需别人帮助方可移位' }] },
  539. { name: '8. 穿脱衣服', options: [{ score: 10, text: '可自行穿脱衣服、鞋子及辅具' }, { score: 5, text: '在别人帮助下,可完成一半以上的上述动作' }, { score: 0, text: '不能自行穿脱衣服' }] },
  540. { name: '9. 上下楼梯', options: [{ score: 10, text: '可自行上下楼梯(包括抓扶手、使用拐杖)' }, { score: 5, text: '需要稍微帮助或口头指导' }, { score: 0, text: '无法上下楼梯' }] },
  541. { name: '10. 洗澡', options: [{ score: 5, text: '可独立完成(不论是盆浴或沐浴)' }, { score: 0, text: '需要别人帮助' }] }
  542. ]
  543. // 构建打印内容
  544. const printContent = `
  545. <!DOCTYPE html>
  546. <html>
  547. <head>
  548. <meta charset="UTF-8">
  549. <title>日常生活活动能力评估表 - ${dataForm.value.elderName || ''}</title>
  550. <style>
  551. @media print {
  552. @page { size: A4 portrait; margin: 15mm; }
  553. }
  554. body {
  555. font-family: 'SimSun', 'Microsoft YaHei', serif;
  556. font-size: 9pt;
  557. line-height: 1.3;
  558. color: #333;
  559. }
  560. .header {
  561. text-align: center;
  562. margin-bottom: 15px;
  563. border-bottom: 2px solid #333;
  564. padding-bottom: 10px;
  565. }
  566. .header h1 {
  567. font-size: 14pt;
  568. margin: 0;
  569. letter-spacing: 2px;
  570. }
  571. .info-section {
  572. margin-bottom: 15px;
  573. padding: 10px;
  574. border: 1px solid #999;
  575. background: #fafafa;
  576. }
  577. .info-row {
  578. display: flex;
  579. flex-wrap: wrap;
  580. gap: 20px;
  581. }
  582. .info-item {
  583. display: flex;
  584. align-items: center;
  585. }
  586. .info-item .label {
  587. font-weight: bold;
  588. margin-right: 8px;
  589. color: #555;
  590. }
  591. .info-item .value {
  592. border-bottom: 1px solid #333;
  593. min-width: 80px;
  594. padding: 0 5px;
  595. text-align: center;
  596. }
  597. .assessment-table {
  598. width: 100%;
  599. border-collapse: collapse;
  600. margin-bottom: 15px;
  601. font-size: 8pt;
  602. }
  603. .assessment-table th, .assessment-table td {
  604. border: 1px solid #333;
  605. padding: 6px;
  606. text-align: center;
  607. vertical-align: middle;
  608. }
  609. .assessment-table th {
  610. background: #e8e8e8;
  611. font-weight: bold;
  612. }
  613. .assessment-table .col-item {
  614. width: 12%;
  615. font-weight: bold;
  616. background: #f5f5f5;
  617. }
  618. .assessment-table .col-score {
  619. width: 6%;
  620. font-weight: bold;
  621. }
  622. .assessment-table .col-content {
  623. width: 70%;
  624. text-align: left;
  625. }
  626. .assessment-table .col-result {
  627. width: 12%;
  628. font-weight: bold;
  629. }
  630. .total-row {
  631. background: #fff3cd;
  632. font-weight: bold;
  633. }
  634. .result-section {
  635. margin: 15px 0;
  636. padding: 10px;
  637. border: 1px solid #999;
  638. background: #fafafa;
  639. }
  640. .result-title {
  641. font-weight: bold;
  642. margin-bottom: 10px;
  643. }
  644. .result-rules {
  645. display: flex;
  646. flex-wrap: wrap;
  647. gap: 10px;
  648. margin-bottom: 10px;
  649. }
  650. .result-rule {
  651. padding: 5px 10px;
  652. border-radius: 4px;
  653. }
  654. .current-result {
  655. display: flex;
  656. align-items: center;
  657. gap: 10px;
  658. padding-top: 10px;
  659. border-top: 1px solid #ccc;
  660. }
  661. .result-label {
  662. font-weight: bold;
  663. }
  664. .score-value {
  665. color: #d9534f;
  666. font-weight: bold;
  667. font-size: 14pt;
  668. }
  669. .assessor-section {
  670. margin: 15px 0;
  671. padding: 10px;
  672. border: 1px solid #999;
  673. background: #fafafa;
  674. }
  675. .assessor-row {
  676. display: flex;
  677. gap: 30px;
  678. }
  679. .assessor-item {
  680. display: flex;
  681. align-items: center;
  682. }
  683. .assessor-item .label {
  684. font-weight: bold;
  685. margin-right: 8px;
  686. }
  687. .assessor-item .value {
  688. border-bottom: 1px solid #333;
  689. min-width: 120px;
  690. padding: 0 5px;
  691. text-align: center;
  692. }
  693. </style>
  694. </head>
  695. <body>
  696. <div class="header">
  697. <h1>日常生活活动能力评估表(Barthel指数评分标准)</h1>
  698. </div>
  699. <div class="info-section">
  700. <div class="info-row">
  701. <div class="info-item">
  702. <span class="label">长者姓名:</span>
  703. <span class="value">${dataForm.value.elderName || ''}</span>
  704. </div>
  705. <div class="info-item">
  706. <span class="label">性别:</span>
  707. <span class="value">${dataForm.value.elderSex || ''}</span>
  708. </div>
  709. <div class="info-item">
  710. <span class="label">年龄:</span>
  711. <span class="value">${dataForm.value.elderAge || ''}</span>
  712. </div>
  713. <div class="info-item">
  714. <span class="label">床号:</span>
  715. <span class="value">${dataForm.value.bedName || ''}</span>
  716. </div>
  717. <div class="info-item">
  718. <span class="label">评估日期:</span>
  719. <span class="value">${form.assessDate || ''}</span>
  720. </div>
  721. </div>
  722. </div>
  723. <!-- Barthel指数评分表 -->
  724. <table class="assessment-table">
  725. <thead>
  726. <tr>
  727. <th class="col-item">项目</th>
  728. <th class="col-score">分数</th>
  729. <th class="col-content">内容</th>
  730. <th class="col-result">得分</th>
  731. </tr>
  732. </thead>
  733. <tbody>
  734. ${assessmentItems.map((item, index) => {
  735. const currentScore = form.scores[index] || 0
  736. return `
  737. ${item.options.map((opt, optIndex) => `
  738. <tr>
  739. ${optIndex === 0 ? `<td class="col-item" rowspan="${item.options.length}">${item.name}</td>` : ''}
  740. <td class="col-score">${opt.score}</td>
  741. <td class="col-content">${currentScore === opt.score ? '☑' : '☐'} ${opt.text}</td>
  742. ${optIndex === 0 ? `<td class="col-result" rowspan="${item.options.length}">${currentScore}</td>` : ''}
  743. </tr>
  744. `).join('')}
  745. `
  746. }).join('')}
  747. <tr class="total-row">
  748. <td class="col-item">总分:</td>
  749. <td class="col-score"></td>
  750. <td class="col-content"></td>
  751. <td class="col-result">${form.totalScore} 分</td>
  752. </tr>
  753. </tbody>
  754. </table>
  755. <!-- 评分结果 -->
  756. <div class="result-section">
  757. <div class="result-title">评分结果:</div>
  758. <div class="result-rules">
  759. <span class="result-rule" style="background: ${form.totalScore < 20 ? '#f8d7da' : '#e8e8e8'}">${form.totalScore < 20 ? '☑' : '☐'} &lt;20分:生活完全依赖</span>
  760. <span class="result-rule" style="background: ${form.totalScore >= 20 && form.totalScore <= 40 ? '#fff3cd' : '#e8e8e8'}">${form.totalScore >= 20 && form.totalScore <= 40 ? '☑' : '☐'} 20~40分:生活需要很大帮助</span>
  761. <span class="result-rule" style="background: ${form.totalScore > 40 && form.totalScore <= 60 ? '#d1ecf1' : '#e8e8e8'}">${form.totalScore > 40 && form.totalScore <= 60 ? '☑' : '☐'} 40~60分:生活需要帮忙</span>
  762. <span class="result-rule" style="background: ${form.totalScore > 60 ? '#d4edda' : '#e8e8e8'}">${form.totalScore > 60 ? '☑' : '☐'} &gt;60分:生活基本自理</span>
  763. </div>
  764. ${form.resultLevel ? `
  765. <div class="current-result">
  766. <span class="result-label">当前评估结果:</span>
  767. <span class="score-value">${getResultText(form.resultLevel)}</span>
  768. </div>
  769. ` : ''}
  770. </div>
  771. <!-- 评估人签名 -->
  772. <div class="assessor-section">
  773. <div class="assessor-row">
  774. <div class="assessor-item">
  775. <span class="label">评估人签名:</span>
  776. <span class="value">${form.assessor || ''}</span>
  777. </div>
  778. </div>
  779. </div>
  780. </body>
  781. </html>
  782. `
  783. // 写入内容并打印
  784. printWindow.document.write(printContent)
  785. printWindow.document.close()
  786. // 延迟打印,确保样式加载完成
  787. setTimeout(() => {
  788. printWindow.print()
  789. }, 500)
  790. }
  791. const rules = {
  792. elderName: [{ required: true, message: '请选择长者', trigger: 'change' }]
  793. }
  794. </script>
  795. <style scoped lang="scss">
  796. .assessment-form {
  797. padding: 0 20px;
  798. .form-header {
  799. margin-bottom: 20px;
  800. }
  801. .barthel-section {
  802. margin-bottom: 20px;
  803. .section-title {
  804. font-size: 16px;
  805. font-weight: bold;
  806. margin-bottom: 15px;
  807. color: #333;
  808. border-left: 4px solid #409eff;
  809. padding-left: 10px;
  810. }
  811. .assessment-table {
  812. width: 100%;
  813. border: 1px solid #e4e7ed;
  814. border-radius: 4px;
  815. border-collapse: collapse;
  816. thead {
  817. background-color: #f5f7fa;
  818. font-weight: bold;
  819. th {
  820. padding: 12px;
  821. border: 1px solid #e4e7ed;
  822. text-align: center;
  823. }
  824. }
  825. tbody {
  826. tr {
  827. border-bottom: 1px solid #e4e7ed;
  828. &:last-child {
  829. border-bottom: none;
  830. }
  831. td {
  832. padding: 12px;
  833. border: 1px solid #e4e7ed;
  834. }
  835. .col-item {
  836. width: 15%;
  837. text-align: center;
  838. font-weight: bold;
  839. vertical-align: middle;
  840. }
  841. .col-score {
  842. width: 10%;
  843. text-align: center;
  844. vertical-align: middle;
  845. }
  846. .col-content {
  847. width: 65%;
  848. vertical-align: middle;
  849. .el-radio {
  850. white-space: normal;
  851. line-height: 1.5;
  852. height: auto;
  853. margin-right: 0;
  854. }
  855. }
  856. .col-result {
  857. width: 10%;
  858. text-align: center;
  859. vertical-align: middle;
  860. .score-display {
  861. font-size: 16px;
  862. font-weight: bold;
  863. color: #409eff;
  864. }
  865. }
  866. }
  867. .total-row {
  868. background-color: #f5f7fa;
  869. font-weight: bold;
  870. .total-score {
  871. font-size: 18px;
  872. font-weight: bold;
  873. color: #f56c6c;
  874. }
  875. }
  876. }
  877. }
  878. .result-section {
  879. margin-top: 15px;
  880. padding: 15px;
  881. background-color: #f5f7fa;
  882. border-radius: 4px;
  883. .result-title {
  884. font-weight: bold;
  885. margin-bottom: 10px;
  886. }
  887. .result-rules {
  888. margin-bottom: 15px;
  889. .rule-tag {
  890. margin-right: 10px;
  891. margin-bottom: 5px;
  892. }
  893. }
  894. .current-result {
  895. .result-label {
  896. font-weight: bold;
  897. margin-right: 10px;
  898. }
  899. }
  900. }
  901. .assessor-section {
  902. margin-top: 20px;
  903. padding: 15px;
  904. border: 1px solid #e4e7ed;
  905. border-radius: 4px;
  906. }
  907. }
  908. .api-params-section {
  909. margin-top: 30px;
  910. padding: 20px;
  911. background-color: #f5f7fa;
  912. border: 1px solid #e4e7ed;
  913. border-radius: 4px;
  914. .section-title {
  915. font-size: 16px;
  916. font-weight: bold;
  917. margin-bottom: 15px;
  918. color: #333;
  919. border-left: 4px solid #67c23a;
  920. padding-left: 10px;
  921. }
  922. .risk-rules {
  923. margin-top: 15px;
  924. padding: 10px;
  925. background-color: #fff;
  926. border-radius: 4px;
  927. .rules-title {
  928. font-weight: bold;
  929. margin-bottom: 10px;
  930. color: #606266;
  931. }
  932. .rule-tag {
  933. margin-right: 10px;
  934. margin-bottom: 5px;
  935. }
  936. }
  937. }
  938. }
  939. </style>