AddForm.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. <template>
  2. <el-drawer
  3. v-model="dialogVisible"
  4. :title="title"
  5. resizable
  6. :close-on-click-modal="false"
  7. :close-on-press-escape="false"
  8. :destroy-on-close="true"
  9. size="70%"
  10. :before-close="handleClosed"
  11. >
  12. <div class="attack-risk-form">
  13. <h1 class="form-title">外出情况确认书</h1>
  14. <!-- 基本信息 -->
  15. <el-row :gutter="40">
  16. <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
  17. <text>长者姓名</text>
  18. <search-the-elderly ref="selectElderRef" :disabled="isDetail" @update_elder="elderUp" v-model="dataForm.elderName" :tId="dataForm.tenantId"/>
  19. </el-col>
  20. <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
  21. <text>档案号</text>
  22. <el-input v-if="!isDetail" v-model="dataForm.contractNumber" disabled />
  23. <el-text v-else disabled="">{{dataForm.contractNumber}}</el-text>
  24. </el-col>
  25. </el-row>
  26. <el-row :gutter="40">
  27. <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
  28. <text>入院日期</text>
  29. <el-input v-if="!isDetail" :model-value="dayjs(dataForm.checkInTime).format('YYYY-MM-DD')=='Invalid Date'?'':dayjs(dataForm.checkInTime).format('YYYY-MM-DD')" disabled />
  30. <el-text v-else disabled="">{{dayjs(dataForm.checkInTime).format('YYYY-MM-DD')}}</el-text>
  31. </el-col>
  32. <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
  33. <text>床位号</text>
  34. <el-input v-if="!isDetail" v-model="dataForm.bedName" disabled />
  35. <el-text v-else disabled="">{{dataForm.bedName}}</el-text>
  36. </el-col>
  37. </el-row>
  38. <el-row :gutter="40">
  39. <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
  40. <text>记录人</text>
  41. <el-input :disabled="isDetail" v-model="dataForm.assessor" />
  42. </el-col>
  43. <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" class="row">
  44. <text>记录日期</text>
  45. <el-date-picker :disabled="isDetail" v-model="dataForm.assessDate" type="date" style="width: 100%;"/>
  46. </el-col>
  47. </el-row>
  48. <!-- 内容区域 -->
  49. <div class="form-body">
  50. <OutingConfirmationBody
  51. v-model="outingConfirmationForm"
  52. :is-text-mode="isDetail"
  53. />
  54. </div>
  55. </div>
  56. <template #footer>
  57. <el-button @click="handleClosed">关闭</el-button>
  58. <el-button style="margin-left: 22px;margin-right: 30px" v-loading="formLoading" type="primary" v-show="!isDetail" @click="submitForm">确定</el-button>
  59. </template>
  60. </el-drawer>
  61. </template>
  62. <script lang="ts" setup>
  63. import { computed, ref, watch, reactive } from 'vue'
  64. import dayjs from 'dayjs'
  65. import OutingConfirmationBody from '../components/OutingConfirmationBody.vue'
  66. import { attackRiskCreate, attackRiskUpdate } from "@/api/social-work";
  67. import { deleteForm } from '@/api/bpm/form/index.js';
  68. const message = useMessage() // 消息弹窗
  69. const { t } = useI18n() // 国际化
  70. const title = ref('')
  71. const dialogVisible = ref(false) // 弹窗
  72. const formRef = ref() // 表单 Ref
  73. const outingConfirmationForm = ref({
  74. elderName: '',
  75. outingAbility: '',
  76. elderSign: '',
  77. guardianSign: '',
  78. signDate: ''
  79. }) // 外出情况确认书表单数据
  80. const isDetail = ref(false) // 是否详情打开
  81. const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
  82. let dataForm = ref({
  83. // 表单字段
  84. id: undefined,
  85. idCard: '',
  86. contractNumber: '', //档案号
  87. elderName: '',//长者姓名
  88. bedName: '', //床位号
  89. elderAge: '', //年龄
  90. elderSex: '', //性别
  91. checkInTime: '', //入院日期
  92. elderId: '',
  93. tenantId: undefined
  94. })
  95. const elderUp = (e) => {
  96. dataForm.value.elderName = e.elderName
  97. dataForm.value.elderId = e.id
  98. dataForm.value.elderSex = e.elderSex === 1 ? '男' : '女'
  99. dataForm.value.bedName = e.bedName || ''
  100. dataForm.value.checkInTime = e.checkInTime
  101. dataForm.value.contractNumber = e.contractNumber||e.fileNumber
  102. dataForm.value.elderAge = e.elderAge
  103. // 同步长者姓名到外出情况确认书
  104. outingConfirmationForm.value.elderName = e.elderName
  105. }
  106. // ========== 攻击风险因素评估量表 表单序列化方法 ==========
  107. const open = (params1, params2, params3) => {
  108. dialogVisible.value = true
  109. title.value = params.title
  110. isDetail.value = params.isDetail
  111. dataForm.value = params.data
  112. }
  113. defineExpose({ open }) // 提供 open 方法,用于打开弹窗
  114. /** 提交表单 */
  115. const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
  116. const submitForm = async () => {
  117. if (formLoading.value) {
  118. return
  119. }
  120. formLoading.value = true
  121. // 提交请求
  122. try {
  123. const tempParams = {
  124. ...dataForm.value,
  125. assessData: JSON.stringify({
  126. outingConfirmation: outingConfirmationForm.value
  127. }),
  128. assessor: dataForm.value.assessor,
  129. assessDate: dataForm.value.assessDate ? dayjs(dataForm.value.assessDate).format('YYYY-MM-DD') : ''
  130. }
  131. if (dataForm.value.id) {
  132. const res = await attackRiskUpdate(tempParams)
  133. if (res) {
  134. message.success(t('common.updateSuccess'))
  135. dialogVisible.value = false
  136. // 发送操作成功的事件
  137. emit('success')
  138. }
  139. } else {
  140. const res = await attackRiskCreate(tempParams)
  141. if (res) {
  142. message.success(t('common.createSuccess'))
  143. dialogVisible.value = false
  144. // 发送操作成功的事件
  145. emit('success')
  146. }
  147. }
  148. } finally {
  149. setTimeout(() => {
  150. formLoading.value = false
  151. }, 500)
  152. }
  153. }
  154. /** 重置表单 */
  155. const resetForm = () => {
  156. formRef.value?.resetFields()
  157. }
  158. // 关闭表单
  159. const handleClosed = () => {
  160. dialogVisible.value = false
  161. resetForm()
  162. }
  163. </script>
  164. <style scoped lang="scss">
  165. .form-title {
  166. text-align: center;
  167. font-size: 20px;
  168. width: 100%;
  169. margin-bottom: 20px;
  170. }
  171. .attack-risk-form {
  172. max-width: 1200px;
  173. margin: 0 auto;
  174. background: #fff;
  175. .info-row {
  176. display: flex;
  177. gap: 40px;
  178. width: 100%;
  179. flex-direction: row;
  180. align-items: center;
  181. margin-bottom: 10px;
  182. .info-item {
  183. display: flex;
  184. align-items: center;
  185. gap: 8px;
  186. .label {
  187. width: 82px;
  188. text-align: right;
  189. margin-right: 4px;
  190. white-space: nowrap;
  191. }
  192. }
  193. }
  194. .form-body {
  195. border: 1px solid #333;
  196. padding: 15px;
  197. }
  198. // 调整 Element Plus 组件样式
  199. :deep(.el-input__inner) {
  200. height: 28px;
  201. line-height: 28px;
  202. border-top: none;
  203. border-left: none;
  204. border-right: none;
  205. border-radius: 0;
  206. padding: 0 4px;
  207. &:focus {
  208. border-color: #409eff;
  209. }
  210. }
  211. :deep(.el-checkbox__label),
  212. :deep(.el-radio__label) {
  213. padding-left: 4px;
  214. }
  215. }
  216. .row{
  217. margin-bottom: 12px;
  218. display: flex;
  219. flex-direction: row;
  220. align-items: center;
  221. text{
  222. text-align: right;
  223. margin-right: 4px;
  224. width: 82px;
  225. }
  226. }
  227. // NGASR自杀风险评估量表 特有样式
  228. .total-score-section {
  229. display: flex;
  230. justify-content: space-between;
  231. align-items: center;
  232. padding: 15px;
  233. background: #f5f7fa;
  234. border-radius: 4px;
  235. margin-bottom: 20px;
  236. .total-score {
  237. display: flex;
  238. align-items: baseline;
  239. gap: 4px;
  240. .score-label {
  241. font-size: 16px;
  242. font-weight: bold;
  243. }
  244. .score-value {
  245. font-size: 28px;
  246. font-weight: bold;
  247. color: #409eff;
  248. }
  249. .score-max {
  250. font-size: 14px;
  251. color: #909399;
  252. }
  253. }
  254. .risk-level {
  255. font-size: 16px;
  256. font-weight: bold;
  257. padding: 8px 16px;
  258. border-radius: 4px;
  259. &.risk-none {
  260. color: #67c23a;
  261. background: #f0f9eb;
  262. }
  263. &.risk-low {
  264. color: #e6a23c;
  265. background: #fdf6ec;
  266. }
  267. &.risk-medium {
  268. color: #f56c6c;
  269. background: #fef0f0;
  270. }
  271. &.risk-high {
  272. color: #f56c6c;
  273. background: #fef0f0;
  274. border: 1px solid #f56c6c;
  275. }
  276. }
  277. }
  278. .assessment-table {
  279. width: 100%;
  280. border-collapse: collapse;
  281. margin-bottom: 20px;
  282. table {
  283. width: 100%;
  284. border: 1px solid #333;
  285. th, td {
  286. border: 1px solid #333;
  287. padding: 12px;
  288. text-align: left;
  289. vertical-align: top;
  290. }
  291. th {
  292. background: #f5f7fa;
  293. font-weight: bold;
  294. text-align: center;
  295. }
  296. .content-col {
  297. width: 65%;
  298. }
  299. .level-col {
  300. width: 10%;
  301. text-align: center;
  302. }
  303. .select-col {
  304. width: 25%;
  305. text-align: center;
  306. }
  307. .content {
  308. text-align: left;
  309. .content-title {
  310. font-weight: bold;
  311. margin-bottom: 8px;
  312. }
  313. .content-item {
  314. margin-left: 15px;
  315. margin-bottom: 4px;
  316. font-size: 13px;
  317. }
  318. }
  319. .level {
  320. text-align: center;
  321. font-weight: bold;
  322. }
  323. .select {
  324. text-align: center;
  325. :deep(.el-radio) {
  326. margin-right: 0;
  327. }
  328. }
  329. }
  330. }
  331. .risk-judgment-section {
  332. margin: 20px 0;
  333. padding: 15px;
  334. background: #f5f7fa;
  335. border-radius: 4px;
  336. border: 1px solid #e4e7ed;
  337. .risk-judgment-title {
  338. font-weight: bold;
  339. font-size: 16px;
  340. margin-bottom: 12px;
  341. color: #303133;
  342. }
  343. .risk-options {
  344. display: flex;
  345. flex-wrap: wrap;
  346. gap: 20px;
  347. :deep(.el-radio) {
  348. margin-right: 0;
  349. }
  350. }
  351. }
  352. .preventive-section {
  353. margin: 20px 0;
  354. padding: 15px;
  355. background: #f5f7fa;
  356. border-radius: 4px;
  357. border: 1px solid #e4e7ed;
  358. .preventive-title {
  359. font-weight: bold;
  360. font-size: 16px;
  361. margin-bottom: 12px;
  362. color: #303133;
  363. }
  364. .preventive-options {
  365. display: flex;
  366. flex-wrap: wrap;
  367. gap: 15px;
  368. :deep(.el-checkbox) {
  369. margin-right: 20px;
  370. margin-bottom: 8px;
  371. }
  372. .other-input {
  373. width: 200px;
  374. margin-left: 10px;
  375. }
  376. }
  377. }
  378. .signature-section {
  379. margin: 20px 0;
  380. padding: 15px;
  381. background: #f5f7fa;
  382. border-radius: 4px;
  383. border: 1px solid #e4e7ed;
  384. .signature-row {
  385. display: flex;
  386. justify-content: space-between;
  387. align-items: center;
  388. gap: 20px;
  389. }
  390. .signature-item {
  391. display: flex;
  392. align-items: center;
  393. gap: 10px;
  394. &.date-item {
  395. :deep(.el-date-picker) {
  396. width: 150px;
  397. }
  398. }
  399. }
  400. .signature-label {
  401. font-weight: bold;
  402. white-space: nowrap;
  403. }
  404. .signature-input {
  405. width: 150px;
  406. }
  407. .date-picker {
  408. width: 150px;
  409. }
  410. }
  411. .note-section {
  412. margin-top: 20px;
  413. padding: 15px;
  414. background: #f5f7fa;
  415. border-radius: 4px;
  416. border: 1px solid #e4e7ed;
  417. .note-title {
  418. font-weight: bold;
  419. font-size: 16px;
  420. margin-bottom: 12px;
  421. color: #303133;
  422. }
  423. .note-content {
  424. font-size: 13px;
  425. line-height: 1.8;
  426. color: #606266;
  427. p {
  428. margin: 5px 0;
  429. }
  430. .indent {
  431. margin-left: 20px;
  432. }
  433. }
  434. }
  435. </style>