index.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. <template>
  2. <!-- 搜索 -->
  3. <ContentWrap>
  4. <el-form
  5. class="-mb-15px"
  6. :model="queryParams"
  7. ref="queryFormRef"
  8. :inline="true"
  9. label-width="80px"
  10. >
  11. <TenantSelect v-model="queryParams.tenantIds" placeholder="请选择机构名称" prop="tenantIds" />
  12. <el-form-item label="长者姓名" prop="elderName">
  13. <el-input
  14. @keyup.enter="handleQuery"
  15. v-model="queryParams.elderName"
  16. placeholder="请输入长者姓名"
  17. class="!w-240px"
  18. clearable
  19. />
  20. </el-form-item>
  21. <el-form-item label="出院日期" prop="dischargeDate">
  22. <el-date-picker
  23. style="width: 240px"
  24. v-model="queryParams.dischargeDate"
  25. type="daterange"
  26. :clearable="true"
  27. placeholder="选择出院日期范围"
  28. value-format="YYYY-MM-DD"
  29. format="YYYY-MM-DD"
  30. date-format="YYYY-MM-DD"
  31. />
  32. </el-form-item>
  33. <el-form-item>
  34. <el-button @click="handleQuery">
  35. <Icon icon="ep:search" class="mr-5px" /> 搜索
  36. </el-button>
  37. <el-button @click="resetQuery">
  38. <Icon icon="ep:refresh" class="mr-5px" /> 重置
  39. </el-button>
  40. </el-form-item>
  41. </el-form>
  42. </ContentWrap>
  43. <!-- 列表 -->
  44. <ContentWrap>
  45. <TabBarBtn @add="openForm()" />
  46. <Table2
  47. v-loading="loading"
  48. :data="list"
  49. :columns="DischargeSummaryColumns"
  50. :queryParams="queryParams"
  51. :op-width="280"
  52. :show-edit-condition="() => false"
  53. :show-delete-condition="() => false"
  54. :show-detail-condition="() => false"
  55. @del="handleDelete"
  56. >
  57. <template #next="{ scope }">
  58. <el-button link type="primary" @click="openForm(scope)">编辑</el-button>
  59. <el-button link type="primary" @click="openDetail(scope)">详情</el-button>
  60. <el-button link type="danger" @click="handleDelete(scope.id)">删除</el-button>
  61. <el-button link type="primary" @click="openPrint(scope)">打印</el-button>
  62. <el-button link type="warning" @click="openCheckOut(scope)">退住申请</el-button>
  63. </template>
  64. </Table2>
  65. <!-- 分页 -->
  66. <Pagination
  67. :total="total"
  68. v-model:page="queryParams.pageNo"
  69. v-model:limit="queryParams.pageSize"
  70. @pagination="getList"
  71. />
  72. </ContentWrap>
  73. <!-- 新增 / 编辑弹窗 -->
  74. <Form ref="formRef" @success="getList" />
  75. <!-- 打印预览 -->
  76. <Print ref="printRef" />
  77. <!-- 退住申请弹窗(从出院小结带入长者 id,无需权限) -->
  78. <CheckOutForm ref="checkOutRef" @success="getList" />
  79. </template>
  80. <script lang="ts" setup>
  81. import {
  82. getDischargeSummaryPage,
  83. deleteDischargeSummary,
  84. getDischargeReasonText,
  85. DISCHARGE_REASON
  86. } from '@/api/elderly/elder/discharge-summary'
  87. import { DischargeSummaryColumns } from './columns'
  88. import Form from './Form.vue'
  89. import Print from './Print.vue'
  90. import CheckOutForm from '@/views/elderly/bak/check-out/Form.vue'
  91. import { useUserStore } from '@/store/modules/user'
  92. defineOptions({ name: 'DischargeSummary' })
  93. const userStore = useUserStore()
  94. const message = useMessage()
  95. const { t } = useI18n()
  96. const loading = ref(true)
  97. const total = ref(0)
  98. const list = ref<any[]>([])
  99. const queryParams = reactive({
  100. pageNo: 1,
  101. pageSize: 10,
  102. elderName: undefined as string | undefined,
  103. dischargeDate: [] as string[] | undefined,
  104. tenantIds: userStore.orgTenantId as any
  105. })
  106. const queryFormRef = ref()
  107. /** 测试假数据:列表请求失败时填充,方便前端联调 */
  108. const buildMockDischargeSummary = () => {
  109. const base = [
  110. {
  111. id: 3001,
  112. elderId: 801,
  113. elderName: '张建国',
  114. gender: 1,
  115. bedName: '1号楼-3区-301-01',
  116. elderAge: 78,
  117. checkInDate: '2024-03-15',
  118. dischargeDate: '2026-08-20',
  119. dischargeReason: DISCHARGE_REASON.HOME_CARE,
  120. doctorSign: '李医生',
  121. createTime: '2026-08-20 10:30:00'
  122. },
  123. {
  124. id: 3002,
  125. elderId: 802,
  126. elderName: '刘秀英',
  127. gender: 2,
  128. bedName: '2号楼-2区-205-03',
  129. elderAge: 82,
  130. checkInDate: '2023-11-02',
  131. dischargeDate: '2026-08-25',
  132. dischargeReason: DISCHARGE_REASON.HOSPITAL,
  133. doctorSign: '陈医生',
  134. createTime: '2026-08-25 15:10:00'
  135. },
  136. {
  137. id: 3003,
  138. elderId: 803,
  139. elderName: '王德海',
  140. gender: 1,
  141. bedName: '1号楼-4区-402-02',
  142. elderAge: 75,
  143. checkInDate: '2025-01-08',
  144. dischargeDate: '2026-09-01',
  145. dischargeReason: DISCHARGE_REASON.OTHER,
  146. dischargeReasonOther: '家属迁居外地',
  147. doctorSign: '周医生',
  148. createTime: '2026-09-01 09:00:00'
  149. }
  150. ]
  151. return base.map((item: any) => ({ ...item, tenantId: queryParams.tenantIds }))
  152. }
  153. /**
  154. * 查询列表
  155. * 说明:出院原因 / 年龄 的展示文本在此统一映射,
  156. * 因为它们是模块自定义枚举,Table2 的 dictArr 字典翻译用不上。
  157. */
  158. const getList = async () => {
  159. loading.value = true
  160. try {
  161. const params: Recordable = {
  162. pageNo: queryParams.pageNo,
  163. pageSize: queryParams.pageSize,
  164. elderName: queryParams.elderName || undefined,
  165. tenantIds: queryParams.tenantIds
  166. }
  167. // 出院日期范围
  168. if (Array.isArray(queryParams.dischargeDate) && queryParams.dischargeDate.length === 2) {
  169. params.dischargeDate = [...queryParams.dischargeDate]
  170. }
  171. // 返回的 list 已由 API 层转换并预计算 dischargeReasonText / elderAgeText
  172. const data = await getDischargeSummaryPage(params)
  173. list.value = data.list || []
  174. total.value = data.total || 0
  175. } catch (e) {
  176. // 列表请求失败时填充测试假数据,便于前端联调(控制台有提示,不影响页面渲染)
  177. console.warn('[出院小结] 列表请求失败,已使用测试假数据。', e)
  178. list.value = buildMockDischargeSummary().map((item: any) => ({
  179. ...item,
  180. dischargeReasonText: getDischargeReasonText(item.dischargeReason),
  181. elderAgeText: `${item.elderAge} 岁`
  182. }))
  183. total.value = list.value.length
  184. } finally {
  185. loading.value = false
  186. }
  187. }
  188. /** 搜索 */
  189. const handleQuery = async () => {
  190. await queryFormRef.value?.validate().catch(() => {})
  191. queryParams.pageNo = 1
  192. getList()
  193. }
  194. /** 重置 */
  195. const resetQuery = () => {
  196. queryFormRef.value?.resetFields()
  197. queryParams.dischargeDate = []
  198. handleQuery()
  199. }
  200. /** 新增 / 编辑 */
  201. const formRef = ref()
  202. const printRef = ref()
  203. const checkOutRef = ref()
  204. const openForm = (row: any = {}) => {
  205. if (
  206. !queryParams.tenantIds ||
  207. (Array.isArray(queryParams.tenantIds) && queryParams.tenantIds.length === 0) ||
  208. (Array.isArray(queryParams.tenantIds) && queryParams.tenantIds.length > 1 && !row.tenantId)
  209. ) {
  210. message.error('新增只能选择一个机构')
  211. return
  212. }
  213. formRef.value.open(row)
  214. }
  215. /** 打开详情(只读) */
  216. const openDetail = (row: any = {}) => {
  217. formRef.value.open(row, true)
  218. }
  219. /** 打印 */
  220. const openPrint = (row: any = {}) => {
  221. printRef.value.open(row)
  222. }
  223. /** 退住申请:复用退住申请页面新增功能,带入当前长者 id 并预选该长者(无需权限) */
  224. const openCheckOut = (row: any = {}) => {
  225. // 解析租户 id:优先用行内 tenantId,否则取当前查询选中的机构(只能单选)
  226. let tId = row.tenantId
  227. if (!tId) {
  228. const qt = queryParams.tenantIds
  229. if (Array.isArray(qt)) {
  230. tId = qt.length === 1 ? qt[0] : undefined
  231. } else {
  232. tId = qt
  233. }
  234. }
  235. if (!tId) {
  236. message.error('请先选择一个机构')
  237. return
  238. }
  239. // elderId 带入当前长者,open 内部会调用 setElderById 默认选中该长者
  240. // dischargeDate 带入退住日期,预填退住申请表单里的「退住日期」
  241. // reason 带入出院原因作为退住原因;出院原因=其他时,退住描述取「其他」输入值
  242. const reason = row.dischargeReason
  243. const description =
  244. Number(reason) === DISCHARGE_REASON.OTHER ? row.dischargeReasonOther || '' : ''
  245. checkOutRef.value.open(
  246. tId,
  247. undefined,
  248. false,
  249. undefined,
  250. row.elderId,
  251. row.dischargeDate,
  252. reason,
  253. description
  254. )
  255. }
  256. /** 删除 */
  257. const handleDelete = async (id: number) => {
  258. try {
  259. await message.confirm('确定删除该出院小结吗?删除后不可恢复。', '提示')
  260. await deleteDischargeSummary(id)
  261. message.success(t('common.delSuccess'))
  262. await getList()
  263. } catch {}
  264. }
  265. /** 路由携带 elderName 时自动带入 */
  266. const route = useRoute()
  267. onMounted(() => {
  268. if (route.query && route.query.elderName) {
  269. queryParams.elderName = route.query.elderName as string
  270. }
  271. getList()
  272. })
  273. </script>