index.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. <template>
  2. <ContentWrap>
  3. <!-- 防噎食评估表 -->
  4. <el-form
  5. class="-mb-15px"
  6. :model="queryParams"
  7. ref="queryFormRef"
  8. :inline="true"
  9. label-width="110px"
  10. >
  11. <TenantSelect v-model="queryParams.tenantIds" placeholder="请选择机构名称" prop="tenantIds" />
  12. <el-form-item label="长者姓名">
  13. <el-input
  14. v-model="queryParams.elderName"
  15. placeholder="长者姓名"
  16. class="!w-240px"
  17. clearable
  18. />
  19. </el-form-item>
  20. <el-form-item label="评估人">
  21. <el-input v-model="queryParams.assessor" placeholder="评估人" class="!w-240px" clearable />
  22. </el-form-item>
  23. <el-form-item label="记录日期">
  24. <el-date-picker
  25. size="default"
  26. ref="selectRef"
  27. class="!w-240px"
  28. v-model="queryParams.assessDate"
  29. type="daterange"
  30. :clearable="true"
  31. :editable="false"
  32. placeholder="选择记录日期"
  33. value-format="YYYY-MM-DD"
  34. format="YYYY-MM-DD"
  35. date-format="YYYY-MM-DD"
  36. />
  37. </el-form-item>
  38. <el-form-item>
  39. <el-button @click="handleQuery" style="margin-left: 2vw"
  40. ><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button
  41. >
  42. <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
  43. </el-form-item>
  44. </el-form>
  45. </ContentWrap>
  46. <!-- 列表 -->
  47. <ContentWrap>
  48. <div class="mb-10px">
  49. <ButtonAdd @click="openForm(undefined)" />
  50. <ButtonImport @click="handleImportCard" />
  51. </div>
  52. <el-table v-loading="loading" :data="list" :header-cell-style="tableHeaderColor">
  53. <el-table-column header-align="center" align="center" label="序号" width="60">
  54. <template #default="scope">
  55. {{
  56. scope.$index + (queryParams.pageNo * queryParams.pageSize - queryParams.pageSize) + 1
  57. }}
  58. </template>
  59. </el-table-column>
  60. <el-table-column
  61. label="机构名称"
  62. v-if="userStore.getUser.id == 1"
  63. type="index"
  64. width="150"
  65. align="center"
  66. >
  67. <template #default="{ row }">
  68. {{ findLabelById(userStore.getOrgTenant.options, row.tenantId) }}
  69. </template>
  70. </el-table-column>
  71. <el-table-column
  72. prop="elderName"
  73. header-align="center"
  74. align="center"
  75. label="长者姓名"
  76. min-width="150"
  77. show-overflow-tooltip
  78. />
  79. <el-table-column
  80. prop="assessor"
  81. header-align="center"
  82. align="center"
  83. label="评估人"
  84. min-width="150"
  85. show-overflow-tooltip
  86. />
  87. <el-table-column
  88. prop="assessDate"
  89. header-align="center"
  90. align="center"
  91. label="记录日期"
  92. min-width="150"
  93. show-overflow-tooltip
  94. />
  95. <el-table-column
  96. prop="riskLevel"
  97. header-align="center"
  98. align="center"
  99. label="风险等级"
  100. min-width="120"
  101. show-overflow-tooltip
  102. >
  103. <template #default="scope">
  104. <el-tag :type="getRiskLevelType(scope.row.riskLevel)">
  105. {{ getRiskLevelText(scope.row.riskLevel) }}
  106. </el-tag>
  107. </template>
  108. </el-table-column>
  109. <el-table-column
  110. prop="creator"
  111. header-align="center"
  112. align="center"
  113. label="记录人"
  114. min-width="150"
  115. show-overflow-tooltip
  116. />
  117. <el-table-column label="操作" align="center" width="200">
  118. <template #default="scope">
  119. <el-button link type="primary" @click="openFormEdit(scope.row, scope.row.id)">
  120. 编辑
  121. </el-button>
  122. <el-button link type="warning" @click="openFormDetail(scope.row, scope.row.id)">
  123. 详情
  124. </el-button>
  125. <el-button link type="danger" @click="openClose(scope.row)"> 删除 </el-button>
  126. </template>
  127. </el-table-column>
  128. </el-table>
  129. <!-- 分页 -->
  130. <Pagination
  131. :total="total"
  132. v-model:page="queryParams.pageNo"
  133. v-model:limit="queryParams.pageSize"
  134. @pagination="getList"
  135. />
  136. </ContentWrap>
  137. <AddForm ref="formRef" @success="getList" />
  138. </template>
  139. <script setup lang="ts">
  140. import AddForm from './AddForm.vue'
  141. import ButtonAdd from '@/components/ButtonAdd/src/ButtonAdd.vue'
  142. import ButtonImport from '@/components/ButtonImport/src/ButtonImport.vue'
  143. import { useUserStore } from '@/store/modules/user'
  144. import { getCurrentMonthRange } from '@/utils/dateUtil'
  145. import { asphyxiationDelete, asphyxiationPage } from '@/api/social-work'
  146. import { exportWithExpandedObjectArrays } from '@/utils/excel-export'
  147. import { findLabelById } from '@/utils/dict'
  148. const message = useMessage()
  149. const { t } = useI18n()
  150. const userStore = useUserStore()
  151. const loading = ref(true)
  152. const total = ref(0)
  153. const list = ref([])
  154. const exportLoading = ref(false)
  155. let queryParams = reactive({
  156. pageNo: 1,
  157. pageSize: 10,
  158. elderName: '',
  159. assessor: '',
  160. // assessDate: getCurrentMonthRange(),
  161. assessDate: [],
  162. tenantIds: userStore.orgTenantId
  163. })
  164. const queryFormRef = ref()
  165. // 打开导出弹窗
  166. const handleImportCard = async () => {
  167. exportLoading.value = true
  168. try {
  169. const queryP = {
  170. pageNo: 1,
  171. pageSize: 9999,
  172. elderName: queryParams.elderName,
  173. assessor: queryParams.assessor,
  174. assessDate: queryParams.assessDate,
  175. tenantIds: queryParams.tenantIds
  176. }
  177. const data = await asphyxiationPage(queryP)
  178. const exportData = data.list || []
  179. if (exportData.length === 0) {
  180. message.warning('暂无数据可导出')
  181. return
  182. }
  183. const processedData = exportData.map((item) => {
  184. const row: any = {
  185. orgName: findLabelById(userStore.getOrgTenant.options, item.tenantId) || '',
  186. elderName: item.elderName || '',
  187. assessor: item.assessor || '',
  188. assessDate: item.assessDate || '',
  189. assessScore: item.assessScore ?? '',
  190. creator: item.creator || ''
  191. }
  192. row.riskLevelText = getRiskLevelText(item.riskLevel) || '-'
  193. return row
  194. })
  195. const headers = [
  196. {
  197. 'key': 'orgName',
  198. 'title': '机构名称'
  199. },
  200. {
  201. 'key': 'elderName',
  202. 'title': '长者姓名'
  203. },
  204. {
  205. 'key': 'assessor',
  206. 'title': '评估人'
  207. },
  208. {
  209. 'key': 'assessDate',
  210. 'title': '记录日期'
  211. },
  212. {
  213. 'key': 'riskLevelText',
  214. 'title': '风险等级'
  215. },
  216. {
  217. 'key': 'creator',
  218. 'title': '记录人'
  219. }
  220. ]
  221. exportWithExpandedObjectArrays(processedData, headers, `防噎食评估_${new Date().getTime()}.xlsx`, '防噎食评估')
  222. message.success('导出成功')
  223. } catch (error) {
  224. console.error('导出失败:', error)
  225. message.error('导出失败,请重试')
  226. } finally {
  227. exportLoading.value = false
  228. }
  229. }
  230. /** 查询列表 */
  231. const getList = async () => {
  232. loading.value = true
  233. try {
  234. const data = await asphyxiationPage(queryParams)
  235. list.value = data.list
  236. total.value = data.total
  237. } finally {
  238. loading.value = false
  239. }
  240. }
  241. /** 搜索按钮操作 */
  242. const handleQuery = async () => {
  243. if (!queryFormRef.value) return
  244. const valid = await queryFormRef.value.validate()
  245. if (!valid) return
  246. queryParams.pageNo = 1
  247. await getList()
  248. }
  249. /** 重置按钮操作 */
  250. const resetQuery = () => {
  251. queryParams.elderName = ''
  252. queryParams.assessor = ''
  253. queryParams.tenantIds = userStore.orgTenantId
  254. // queryParams.assessDate = getCurrentMonthRange()
  255. queryParams.assessDate = []
  256. queryFormRef.value.resetFields()
  257. handleQuery()
  258. }
  259. /** 添加/修改操作 */
  260. const formRef = ref()
  261. const openForm = (id?: number) => {
  262. if (queryParams.tenantIds.length == 0 || queryParams.tenantIds.length > 1) {
  263. message.error('新增只能选择一个机构')
  264. return
  265. }
  266. formRef.value.open(queryParams.tenantIds[0], id, false)
  267. }
  268. const openFormEdit = (row: any = {}, id?: number) => {
  269. formRef.value.open(row.tenantId, id, false)
  270. }
  271. const openFormDetail = (row: any = {}, id?: number) => {
  272. formRef.value.open(row.tenantId, id, true)
  273. }
  274. const openClose = async (item: any) => {
  275. try {
  276. const res = await message.confirm('确定要删除吗?', '提示')
  277. if (res == 'confirm') {
  278. try {
  279. const res = await asphyxiationDelete(item.id)
  280. if (res) {
  281. message.success(t('common.updateSuccess'))
  282. await getList()
  283. }
  284. } catch (err) {}
  285. }
  286. } catch {}
  287. }
  288. /** 取消按钮操作 */
  289. const cancelDelete = async (id: number) => {
  290. try {
  291. await message.cancelConfirm()
  292. message.success(t('common.delSuccess'))
  293. await getList()
  294. } catch {}
  295. }
  296. const route = useRoute()
  297. /** 初始化 **/
  298. onMounted(() => {
  299. if (route.query && route.query.elderName) {
  300. queryParams.elderName = route.query.elderName as string
  301. }
  302. getList()
  303. })
  304. // 表头格式
  305. const tableHeaderColor = ({ rowIndex }: any) => {
  306. if (rowIndex === 0) {
  307. return {
  308. backgroundColor: '#f8f8f9',
  309. color: '#666666',
  310. fontWeight: 'bold'
  311. }
  312. }
  313. }
  314. // 获取风险等级类型
  315. const getRiskLevelType = (riskLevel: string) => {
  316. switch (riskLevel) {
  317. case 'none':
  318. return 'success'
  319. case 'low':
  320. return 'info'
  321. case 'medium':
  322. return 'warning'
  323. case 'high':
  324. return 'danger'
  325. default:
  326. return ''
  327. }
  328. }
  329. // 获取风险等级文本
  330. const getRiskLevelText = (riskLevel: string) => {
  331. switch (riskLevel) {
  332. case 'none':
  333. return '无风险'
  334. case 'low':
  335. return '低风险'
  336. case 'medium':
  337. return '中度风险'
  338. case 'high':
  339. return '高风险'
  340. default:
  341. return '-'
  342. }
  343. }
  344. </script>
  345. <style scoped lang="scss"></style>