FillAderverseEvent.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. <template>
  2. <div class="layout_container">
  3. <header class="round-header">
  4. <el-button
  5. type="primary"
  6. icon="RefreshLeft"
  7. @click="genNewReport"
  8. >
  9. 填写新报告
  10. </el-button>
  11. <el-button
  12. type="primary"
  13. icon="Edit"
  14. @click="beforeSubmit"
  15. :disabled="disableSubmit"
  16. >
  17. 提交/修改当前报告
  18. </el-button>
  19. </header>
  20. <div class="layout_main layout_container layout-horizontal">
  21. <aside>
  22. <el-table
  23. :data="histories"
  24. stripe
  25. highlight-current-row
  26. @row-click="fetchReportDetail">
  27. <el-table-column prop="submitDatetime" label="提交时间" width="130"></el-table-column>
  28. <el-table-column prop="category" label="事件类型"></el-table-column>
  29. <el-table-column label="受理" width="60">
  30. <template v-slot="scope">
  31. <span v-html="filterAccepted(scope.row.accepted)"></span>
  32. </template>
  33. </el-table-column>
  34. <el-table-column label="处理" width="60">
  35. <template v-slot="scope">
  36. <span v-html="filterHandled(scope.row.handled)"></span>
  37. </template>
  38. </el-table-column>
  39. </el-table>
  40. </aside>
  41. <div class="layout_main">
  42. <el-row :gutter="5">
  43. <el-col :span="12">
  44. <el-tag>事件信息</el-tag>
  45. <el-row :gutter="5">
  46. <el-col :span="8">
  47. <el-tag type="info">事件类型</el-tag>
  48. <div></div>
  49. <el-select v-model="report.category" placeholder="请选择" style="width: 100%">
  50. <el-option-group v-for="group in dict.categories" :key="group.id" :label="group.name">
  51. <el-option v-for="item in group.children" :key="item.id" :label="item.name"
  52. :value="group.name + ' - ' + item.name"></el-option>
  53. </el-option-group>
  54. </el-select>
  55. </el-col>
  56. <el-col :span="9">
  57. <el-tag type="info">发生日期:</el-tag>
  58. <div></div>
  59. <el-date-picker v-model="report.occurDatetime" type="datetime" placeholder="选择日期时间"
  60. style="width: 100%"></el-date-picker>
  61. </el-col>
  62. <el-col :span="7">
  63. <el-tag type="info">发生科室:</el-tag>
  64. <div></div>
  65. <el-select v-model="report.deptCode" placeholder="请选择" style="width: 100%">
  66. <el-option v-for="item in depts" :key="item.code" :label="item.name" :value="item.code"></el-option>
  67. </el-select>
  68. </el-col>
  69. </el-row>
  70. </el-col>
  71. <el-col :span="12">
  72. <el-tag>提交人信息</el-tag>
  73. <el-row :gutter="5">
  74. <el-col :span="8">
  75. <el-tag type="info">姓名:</el-tag>
  76. <div></div>
  77. <el-input v-model="report.userName" style="width: 100%" readonly></el-input>
  78. </el-col>
  79. <el-col :span="8">
  80. <el-tag type="info">职称:</el-tag>
  81. <div></div>
  82. <el-select v-model="report.userLevel" placeholder="请选择" style="width: 100%">
  83. <el-option v-for="item in dict.positions" :key="item.id" :label="item.name"
  84. :value="item.name"></el-option>
  85. </el-select>
  86. </el-col>
  87. <el-col :span="8">
  88. <el-tag type="info">工作年限:</el-tag>
  89. <div></div>
  90. <el-input-number v-model="report.workYear" :min="0" :max="10" style="width: 100%"></el-input-number>
  91. </el-col>
  92. </el-row>
  93. </el-col>
  94. </el-row>
  95. <div style="height: 10px"></div>
  96. <el-row :gutter="5">
  97. <el-col :span="12">
  98. <el-tag>事件经过</el-tag>
  99. <el-input type="textarea" :rows="5" placeholder="请输入内容" v-model="report.course" maxlength="200"
  100. show-word-limit style="width: 100%"></el-input>
  101. </el-col>
  102. <el-col :span="12">
  103. <el-tag>事件结果与补救措施</el-tag>
  104. <el-input type="textarea" :rows="5" placeholder="请输入内容" v-model="report.result" maxlength="100"
  105. show-word-limit style="width: 100%"></el-input>
  106. </el-col>
  107. </el-row>
  108. <div style="height: 10px"></div>
  109. <el-tag>原因分析</el-tag>
  110. <el-row :gutter="5">
  111. <el-col :span="6">
  112. <el-tag type="info">护士因素:</el-tag>
  113. <div></div>
  114. <el-select v-model="report.nurseReasonArr" multiple collapse-tags placeholder="请选择" style="width: 100%">
  115. <el-option v-for="item in dict.nurseReasons" :key="item.id" :label="item.name" :value="item.name">
  116. <span style="overflow: auto">{{ item.name }}</span>
  117. </el-option>
  118. </el-select>
  119. <el-input v-model="report.nurseReasonElse" placeholder="其他护士因素" style="width: 100%"></el-input>
  120. </el-col>
  121. <el-col :span="6">
  122. <el-tag type="info">病人因素:</el-tag>
  123. <div></div>
  124. <el-select v-model="report.patientReasonArr" multiple collapse-tags placeholder="请选择" style="width: 100%">
  125. <el-option v-for="item in dict.patientReasons" :key="item.id" :label="item.name" :value="item.name">
  126. <span style="overflow: auto">{{ item.name }}</span>
  127. </el-option>
  128. </el-select>
  129. <el-input v-model="report.patientReasonElse" placeholder="其他病人因素" style="width: 100%"></el-input>
  130. </el-col>
  131. <el-col :span="6">
  132. <el-tag type="info">环境因素:</el-tag>
  133. <div></div>
  134. <el-select v-model="report.environReasonArr" multiple collapse-tags placeholder="请选择" style="width: 100%">
  135. <el-option v-for="item in dict.environReasons" :key="item.id" :label="item.name" :value="item.name">
  136. <span style="overflow: auto">{{ item.name }}</span>
  137. </el-option>
  138. </el-select>
  139. <el-input v-model="report.environReasonElse" placeholder="其他环境因素" style="width: 100%"></el-input>
  140. </el-col>
  141. <el-col :span="6">
  142. <el-tag type="info">管理因素:</el-tag>
  143. <div></div>
  144. <el-select v-model="report.manageReasonArr" multiple collapse-tags placeholder="请选择" style="width: 100%">
  145. <el-option v-for="item in dict.manageReasons" :key="item.id" :label="item.name" :value="item.name">
  146. <span style="overflow: auto">{{ item.name }}</span>
  147. </el-option>
  148. </el-select>
  149. <el-input v-model="report.manageReasonElse" placeholder="其他管理因素" style="width: 100%"></el-input>
  150. </el-col>
  151. </el-row>
  152. <div style="height: 10px"></div>
  153. <el-tag>改进措施</el-tag>
  154. <el-row :gutter="5">
  155. <el-col :span="6">
  156. <el-tag type="info">护士因素:</el-tag>
  157. <div></div>
  158. <el-select v-model="report.proNurseArr" multiple collapse-tags placeholder="请选择" style="width: 100%">
  159. <el-option v-for="item in dict.nursePros" :key="item.id" :label="item.name" :value="item.name">
  160. <span style="overflow: auto">{{ item.name }}</span>
  161. </el-option>
  162. </el-select>
  163. <el-input v-model="report.proNurseElse" placeholder="其他护士因素改进措施" style="width: 100%"></el-input>
  164. </el-col>
  165. <el-col :span="6">
  166. <el-tag type="info">病人因素:</el-tag>
  167. <div></div>
  168. <el-select v-model="report.proPatientArr" multiple collapse-tags placeholder="请选择" style="width: 100%">
  169. <el-option v-for="item in dict.patientPros" :key="item.id" :label="item.name" :value="item.name">
  170. <span style="overflow: auto">{{ item.name }}</span>
  171. </el-option>
  172. </el-select>
  173. <el-input v-model="report.proPatientElse" placeholder="其他病人因素改进措施" style="width: 100%"></el-input>
  174. </el-col>
  175. <el-col :span="6">
  176. <el-tag type="info">环境因素:</el-tag>
  177. <div></div>
  178. <el-select v-model="report.proEnvironArr" multiple collapse-tags placeholder="请选择" style="width: 100%">
  179. <el-option v-for="item in dict.environPros" :key="item.id" :label="item.name" :value="item.name">
  180. <span style="overflow: auto">{{ item.name }}</span>
  181. </el-option>
  182. </el-select>
  183. <el-input v-model="report.proEnvironElse" placeholder="其他环境因素改进措施" style="width: 100%"></el-input>
  184. </el-col>
  185. <el-col :span="6">
  186. <el-tag type="info">管理因素:</el-tag>
  187. <div></div>
  188. <el-select v-model="report.proManageArr" multiple collapse-tags placeholder="请选择" style="width: 100%">
  189. <el-option v-for="item in dict.managePros" :key="item.id" :label="item.name" :value="item.name">
  190. <span style="overflow: auto">{{ item.name }}</span>
  191. </el-option>
  192. </el-select>
  193. <el-input v-model="report.proManageElse" placeholder="其他管理因素改进措施" style="width: 100%"></el-input>
  194. </el-col>
  195. </el-row>
  196. </div>
  197. </div>
  198. </div>
  199. </template>
  200. <script setup>
  201. import {computed, onMounted, ref} from 'vue'
  202. import {dict} from '@/data/adverse-event'
  203. import {ElMessage, ElMessageBox} from 'element-plus'
  204. import {getAllDepts, getHistories, getReportDetail, submitNewReport} from '@/api/adverse-event'
  205. import {formatDatetime} from '@/utils/date'
  206. import {useUserStore} from "@/pinia/user-store";
  207. const userInfo = useUserStore().userInfo
  208. const depts = ref([])
  209. const histories = ref([])
  210. const report = initReport()
  211. const isModify = ref(false)
  212. const fetchHistories = () => {
  213. getHistories().then((res) => {
  214. histories.value = res
  215. })
  216. }
  217. const fetchReportDetail = (val) => {
  218. getReportDetail(val.pid, 'nurse').then((res) => {
  219. report.value = res
  220. isModify.value = true
  221. })
  222. }
  223. const genNewReport = () => {
  224. report.value = initReport().value
  225. isModify.value = false
  226. }
  227. const beforeSubmit = () => {
  228. const message = validateReport(report.value)
  229. if (message) {
  230. ElMessage({
  231. message,
  232. type: 'warning',
  233. duration: 2500,
  234. showClose: true,
  235. })
  236. return
  237. }
  238. ElMessageBox.confirm('确定提交此报告?', '提示', {
  239. type: 'warning',
  240. confirmButtonText: '确定',
  241. cancelButtonText: '取消',
  242. }).then(() => {
  243. report.value.isModify = isModify.value
  244. report.value.occurDatetime = formatDatetime(report.value.occurDatetime)
  245. submitNewReport(report.value).then(() => {
  246. ElMessage({
  247. message: '提交成功。',
  248. type: 'success',
  249. duration: 2000,
  250. showClose: true,
  251. })
  252. fetchHistories()
  253. genNewReport()
  254. })
  255. })
  256. .catch(() => {
  257. })
  258. }
  259. const disableSubmit = computed(() => {
  260. return report.value.handled === 1
  261. })
  262. onMounted(() => {
  263. getAllDepts().then(res => {
  264. depts.value = res
  265. fetchHistories()
  266. })
  267. })
  268. function initReport() {
  269. return ref({
  270. deptCode: userInfo.deptCode,
  271. userName: userInfo.name,
  272. category: null,
  273. occurDatetime: null,
  274. userLevel: '护士',
  275. workYear: 1,
  276. course: null,
  277. result: null,
  278. nurseReasonArr: [],
  279. nurseReasonElse: null,
  280. patientReasonArr: [],
  281. patientReasonElse: null,
  282. environReasonArr: [],
  283. environReasonElse: null,
  284. manageReasonArr: [],
  285. manageReasonElse: null,
  286. proNurseArr: [],
  287. proNurseElse: null,
  288. proPatientArr: [],
  289. proPatientElse: null,
  290. proEnvironArr: [],
  291. proEnvironElse: null,
  292. proManageArr: [],
  293. proManageElse: null,
  294. })
  295. }
  296. function validateReport(val) {
  297. if (!val.category) {
  298. return '请选择事件类型!'
  299. }
  300. if (!val.occurDatetime) {
  301. return '请选择发生日期!'
  302. }
  303. if (!val.deptCode) {
  304. return '请选择发生科室!'
  305. }
  306. if (!val.course) {
  307. return '请填写事件经过!'
  308. }
  309. if (!val.result) {
  310. return '请填写事件结果与补救措施!'
  311. }
  312. if (val.nurseReasonArr.length === 0) {
  313. return '请选择护士因素!'
  314. }
  315. if (val.proNurseArr.length === 0) {
  316. return '请选择护士因素改进措施!'
  317. }
  318. return null
  319. }
  320. function filterAccepted(val) {
  321. return val === 1 ? '<span style="color:green">已受理</span>' : '<span style="color:red">未受理</span>'
  322. }
  323. function filterHandled(val) {
  324. return val === 1 ? '<span style="color:green">已处理</span>' : '<span style="color:red">未处理</span>'
  325. }
  326. </script>