index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. <template>
  2. <ContentWrap>
  3. <!-- 搜索工作栏 -->
  4. <el-form
  5. class="-mb-15px"
  6. :model="queryParams"
  7. ref="queryFormRef"
  8. :inline="true"
  9. label-width="80px"
  10. >
  11. <el-form-item label="长者姓名" prop="elderName">
  12. <el-input
  13. v-model="queryParams.elderName"
  14. placeholder="请输入长者姓名"
  15. class="!w-240px"
  16. @keyup.enter="handleQuery"
  17. />
  18. </el-form-item>
  19. <!-- <el-form-item label="评估年份">-->
  20. <!-- <el-date-picker-->
  21. <!-- size="default"-->
  22. <!-- ref="selectRef"-->
  23. <!-- class="!w-240px"-->
  24. <!-- v-model="queryParams.recordMonthRange"-->
  25. <!-- type="year"-->
  26. <!-- :clearable="true"-->
  27. <!-- :editable="false"-->
  28. <!-- placeholder="选择记录年份"-->
  29. <!-- value-format="YYYY"-->
  30. <!-- format="YYYY"-->
  31. <!-- date-format="YYYY"-->
  32. <!-- />-->
  33. <!-- </el-form-item>-->
  34. <el-form-item>
  35. <el-button @click="handleQuery">
  36. <Icon icon="ep:search" class="mr-5px" /> 搜索
  37. </el-button>
  38. <el-button @click="resetQuery">
  39. <Icon icon="ep:refresh" class="mr-5px" /> 重置
  40. </el-button>
  41. </el-form-item>
  42. </el-form>
  43. </ContentWrap>
  44. <!-- 列表 -->
  45. <ContentWrap>
  46. <TabBarBtn>
  47. <template #next>
  48. <el-button type="primary" @click="handleAdd">
  49. <Icon icon="ep:plus" class="mr-5px" /> 新增
  50. </el-button>
  51. <el-button type="success" @click="handleExport">
  52. <Icon icon="ep:upload" class="mr-5px" /> 导出
  53. </el-button>
  54. </template>
  55. </TabBarBtn>
  56. <el-table v-loading="loading" :data="list" stripe>
  57. <el-table-column type="index" label="序号" width="60" align="center" />
  58. <el-table-column label="长者姓名" prop="elderName" width="110" align="center"/>
  59. <el-table-column label="性别" prop="elderSex" width="80" align="center">
  60. <template #default="{ row }">
  61. {{ getDictLabel(DICT_TYPE.SYSTEM_USER_SEX, row.elderSex) }}
  62. </template>
  63. </el-table-column>
  64. <el-table-column label="年龄" prop="elderAge" width="80" align="center"/>
  65. <el-table-column label="床号" prop="bedName" width="200" align="center"/>
  66. <el-table-column label="合同号" prop="contractNumber" width="150" align="center"/>
  67. <el-table-column label="护理级别" prop="nurseLevelName" width="150" align="center"/>
  68. <el-table-column label="防噎食评估" prop="asphyxiationRisk" width="130" align="center" >
  69. <template #default="{ row }">
  70. <el-tag :type="getRiskType(row.riskData?.asphyxiation?.level)" :class="{ 'cursor-pointer': row.riskData?.asphyxiation?.id }" @click="row.riskData?.asphyxiation?.id && handleOpenAsphyxiation(row.riskData?.asphyxiation)">{{ getRiskLevelText(row.riskData?.asphyxiation?.level || '-') }}</el-tag>
  71. </template>
  72. </el-table-column>
  73. <el-table-column label="防压疮评估" prop="pressureUlcerRisk" width="130" align="center" >
  74. <template #default="{ row }">
  75. <el-tag :type="getRiskType(row.riskData?.pressureUlcer?.level)" :class="{ 'cursor-pointer': row.riskData?.pressureUlcer?.id }" @click="row.riskData?.pressureUlcer?.id && handleOpenPressureUlcer(row.riskData?.pressureUlcer)">{{ getRiskLevelText(row.riskData?.pressureUlcer?.level || '-') }}</el-tag>
  76. </template>
  77. </el-table-column>
  78. <el-table-column label="防跌倒评估" prop="fallRisk" width="130" align="center" >
  79. <template #default="{ row }">
  80. <el-tag :type="getRiskType(row.riskData?.fall?.level)" :class="{ 'cursor-pointer': row.riskData?.fall?.id }" @click="row.riskData?.fall?.id && handleOpenFall(row.riskData?.fall)">{{ getRiskLevelText(row.riskData?.fall?.level || '-') }}</el-tag>
  81. </template>
  82. </el-table-column>
  83. <el-table-column label="防坠床评估" prop="bedFallRisk" width="130" align="center" >
  84. <template #default="{ row }">
  85. <el-tag :type="getRiskType(row.riskData?.bedFall?.level)" :class="{ 'cursor-pointer': row.riskData?.bedFall?.id }" @click="row.riskData?.bedFall?.id && handleOpenBedFall(row.riskData?.bedFall)">{{ getRiskLevelText(row.riskData?.bedFall?.level || '-') }}</el-tag>
  86. </template>
  87. </el-table-column>
  88. <el-table-column label="防烫伤评估" prop="scaldRisk" width="130" align="center" >
  89. <template #default="{ row }">
  90. <el-tag :type="getRiskType(row.riskData?.scald?.level)" :class="{ 'cursor-pointer': row.riskData?.scald?.id }" @click="row.riskData?.scald?.id && handleOpenScald(row.riskData?.scald)">{{ getRiskLevelText(row.riskData?.scald?.level || '-') }}</el-tag>
  91. </template>
  92. </el-table-column>
  93. <el-table-column label="防走失评估" prop="wanderingRisk" width="130" align="center" >
  94. <template #default="{ row }">
  95. <el-tag :type="getRiskType(row.riskData?.wandering?.level)" :class="{ 'cursor-pointer': row.riskData?.wandering?.id }" @click="row.riskData?.wandering?.id && handleOpenWandering(row.riskData?.wandering)">{{ getRiskLevelText(row.riskData?.wandering?.level || '-') }}</el-tag>
  96. </template>
  97. </el-table-column>
  98. <el-table-column label="防自伤他伤评估" prop="suicideRisk" width="130" align="center" >
  99. <template #default="{ row }">
  100. <el-tag :type="getRiskType(row.riskData?.selfHarm?.level)" :class="{ 'cursor-pointer': row.riskData?.selfHarm?.id }" @click="row.riskData?.selfHarm?.id && handleOpenSuicide(row.riskData?.selfHarm)">{{ getRiskLevelText(row.riskData?.selfHarm?.level || '-') }}</el-tag>
  101. </template>
  102. </el-table-column>
  103. <el-table-column label="防食品药品误食评估" prop="perceptionRisk" width="152" align="center" >
  104. <template #default="{ row }">
  105. <el-tag :type="getRiskType(row.riskData?.foodDrug?.level)" :class="{ 'cursor-pointer': row.riskData?.foodDrug?.id }" @click="row.riskData?.foodDrug?.id && handleOpenMental(row.riskData?.foodDrug)">{{ getRiskLevelText(row.riskData?.foodDrug?.level || '-') }}</el-tag>
  106. </template>
  107. </el-table-column>
  108. <el-table-column label="防文娱活动意外" prop="balanceRisk" width="130" align="center" >
  109. <template #default="{ row }">
  110. <el-tag :type="getRiskType(row.riskData?.entertainment?.level)" :class="{ 'cursor-pointer': row.riskData?.entertainment?.id }" @click="row.riskData?.entertainment?.id && handleOpenBalance(row.riskData?.entertainment)">{{ getRiskLevelText(row.riskData?.entertainment?.level || '-') }}</el-tag>
  111. </template>
  112. </el-table-column>
  113. <el-table-column label="记录时间" prop="bedName" width="200" align="center">
  114. <template #default="{ row }">
  115. {{formatToDateTime(row.createTime)}}
  116. </template>
  117. </el-table-column>
  118. <el-table-column label="记录人" prop="creator" width="150" align="center"/>
  119. <el-table-column label="操作" align="center" width="200" fixed="right">
  120. <template #default="scope">
  121. <el-button
  122. link
  123. type="primary"
  124. @click="handleEdit(scope.row, scope.row.id)"
  125. >
  126. 编辑
  127. </el-button>
  128. <el-button
  129. link
  130. type="warning"
  131. @click="handleView(scope.row,scope.row.id)"
  132. >
  133. 详情
  134. </el-button>
  135. <el-button
  136. link
  137. type="danger"
  138. @click="handleDelete(scope.row)"
  139. >
  140. 删除
  141. </el-button>
  142. </template>
  143. </el-table-column>
  144. </el-table>
  145. <!-- 分页 -->
  146. <Pagination
  147. :total="total"
  148. v-model:page="queryParams.pageNo"
  149. v-model:limit="queryParams.pageSize"
  150. @pagination="getList"
  151. />
  152. </ContentWrap>
  153. <!-- 新增/编辑弹窗 -->
  154. <SafetyRiskNoticeForm ref="formRef" @success="getList" />
  155. <!-- 各项评估详情弹窗 -->
  156. <AsphyxiationForm ref="asphyxiationFormRef" />
  157. <PressureSoresForm ref="pressureSoresFormRef" />
  158. <FallDownForm ref="fallDownFormRef" />
  159. <FallPreventionForm ref="fallPreventionFormRef" />
  160. <EmpyrosisForm ref="empyrosisFormRef" />
  161. <WanderAwayForm ref="wanderAwayFormRef" />
  162. <CommitSuicideForm ref="commitSuicideFormRef" />
  163. <MMSEForm ref="mmseFormRef" />
  164. <AttackForm ref="attackFormRef" />
  165. <AntiEntertainmentForm ref="equilibriumFormRef" />
  166. <DailyLifeForm ref="dailyLifeFormRef" />
  167. <NutritionalRiskForm ref="nutritionalRiskFormRef" />
  168. </template>
  169. <script setup lang="ts">
  170. import { DICT_TYPE, getDictLabel } from '@/utils/dict'
  171. import {
  172. getSafetyRiskNoticePage,
  173. deleteSafetyRiskNotice
  174. } from '@/api/elderly/apply/check-in'
  175. import { formatTime } from '@/utils'
  176. import SafetyRiskNoticeForm from './Form.vue'
  177. import AsphyxiationForm from '@/views/elderly/apply/nine-precautions/asphyxiation-by-choking/AddForm.vue'
  178. import PressureSoresForm from '@/views/elderly/apply/nine-precautions/pressure-sores/AddForm.vue'
  179. import FallDownForm from '@/views/elderly/apply/nine-precautions/fall-down/AddForm.vue'
  180. import FallPreventionForm from '@/views/elderly/apply/nine-precautions/fall-prevention-measures/AddForm.vue'
  181. import EmpyrosisForm from '@/views/elderly/apply/nine-precautions/empyrosis/AddForm.vue'
  182. import WanderAwayForm from '@/views/elderly/apply/nine-precautions/wander-away/AddForm.vue'
  183. import CommitSuicideForm from '@/views/elderly/apply/nine-precautions/commit-suicide/AddForm.vue'
  184. import MMSEForm from '@/views/elderly/apply/nine-precautions/MMSE/AddForm.vue'
  185. import AttackForm from '@/views/elderly/apply/nine-precautions/attack/AddForm.vue'
  186. import CommunicationForm from '@/views/elderly/apply/nine-precautions/communication/AddForm.vue'
  187. import AntiEntertainmentForm from '@/views/elderly/apply/nine-precautions/anti-entertainment/AddForm.vue'
  188. import DailyLifeForm from '@/views/elderly/apply/nine-precautions/daily-life/AddForm.vue'
  189. import NutritionalRiskForm from '@/views/elderly/apply/nine-precautions/nutritional-risk/AddForm.vue'
  190. import {useUserStore} from "@/store/modules/user";
  191. import {formatToDateTime} from "@/utils/dateUtil";
  192. const userStore = useUserStore()
  193. defineOptions({ name: 'RiskDisclosureStatement' })
  194. const message = useMessage()
  195. const { t } = useI18n()
  196. // 列表数据
  197. const loading = ref(false)
  198. const list = ref([])
  199. const total = ref(0)
  200. // 查询参数
  201. const queryParams = reactive({
  202. pageNo: 1,
  203. pageSize: 10,
  204. elderName: undefined,
  205. floorName: undefined,
  206. tenantIds: userStore.orgTenantId
  207. })
  208. const queryFormRef = ref()
  209. // 解析 riskData JSON 字符串
  210. const parseRiskData = (row: any) => {
  211. if (!row.riskData) return {}
  212. try {
  213. return typeof row.riskData === 'string' ? JSON.parse(row.riskData) : row.riskData
  214. } catch (e) {
  215. return {}
  216. }
  217. }
  218. // 获取列表
  219. const getList = async () => {
  220. loading.value = true
  221. try {
  222. const data = await getSafetyRiskNoticePage(queryParams)
  223. list.value = (data.list || []).map((item: any) => ({
  224. ...item,
  225. riskData: parseRiskData(item)
  226. }))
  227. total.value = data.total || 0
  228. } finally {
  229. loading.value = false
  230. }
  231. }
  232. // 搜索
  233. const handleQuery = () => {
  234. queryParams.pageNo = 1
  235. getList()
  236. }
  237. // 重置
  238. const resetQuery = () => {
  239. queryFormRef.value?.resetFields()
  240. handleQuery()
  241. }
  242. // 新增
  243. const formRef = ref()
  244. const handleAdd = () => {
  245. formRef.value?.open()
  246. }
  247. // 各项评估弹窗引用
  248. const asphyxiationFormRef = ref()
  249. const pressureSoresFormRef = ref()
  250. const fallDownFormRef = ref()
  251. const fallPreventionFormRef = ref()
  252. const empyrosisFormRef = ref()
  253. const wanderAwayFormRef = ref()
  254. const commitSuicideFormRef = ref()
  255. const mmseFormRef = ref()
  256. const attackFormRef = ref()
  257. const communicationFormRef = ref()
  258. const equilibriumFormRef = ref()
  259. const dailyLifeFormRef = ref()
  260. const nutritionalRiskFormRef = ref()
  261. // 各项评估点击处理方法
  262. const handleOpenAsphyxiation = (row: any) => {
  263. asphyxiationFormRef.value?.open(queryParams.tenantIds[0], row.id, true)
  264. }
  265. const handleOpenPressureUlcer = (row: any) => {
  266. pressureSoresFormRef.value?.open(queryParams.tenantIds[0], row.id, true)
  267. }
  268. const handleOpenFall = (row: any) => {
  269. fallDownFormRef.value?.open(queryParams.tenantIds[0], row.id, true)
  270. }
  271. const handleOpenBedFall = (row: any) => {
  272. fallPreventionFormRef.value?.open(queryParams.tenantIds[0], row.id, true)
  273. }
  274. const handleOpenScald = (row: any) => {
  275. empyrosisFormRef.value?.open(queryParams.tenantIds[0], row.id, true)
  276. }
  277. const handleOpenWandering = (row: any) => {
  278. wanderAwayFormRef.value?.open(queryParams.tenantIds[0], row.id, true)
  279. }
  280. const handleOpenSuicide = (row: any) => {
  281. commitSuicideFormRef.value?.open(queryParams.tenantIds[0], row.id, true)
  282. }
  283. const handleOpenMental = (row: any) => {
  284. mmseFormRef.value?.open(queryParams.tenantIds[0], row.id, true)
  285. }
  286. const handleOpenAttack = (row: any) => {
  287. attackFormRef.value?.open(queryParams.tenantIds[0], row.id, true)
  288. }
  289. const handleOpenPerception = (row: any) => {
  290. communicationFormRef.value?.open(queryParams.tenantIds[0], row.id, true)
  291. }
  292. const handleOpenBalance = (row: any) => {
  293. equilibriumFormRef.value?.open(queryParams.tenantIds[0], row.id, true)
  294. }
  295. const handleOpenDailyLiving = (row: any) => {
  296. dailyLifeFormRef.value?.open(queryParams.tenantIds[0], row.id, true)
  297. }
  298. const handleOpenNutrition = (row: any) => {
  299. nutritionalRiskFormRef.value?.open(queryParams.tenantIds[0], row.id, true)
  300. }
  301. // 获取风险等级文本
  302. const getRiskLevelText = (riskLevel: string) => {
  303. switch (riskLevel) {
  304. case 'none': return '无风险'
  305. case 'low': return '低风险'
  306. case 'medium': return '中度风险'
  307. case 'high': return '高风险'
  308. default: return '-'
  309. }
  310. }
  311. /**
  312. * 根据风险等级获取按钮类型(颜色)
  313. * @param riskLevel 风险等级:none(无风险)、low(低风险)、medium(中风险)、high(高风险)
  314. * @returns Element Plus 按钮类型:success(绿)、info(灰)、warning(黄)、danger(红)、primary(蓝)
  315. */
  316. const getRiskType = (riskLevel: string): string => {
  317. if (!riskLevel) return 'info'
  318. const level = riskLevel.trim().toLowerCase()
  319. if (level === 'none') return 'success'
  320. if (level === 'low') return 'info'
  321. if (level === 'medium') return 'warning'
  322. if (level === 'high') return 'danger'
  323. return 'primary'
  324. }
  325. // 编辑
  326. const handleEdit = (row: any) => {
  327. formRef.value?.open(row)
  328. }
  329. // 详情
  330. const handleView = (row: any) => {
  331. formRef.value?.open(row, true)
  332. }
  333. // 删除
  334. const handleDelete = async (row: any) => {
  335. try {
  336. await message.confirm('确认删除该记录吗?')
  337. await deleteSafetyRiskNotice(row.id)
  338. message.success('删除成功')
  339. getList()
  340. } catch (e) {
  341. // 用户取消
  342. }
  343. }
  344. // 初始化
  345. onMounted(() => {
  346. getList()
  347. })
  348. </script>
  349. <style scoped lang="scss">
  350. </style>