SurgeryArrangement.vue 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216
  1. <template>
  2. <div class="layout_container surgery-arrangement">
  3. <header>
  4. <el-date-picker
  5. v-model="dateRange"
  6. :shortcuts="shortcuts"
  7. end-placeholder="结束日期"
  8. range-separator="至"
  9. start-placeholder="开始日期"
  10. style="width: 220px"
  11. type="daterange"
  12. />
  13. &nbsp;&nbsp;病房:
  14. <el-select
  15. v-model="queryParam.ward"
  16. clearable
  17. filterable
  18. style="width: 120px"
  19. >
  20. <el-option
  21. v-for="item in wardList"
  22. :key="item.code"
  23. :label="item.name"
  24. :value="item.code"
  25. ></el-option>
  26. </el-select>
  27. &nbsp;&nbsp;住院号:
  28. <el-input
  29. v-model="queryParam.patNo"
  30. clearable
  31. style="width: 100px"
  32. ></el-input>
  33. &nbsp;&nbsp;状态:
  34. <el-select v-model="queryParam.status" style="width: 80px">
  35. <el-option
  36. v-for="item in statusList"
  37. :key="item.code"
  38. :label="item.name"
  39. :value="item.code"
  40. ></el-option>
  41. </el-select>
  42. <el-divider direction="vertical" />
  43. <el-checkbox v-model="queryParam.jzFlag">急诊</el-checkbox>
  44. <el-divider direction="vertical" />
  45. <el-button
  46. icon="Search"
  47. type="primary"
  48. @click="clickQuery"
  49. >
  50. 查询
  51. </el-button>
  52. <el-button
  53. icon="Printer"
  54. type="danger"
  55. @click="clickPrint"
  56. >
  57. 打印
  58. </el-button>
  59. <el-button
  60. icon="PieChart"
  61. type="success"
  62. @click="showSurgeryStatistics"
  63. >
  64. 统计
  65. </el-button>
  66. <el-select
  67. v-model="displayRoom"
  68. style="width: 120px;
  69. margin-left: 12px"
  70. @change="handleChangeDisplay"
  71. >
  72. <el-option value="ALL" label="查看全部" />
  73. <el-option value="NORMAL" label="只看普通手术间" />
  74. <el-option value="OTHER" label="只看其他手术间" />
  75. </el-select>
  76. </header>
  77. <div class="layout_main layout_el-table">
  78. <div>
  79. <el-tag
  80. effect="dark"
  81. size="small"
  82. type="danger"
  83. >
  84. 急诊:{{ emergencyCount }}条
  85. </el-tag>
  86. <el-tag
  87. effect="dark"
  88. size="small"
  89. >
  90. 普通:{{ cptSrgLst.length - emergencyCount }}条
  91. </el-tag>
  92. </div>
  93. <el-table
  94. :data="
  95. cptSrgLst.slice(
  96. (currentPage - 1) * pageSize,
  97. currentPage * pageSize
  98. )
  99. "
  100. border
  101. :row-class-name="differChargedRows"
  102. header-cell-class-name="cell-border"
  103. cell-class-name="cell-border"
  104. >
  105. <el-table-column label="手术编号" prop="recordId" width="55">
  106. <template #default="scope">
  107. <el-tag
  108. :type="scope.row.urgentClinicFlag === '1' ? 'danger' : 'primary'"
  109. effect="dark"
  110. >
  111. {{ scope.row.recordId }}
  112. </el-tag>
  113. </template>
  114. </el-table-column>
  115. <el-table-column label="日期" width="125">
  116. <template #default="scope">
  117. <div v-if="scope.row.status === 'd'">
  118. {{ scope.row.opDatetime }}
  119. </div>
  120. <el-input
  121. v-else
  122. v-model="scope.row.opDatetime"
  123. readonly
  124. @click="beforeChargeOpTime(scope.row)"
  125. ></el-input>
  126. </template>
  127. </el-table-column>
  128. <el-table-column
  129. label="送出时间"
  130. prop="applyDate"
  131. width="118"
  132. ></el-table-column>
  133. <el-table-column label="手术间" prop="roomName" width="50">
  134. <template #default="scope">
  135. <div v-if="scope.row.status === 'd'">{{ scope.row.roomName }}</div>
  136. <el-select
  137. v-else
  138. v-model="scope.row.roomCode"
  139. @focus="handleSelectionFocus(scope.row, 'roomCode')"
  140. @change="
  141. roomCode =>
  142. handleSelectionChange(
  143. scope.row.recordId,
  144. 'room_code',
  145. roomCode
  146. )
  147. "
  148. placeholder=" "
  149. class="el-select_no-suffix"
  150. >
  151. <el-option
  152. v-for="item in allRooms"
  153. :value="item.code"
  154. :label="item.name"
  155. ></el-option>
  156. </el-select>
  157. </template>
  158. </el-table-column>
  159. <el-table-column
  160. label="科室"
  161. prop="deptName"
  162. width="78"
  163. ></el-table-column>
  164. <el-table-column label="台次" prop="sstc" width="40">
  165. <template #default="{ row }">
  166. <div v-if="row.status === 'd'">{{ row.sstc }}</div>
  167. <el-select
  168. v-else
  169. v-model="row.sstc"
  170. @focus="handleSelectionFocus(row, 'sstc')"
  171. @change="
  172. sstc => handleSelectionChange(row.recordId, 'sstc', sstc)
  173. "
  174. placeholder=" "
  175. clearable
  176. class="el-select_no-suffix"
  177. >
  178. <el-option value="" label="清空"></el-option>
  179. <el-option v-for="n in 12" :value="n" :label="n"></el-option>
  180. </el-select>
  181. </template>
  182. </el-table-column>
  183. <el-table-column label="床号" prop="bedNo" width="30"></el-table-column>
  184. <el-table-column
  185. label="住院号"
  186. prop="inpatientNo"
  187. width="60"
  188. ></el-table-column>
  189. <el-table-column label="姓名" width="50">
  190. <template #default="scope">
  191. <div style="height: 32px; line-height: 32px">
  192. {{ scope.row.patientName }}
  193. </div>
  194. </template>
  195. </el-table-column>
  196. <el-table-column label="年龄" prop="age" width="33"></el-table-column>
  197. <el-table-column label="性别" prop="sex" width="30"></el-table-column>
  198. <el-table-column
  199. label="手术名称"
  200. prop="opName"
  201. width="183"
  202. ></el-table-column>
  203. <el-table-column
  204. label="麻醉方式"
  205. prop="hocusName"
  206. width="165"
  207. ></el-table-column>
  208. <el-table-column label="麻醉医生" prop="doctorMzYsName" width="60">
  209. <template #default="scope">
  210. <div v-if="scope.row.status === 'd'">
  211. {{ scope.row.doctorMzYsName }}
  212. </div>
  213. <el-select
  214. v-else
  215. v-model="scope.row.doctorMzYs"
  216. filterable
  217. @focus="handleSelectionFocus(scope.row, 'doctorMzYs')"
  218. @change="
  219. doctorMzYs =>
  220. handleSelectionChange(
  221. scope.row.recordId,
  222. 'doctor_mz_ys',
  223. doctorMzYs
  224. )
  225. "
  226. placeholder=" "
  227. class="el-select_no-suffix"
  228. >
  229. <el-option
  230. v-for="item in aneStaffs"
  231. :value="item.code"
  232. :label="item.name"
  233. :key="'doctor_mz_ys-' + item.code"
  234. ></el-option>
  235. </el-select>
  236. </template>
  237. </el-table-column>
  238. <el-table-column label="主刀医生" width="55">
  239. <template #default="scope">
  240. <div v-if="scope.row.status === 'd'">
  241. {{ scope.row.doctorZdName }}
  242. </div>
  243. <el-input
  244. v-else
  245. v-model="scope.row.doctorZdName"
  246. @click="beforeSearch(scope.row, 'doctor_zd')"
  247. ></el-input>
  248. </template>
  249. </el-table-column>
  250. <el-table-column label="一助" width="55">
  251. <template #default="scope">
  252. <div v-if="scope.row.status === 'd'">
  253. {{ scope.row.doctor1Name }}
  254. </div>
  255. <el-input
  256. v-else
  257. v-model="scope.row.doctor1Name"
  258. @click="beforeSearch(scope.row, 'doctor_1')"
  259. ></el-input>
  260. </template>
  261. </el-table-column>
  262. <el-table-column label="二助" width="55">
  263. <template #default="scope">
  264. <div v-if="scope.row.status === 'd'">
  265. {{ scope.row.doctor2Name }}
  266. </div>
  267. <el-input
  268. v-else
  269. v-model="scope.row.doctor2Name"
  270. @click="beforeSearch(scope.row, 'doctor_2')"
  271. ></el-input>
  272. </template>
  273. </el-table-column>
  274. <el-table-column label="器械护士" width="60">
  275. <template #default="scope">
  276. <div v-if="scope.row.status === 'd'">
  277. {{ scope.row.nurseQxName }}
  278. </div>
  279. <el-select
  280. v-else
  281. v-model="scope.row.nurseQx"
  282. filterable
  283. @focus="handleSelectionFocus(scope.row, 'nurseQx')"
  284. @change="
  285. nurseQx =>
  286. handleSelectionChange(scope.row.recordId, 'nurse_qx', nurseQx)
  287. "
  288. placeholder=" "
  289. class="el-select_no-suffix"
  290. >
  291. <el-option
  292. v-for="item in surStaffs"
  293. :value="item.code"
  294. :label="item.name"
  295. :key="'nurse_qx-' + item.code"
  296. ></el-option>
  297. </el-select>
  298. </template>
  299. </el-table-column>
  300. <el-table-column label="巡回护士" width="60">
  301. <template #default="scope">
  302. <div v-if="scope.row.status === 'd'">
  303. {{ scope.row.nurseXhName }}
  304. </div>
  305. <el-select
  306. v-else
  307. v-model="scope.row.nurseXh"
  308. filterable
  309. @focus="handleSelectionFocus(scope.row, 'nurseXh')"
  310. @change="
  311. nurseXh =>
  312. handleSelectionChange(scope.row.recordId, 'nurse_xh', nurseXh)
  313. "
  314. placeholder=" "
  315. class="el-select_no-suffix"
  316. >
  317. <el-option
  318. v-for="item in surStaffs"
  319. :value="item.code"
  320. :label="item.name"
  321. :key="'nurse_xh-' + item.code"
  322. ></el-option>
  323. </el-select>
  324. </template>
  325. </el-table-column>
  326. <el-table-column
  327. label="申请医生"
  328. prop="applyDocName"
  329. width="55"
  330. ></el-table-column>
  331. <el-table-column
  332. label="诊断"
  333. prop="diagBeforeOp"
  334. width="135"
  335. ></el-table-column>
  336. <el-table-column label="分类" width="50">
  337. <template #default="scope">
  338. <div v-if="scope.row.status === 'd'">
  339. {{ filterUrgentClinicFlag(scope.row.urgentClinicFlag) }}
  340. </div>
  341. <el-select
  342. v-else
  343. v-model="scope.row.urgentClinicFlag"
  344. placeholder=" "
  345. @focus="handleSelectionFocus(scope.row, 'urgentClinicFlag')"
  346. @change="
  347. urgentClinicFlag =>
  348. handleSelectionChange(
  349. scope.row.recordId,
  350. 'urgent_clinic_flag',
  351. urgentClinicFlag
  352. )
  353. "
  354. class="el-select_no-suffix"
  355. >
  356. <el-option label="普通" value="0"></el-option>
  357. <el-option label="急诊" value="1"></el-option>
  358. <el-option label="择期" value="2"></el-option>
  359. <el-option label="限期" value="3"></el-option>
  360. </el-select>
  361. </template>
  362. </el-table-column>
  363. <el-table-column label="班次" width="50">
  364. <template #default="scope">
  365. <div v-if="scope.row.status === 'd'">
  366. {{ filterSsbc(scope.row.ssbc) }}
  367. </div>
  368. <el-select
  369. v-else
  370. v-model="scope.row.ssbc"
  371. placeholder=" "
  372. class="el-select_no-suffix"
  373. >
  374. <el-option label="正常" value="0"></el-option>
  375. <el-option label="正常" value="1"></el-option>
  376. <el-option label="加班" value="2"></el-option>
  377. </el-select>
  378. </template>
  379. </el-table-column>
  380. <el-table-column label="级别" width="70">
  381. <template #default="scope">
  382. <div v-if="scope.row.status === 'd'">
  383. {{ filterOpScale(scope.row.opScale) }}
  384. </div>
  385. <el-select
  386. v-else
  387. v-model="scope.row.opScale"
  388. placeholder=" "
  389. class="el-select_no-suffix"
  390. >
  391. <el-option label="一级手术" value="1"></el-option>
  392. <el-option label="二级手术" value="2"></el-option>
  393. <el-option label="三级手术" value="3"></el-option>
  394. <el-option label="四级手术" value="4"></el-option>
  395. </el-select>
  396. </template>
  397. </el-table-column>
  398. <el-table-column label="体外" width="40">
  399. <template #default="scope">
  400. <div v-if="scope.row.status === 'd'">
  401. {{ filterTwFlag(scope.row.twFlag) }}
  402. </div>
  403. <el-select
  404. v-else
  405. v-model="scope.row.twFlag"
  406. @focus="handleSelectionFocus(scope.row, 'twFlag')"
  407. @change="
  408. twFlag =>
  409. handleSelectionChange(scope.row.recordId, 'tw_flag', twFlag)
  410. "
  411. placeholder=" "
  412. class="el-select_no-suffix"
  413. >
  414. <el-option label="否" value="0"></el-option>
  415. <el-option label="是" value="1"></el-option>
  416. </el-select>
  417. </template>
  418. </el-table-column>
  419. <el-table-column label="术前访视">
  420. <template #default="scope">
  421. <div
  422. v-if="scope.row.status === 'd'"
  423. :title="scope.row.preoperativeVisit"
  424. >
  425. {{ scope.row.preoperativeVisit }}
  426. </div>
  427. <el-input
  428. v-else
  429. v-model="scope.row.preoperativeVisit"
  430. readonly
  431. @click="inputContent(scope.row, 'preoperativeVisit')"
  432. :title="scope.row.preoperativeVisit"
  433. ></el-input>
  434. </template>
  435. </el-table-column>
  436. <el-table-column label="术前准备">
  437. <template #default="scope">
  438. <div
  439. v-if="scope.row.status === 'd'"
  440. :title="scope.row.preoperativePreparation"
  441. >
  442. {{ scope.row.preoperativePreparation }}
  443. </div>
  444. <el-input
  445. v-else
  446. v-model="scope.row.preoperativePreparation"
  447. readonly
  448. @click="inputContent(scope.row, 'preoperativePreparation')"
  449. :title="scope.row.preoperativePreparation"
  450. ></el-input>
  451. </template>
  452. </el-table-column>
  453. <el-table-column label="备注">
  454. <template #default="scope">
  455. <div v-if="scope.row.status === 'd'" :title="scope.row.remark">
  456. {{ scope.row.remark }}
  457. </div>
  458. <el-input
  459. v-else
  460. v-model="scope.row.remark"
  461. readonly
  462. @click="inputContent(scope.row, 'remark')"
  463. :title="scope.row.remark"
  464. ></el-input>
  465. </template>
  466. </el-table-column>
  467. <el-table-column
  468. label="手术开始时间"
  469. prop="opStartDate"
  470. width="118"
  471. ></el-table-column>
  472. <el-table-column
  473. label="手术结束时间"
  474. prop="opEndDate"
  475. width="118"
  476. ></el-table-column>
  477. <el-table-column
  478. label="麻醉开始时间"
  479. prop="anstStartDate"
  480. width="118"
  481. ></el-table-column>
  482. <el-table-column
  483. label="麻醉结束时间"
  484. prop="anstEndDate"
  485. width="118"
  486. ></el-table-column>
  487. <el-table-column fixed="right" label="操作" width="100">
  488. <template #default="scope">
  489. <el-button
  490. v-if="scope.row.status === 'd'"
  491. link
  492. type="primary"
  493. icon="Refresh"
  494. @click.prevent="changeSurgeryStatus(scope.row, '1')"
  495. >
  496. 恢复
  497. </el-button>
  498. <span v-else>
  499. <el-button
  500. link
  501. :type="scope.row.arrangementExecuted === 0 ? 'info' : 'primary'"
  502. :icon="scope.row.arrangementExecuted === 0 ? 'Close' : 'Check'"
  503. @click.prevent="changeArrangementExecuted(scope.row)"
  504. >
  505. {{ scope.row.arrangementExecuted === 0 ? "未接" : "已接" }}
  506. </el-button>
  507. <el-button
  508. v-if="
  509. scope.row.status !== '3' &&
  510. scope.row.arrangementExecuted === 0
  511. "
  512. link
  513. type="danger"
  514. icon="Delete"
  515. @click.prevent="changeSurgeryStatus(scope.row, 'd')"
  516. >
  517. 取消
  518. </el-button>
  519. </span>
  520. </template>
  521. </el-table-column>
  522. </el-table>
  523. <el-pagination
  524. :current-page="currentPage"
  525. :page-size="pageSize"
  526. :total="cptSrgLst.length"
  527. layout="total,prev, pager, next"
  528. @current-change="handleCurrentChange"
  529. ></el-pagination>
  530. </div>
  531. </div>
  532. <search
  533. v-if="showSearch"
  534. :title="titleOfSearch"
  535. target="physician"
  536. show-emp-dept
  537. @close="showSearch = false"
  538. @click-item="handleClickSearchResult"
  539. ></search>
  540. <div
  541. id="printArea"
  542. style="position: fixed; background: white; color: black; opacity: 0"
  543. >
  544. <div
  545. style="
  546. width: 100%;
  547. margin-top: 12px;
  548. text-align: center;
  549. height: 36px;
  550. line-height: 36px;
  551. font-size: 22px;
  552. font-weight: bold;
  553. "
  554. >
  555. 手 术 安 排 表({{ nowdate }})
  556. </div>
  557. <div style="width: 100%; padding-left: 30px; height: 32px">
  558. 打印时间:{{ nowdatetime }}
  559. </div>
  560. <div style="padding-left: 30px">
  561. <div
  562. style="
  563. display: flex;
  564. align-items: center;
  565. justify-content: center;
  566. font-weight: bold;
  567. font-size: 12px;
  568. height: 30px;
  569. border-bottom: 1px solid black;
  570. "
  571. >
  572. <div style="width: 170px">手术日期</div>
  573. <div style="width: 90px">手术间</div>
  574. <div style="width: 160px">科室 - 床号</div>
  575. <div style="width: 80px">住院号</div>
  576. <div style="width: 160px">年龄 - 性别 - 姓名</div>
  577. <div style="width: 260px">手术名称</div>
  578. <div style="width: 170px; margin-left: 16px">麻醉方式</div>
  579. <div style="width: 80px">麻醉医生</div>
  580. <div style="width: 80px">手术医生</div>
  581. <div style="width: 80px">器械护士</div>
  582. <div style="width: 80px">巡回护士</div>
  583. </div>
  584. <div style="height: 8px"></div>
  585. <div
  586. v-for="item in surgeryListForPrint"
  587. style="
  588. display: flex;
  589. align-items: center;
  590. justify-content: center;
  591. font-size: 12px;
  592. height: 32px;
  593. border-bottom: 1px solid black;
  594. "
  595. >
  596. <div style="width: 170px">{{ item.opDatetime }}</div>
  597. <div style="width: 90px">{{ item.roomName }}</div>
  598. <div style="width: 160px">
  599. {{ item.deptName }} - {{ item.bedNo }}床
  600. </div>
  601. <div style="width: 80px">{{ item.inpatientNo }}</div>
  602. <div style="width: 160px">
  603. {{ item.age }} - {{ item.sex }} - {{ item.patientName }}
  604. </div>
  605. <div style="width: 260px">{{ item.opName }}</div>
  606. <div style="width: 170px; margin-left: 16px">{{ item.hocusName }}</div>
  607. <div style="width: 80px">{{ item.doctorMzYsName }}</div>
  608. <div style="width: 80px">{{ item.doctorZdName }}</div>
  609. <div style="width: 80px">{{ item.nurseQxName }}</div>
  610. <div style="width: 80px">{{ item.nurseXhName }}</div>
  611. </div>
  612. </div>
  613. </div>
  614. <el-dialog v-model="surgeryStatisticsVisible" title="手术统计" width="70%">
  615. <div style="display: flex; align-items: center">
  616. <div style="width: 220px">
  617. <el-date-picker
  618. v-model="statisticsDateRange"
  619. :shortcuts="shortcuts"
  620. end-placeholder="结束日期"
  621. range-separator="至"
  622. start-placeholder="开始日期"
  623. style="width: 200px"
  624. :clearable="false"
  625. type="daterange"
  626. />
  627. </div>
  628. <el-select
  629. v-model="statisticsRequest.statisticsLabel"
  630. style="margin-left: 12px; width: 100px"
  631. >
  632. <el-option label="按科室" value="BY_DEPARTMENT"></el-option>
  633. <el-option label="按手术" value="BY_SURGERY"></el-option>
  634. <el-option label="按级别" value="BY_LEVEL"></el-option>
  635. </el-select>
  636. <el-divider direction="vertical"></el-divider>
  637. <el-button icon="Search" @click="executeQueryStatistics">查询</el-button>
  638. </div>
  639. <div style="height: 500px" class="surgery-arrangement">
  640. <div
  641. style="
  642. height: 460px;
  643. margin-top: 20px;
  644. padding: 8px 0;
  645. overflow-y: scroll;
  646. background-color: #e0e0e0;
  647. "
  648. >
  649. <div v-for="(val, key) in surgeryStatistics.surgeryMap">
  650. <div
  651. style="
  652. display: flex;
  653. width: 330px;
  654. padding-left: 12px;
  655. line-height: 32px;
  656. border-bottom: 1px solid white;
  657. "
  658. >
  659. <div style="width: 32px">
  660. <div class="show-detail-icon" @click="showStatisticsDetail(key)">
  661. >
  662. </div>
  663. </div>
  664. <div style="width: 260px; padding-left: 8px; text-align: left">
  665. {{ key }}
  666. </div>
  667. <div style="width: 40px; text-align: center">
  668. <span style="font-weight: bold; color: black">{{
  669. val.length
  670. }}</span
  671. >台
  672. </div>
  673. </div>
  674. <div
  675. v-if="currentStatistics.key === key"
  676. style="background-color: white; padding: 0 12px"
  677. >
  678. <el-table :data="currentStatistics.list">
  679. <el-table-column prop="deptName" label="手术科室" />
  680. <el-table-column prop="recordId" label="手术单号" />
  681. <el-table-column prop="patientName" label="患者姓名" />
  682. <el-table-column prop="inpatientNo" label="住院号" />
  683. <el-table-column prop="applyDocName" label="申请医生" />
  684. <el-table-column prop="applyDate" label="申请时间" />
  685. <el-table-column prop="opDatetime" label="手术时间" />
  686. <el-table-column prop="opCode" label="手术编码" />
  687. <el-table-column prop="opName" label="手术名称" />
  688. <el-table-column prop="opScaleName" label="手术级别" />
  689. <el-table-column prop="urgentClinicName" label="手术分类" />
  690. <el-table-column prop="statusName" label="手术状态" />
  691. <el-table-column prop="doctorZdName" label="主刀医生" />
  692. <el-table-column prop="doctor1Name" label="一助" />
  693. <el-table-column prop="doctor2Name" label="二助" />
  694. <el-table-column prop="doctorMzName" label="麻醉医生" />
  695. <el-table-column prop="hocusName" label="麻醉方式" />
  696. <el-table-column prop="nurseXhName" label="巡回护士" />
  697. <el-table-column prop="nurseQxName" label="器械护士" />
  698. </el-table>
  699. </div>
  700. </div>
  701. </div>
  702. <div
  703. style="margin-top: 15px; font-weight: bold"
  704. v-show="surgeryStatistics.total"
  705. >
  706. 总计:{{ surgeryStatistics.total }}台
  707. </div>
  708. </div>
  709. </el-dialog>
  710. </template>
  711. <script name="SurgeryArrangement" setup>
  712. import {
  713. getDicList,
  714. notifyDoctor,
  715. queryStatistics,
  716. selectSurgeryArrangements,
  717. updateArrangement,
  718. updateSurgeryStatus,
  719. } from "@/api/surgical-management/surgery-arrangement";
  720. import {shortcuts} from "@/data/shortcuts.js";
  721. import {formatDate, formatDatetime, getDateRangeFormatDate,} from "@/utils/date";
  722. import {listIsBlank, stringNotBlank} from "@/utils/blank-utils";
  723. import {ElMessage, ElMessageBox} from "element-plus";
  724. import Search from "@/components/search/Index.vue";
  725. import router from "@/router";
  726. import {getLodop, initLodop} from "@/utils/c-lodop";
  727. const currentPage = ref(1);
  728. const pageSize = ref(30);
  729. const emergencyCount = ref(0);
  730. const wardList = ref([]);
  731. const allRooms = ref([]);
  732. const surStaffs = ref([]);
  733. const aneStaffs = ref([]);
  734. let statusList = reactive([
  735. { code: "0", name: "全部" },
  736. { code: "1", name: "申请" },
  737. { code: "2", name: "安排" },
  738. { code: "3", name: "确认" },
  739. { code: "d", name: "取消" },
  740. ]);
  741. const dateRange = ref([shortcuts[0].value[0], shortcuts[0].value[1]]);
  742. let queryParam = reactive({
  743. ward: "",
  744. patNo: "",
  745. status: "0",
  746. startTime: "",
  747. endTime: "",
  748. jzFlag: false,
  749. });
  750. const surgeryList = ref([]);
  751. const cptSrgLst = ref([])
  752. const displayRoom = ref('ALL')
  753. function handleChangeDisplay(val) {
  754. if (val === "ALL") {
  755. cptSrgLst.value = surgeryList.value;
  756. } else if (val === "NORMAL") {
  757. cptSrgLst.value = surgeryList.value.filter(item => {
  758. return !item.roomCode || (parseInt(item.roomCode) < 15)
  759. })
  760. } else {
  761. cptSrgLst.value = surgeryList.value.filter(item => {
  762. return item.roomCode && (parseInt(item.roomCode) >= 15)
  763. })
  764. }
  765. calEmergencyCount(cptSrgLst.value)
  766. }
  767. function calEmergencyCount(list) {
  768. emergencyCount.value = 0
  769. list.forEach(item => {
  770. if (stringNotBlank(item.urgentClinicFlag)) {
  771. if (item.urgentClinicFlag === "1") {
  772. emergencyCount.value++;
  773. }
  774. }
  775. });
  776. }
  777. let surgeryListForPrint = computed(() => {
  778. return surgeryList.value.filter(item => {
  779. return item.status !== "d";
  780. });
  781. });
  782. const clickQuery = () => {
  783. if (listIsBlank(dateRange.value)) {
  784. ElMessage.error("请先输入日期");
  785. return;
  786. }
  787. let dateS = getDateRangeFormatDate(dateRange.value);
  788. queryParam.startTime = dateS.startTime;
  789. queryParam.endTime = dateS.endTime;
  790. selectSurgeryArrangements(queryParam).then(res => {
  791. surgeryList.value = res;
  792. handleChangeDisplay(displayRoom.value);
  793. }).catch(() => {
  794. surgeryList.value = []
  795. });
  796. };
  797. const handleCurrentChange = val => {
  798. currentPage.value = val;
  799. };
  800. const differChargedRows = ({ row }) => {
  801. if (row.chargeSum && row.chargeSum > 0) {
  802. return "charged-row";
  803. }
  804. if (row.status === "d") {
  805. return "canceled-row";
  806. }
  807. };
  808. const surgeryExecuted = row => {
  809. if (row.status === "3") {
  810. ElMessage({
  811. message: "已完成的手术不可取消。",
  812. type: "error",
  813. duration: 2500,
  814. showClose: true,
  815. });
  816. return true;
  817. }
  818. return false;
  819. };
  820. const arrangementExecuted = row => {
  821. if (row.arrangementExecuted === 1) {
  822. ElMessage({
  823. message: "已接的手术不可取消。",
  824. type: "error",
  825. duration: 2500,
  826. showClose: true,
  827. });
  828. return true;
  829. }
  830. return false;
  831. };
  832. const changeSurgeryStatus = (row, status) => {
  833. if (!surgeryExecuted(row) && !arrangementExecuted(row)) {
  834. currentRow.value = row;
  835. updateSurgeryStatus(row.recordId, status).then(() => {
  836. currentRow.value.status = status;
  837. });
  838. }
  839. };
  840. const changeArrangementExecuted = row => {
  841. currentRow.value = row;
  842. const targetVal = row.arrangementExecuted === 0 ? 1 : 0;
  843. updateArrangement(row.recordId, "arrangement_executed", targetVal).then(
  844. () => {
  845. currentRow.value.arrangementExecuted = targetVal;
  846. if (targetVal === 1) {
  847. cyMessageBox
  848. .confirm({
  849. title: "提示",
  850. message: "是否向手术医生发送通知?",
  851. type: "warning",
  852. })
  853. .then(() => {
  854. notifyDoctor(row).then(res2 => {
  855. ElMessage({
  856. message: res2,
  857. type: "success",
  858. duration: 2000,
  859. showClose: true,
  860. });
  861. });
  862. });
  863. }
  864. }
  865. );
  866. };
  867. const showSearch = ref(false);
  868. const titleOfSearch = ref("");
  869. const currentRow = ref({});
  870. const currentKey = ref("");
  871. const beforeSearch = (row, col) => {
  872. currentRow.value = row;
  873. currentKey.value = col;
  874. titleOfSearch.value = "手术医生";
  875. showSearch.value = true;
  876. };
  877. const handleClickSearchResult = item => {
  878. showSearch.value = false;
  879. handleArrangementChange(
  880. currentRow.value.recordId,
  881. currentKey.value,
  882. item.code
  883. ).then(() => {
  884. switch (currentKey.value) {
  885. case 'doctor_zd':
  886. currentRow.value.doctorZd = item.code;
  887. currentRow.value.doctorZdName = item.name;
  888. break;
  889. case 'doctor_1':
  890. currentRow.value.doctor1 = item.code;
  891. currentRow.value.doctor1Name = item.name;
  892. break;
  893. case 'doctor_2':
  894. currentRow.value.doctor2 = item.code;
  895. currentRow.value.doctor2Name = item.name;
  896. break;
  897. }
  898. });
  899. };
  900. const oldSelection = reactive({
  901. column: "",
  902. value: "",
  903. });
  904. const handleSelectionFocus = (row, column) => {
  905. currentRow.value = row;
  906. oldSelection.column = column;
  907. oldSelection.value = row[column];
  908. };
  909. const handleSelectionChange = (orderId, column, value) => {
  910. handleArrangementChange(orderId, column, value)
  911. .then(() => {})
  912. .catch(() => {
  913. currentRow.value[oldSelection.column] = oldSelection.value;
  914. });
  915. };
  916. const beforeChargeOpTime = row => {
  917. ElMessageBox.prompt("请输入手术时间:", "提示", {
  918. confirmButtonText: "确定",
  919. cancelButtonText: "取消",
  920. inputValue: row.opDatetime,
  921. inputPattern:
  922. /^[1-9][0-9][0-9][0-9]-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[0-1]) (0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9]):(0[0-9]|[1-5][0-9])$/,
  923. inputErrorMessage: "请输入正确的时间格式",
  924. })
  925. .then(({ value }) => {
  926. handleArrangementChange(row.recordId, "op_datetime", value).then(() => {
  927. row.opDatetime = value;
  928. });
  929. })
  930. .catch(() => {});
  931. };
  932. const filterPromptMessage = key => {
  933. switch (key) {
  934. case "remark":
  935. return { title: "请输入备注", column: "remark" };
  936. case "preoperativeVisit":
  937. return { title: "请输入术前访视", column: "preoperative_visit" };
  938. case "preoperativePreparation":
  939. return {
  940. title: "请输入术前准备完善情况",
  941. column: "preoperative_preparation",
  942. };
  943. }
  944. };
  945. const inputContent = (row, key) => {
  946. let message = filterPromptMessage(key);
  947. ElMessageBox.prompt(message.title, "提示", {
  948. confirmButtonText: "确定",
  949. cancelButtonText: "取消",
  950. inputValue: row[key],
  951. })
  952. .then(({ value }) => {
  953. let inputVal = value ? value : "";
  954. handleArrangementChange(row.recordId, message.column, inputVal).then(
  955. () => {
  956. row[key] = inputVal;
  957. }
  958. );
  959. })
  960. .catch(() => {});
  961. };
  962. const handleArrangementChange = (orderId, column, value) => {
  963. return new Promise((resolve, reject) => {
  964. updateArrangement(orderId, column, value)
  965. .then(() => {
  966. resolve();
  967. })
  968. .catch(() => {
  969. reject();
  970. });
  971. });
  972. };
  973. const doctorAdvise = row => {
  974. router.push({
  975. name: "yiZhuLuRu",
  976. params: {
  977. inpatientNo: row.inpatientNo,
  978. admissTimes: row.admissTimes,
  979. },
  980. });
  981. };
  982. const filterUrgentClinicFlag = flag => {
  983. switch (flag) {
  984. case "0":
  985. return "普通";
  986. case "1":
  987. return "急诊";
  988. case "2":
  989. return "择期";
  990. case "3":
  991. return "限期";
  992. default:
  993. return "";
  994. }
  995. };
  996. const filterSsbc = ssbc => {
  997. switch (ssbc) {
  998. case "1":
  999. return "正常";
  1000. case "2":
  1001. return "加班";
  1002. default:
  1003. return "";
  1004. }
  1005. };
  1006. const filterTwFlag = flag => {
  1007. switch (flag) {
  1008. case "0":
  1009. return "否";
  1010. case "1":
  1011. return "是";
  1012. default:
  1013. return "";
  1014. }
  1015. };
  1016. const filterOpScale = scale => {
  1017. switch (scale) {
  1018. case "4":
  1019. return "四级手术";
  1020. case "3":
  1021. return "三级手术";
  1022. case "2":
  1023. return "二级手术";
  1024. case "1":
  1025. return "一级手术";
  1026. default:
  1027. return "";
  1028. }
  1029. };
  1030. const nowdate = ref("");
  1031. const nowdatetime = ref("");
  1032. const clickPrint = () => {
  1033. nowdate.value = formatDate(new Date());
  1034. nowdatetime.value = formatDatetime(new Date());
  1035. let LODOP = getLodop();
  1036. let pagePrint =
  1037. "<body>" + document.getElementById("printArea").innerHTML + "</body>";
  1038. LODOP.PRINT_INIT("surgeryArrangement");
  1039. LODOP.SET_PRINT_PAGESIZE(2, "210mm", "297mm", "");
  1040. LODOP.SET_PRINT_MODE("RESELECT_PRINTER", true);
  1041. LODOP.SET_PRINT_MODE("PRINT_PAGE_PERCENT", "Full-Width");
  1042. LODOP.ADD_PRINT_HTM("2mm", "2mm", "100%", "100%", pagePrint);
  1043. LODOP.SET_SHOW_MODE("LANDSCAPE_DEFROTATED", 1);
  1044. LODOP.PREVIEW();
  1045. };
  1046. const statisticsRequest = reactive({
  1047. startDate: null,
  1048. endDate: null,
  1049. statisticsLabel: "BY_DEPARTMENT",
  1050. });
  1051. const statisticsDateRange = ref([]);
  1052. const surgeryStatisticsVisible = ref(false);
  1053. const surgeryStatistics = ref([]);
  1054. function showSurgeryStatistics() {
  1055. statisticsDateRange.value = [shortcuts[0].value[0], shortcuts[0].value[1]];
  1056. surgeryStatisticsVisible.value = true;
  1057. }
  1058. function executeQueryStatistics() {
  1059. let temp = getDateRangeFormatDate(statisticsDateRange.value);
  1060. statisticsRequest.startDate = temp.startTime;
  1061. statisticsRequest.endDate = temp.endTime;
  1062. queryStatistics(statisticsRequest).then(res => {
  1063. surgeryStatistics.value = res;
  1064. });
  1065. }
  1066. const currentStatistics = reactive({
  1067. key: "",
  1068. list: [],
  1069. });
  1070. function showStatisticsDetail(key) {
  1071. if (key === currentStatistics.key) {
  1072. currentStatistics.key = "";
  1073. currentStatistics.list = [];
  1074. return;
  1075. }
  1076. currentStatistics.key = key;
  1077. currentStatistics.list = surgeryStatistics.value.surgeryMap[key];
  1078. }
  1079. onMounted(() => {
  1080. initLodop();
  1081. nowdate.value = formatDate(new Date());
  1082. nowdatetime.value = formatDatetime(new Date());
  1083. getDicList().then(res => {
  1084. wardList.value = res.allWards;
  1085. allRooms.value = res.allRooms;
  1086. surStaffs.value = res.surStaffs;
  1087. aneStaffs.value = res.aneStaffs;
  1088. });
  1089. clickQuery();
  1090. });
  1091. </script>
  1092. <style lang="scss">
  1093. .surgery-arrangement {
  1094. .el-input__inner {
  1095. color: black !important;
  1096. }
  1097. .el-input--small {
  1098. .el-input__wrapper {
  1099. padding: 1px 4px;
  1100. background-color: transparent;
  1101. }
  1102. }
  1103. .el-table {
  1104. .el-input__suffix {
  1105. display: none;
  1106. }
  1107. .cell {
  1108. line-height: 16px;
  1109. padding-left: 2px;
  1110. padding-right: 2px;
  1111. }
  1112. .cell-border {
  1113. border: 1px solid #555;
  1114. color: black;
  1115. padding: 0;
  1116. }
  1117. .el-table-fixed-column--right {
  1118. .cell {
  1119. width: 100%;
  1120. background: white;
  1121. position: absolute;
  1122. top: 0;
  1123. bottom: 0;
  1124. display: flex;
  1125. align-items: center;
  1126. .el-button {
  1127. margin-left: 2px;
  1128. span {
  1129. margin-left: 0;
  1130. }
  1131. }
  1132. }
  1133. }
  1134. .charged-row {
  1135. background: rgba(142, 252, 142, 0.8);
  1136. }
  1137. .canceled-row * {
  1138. color: red;
  1139. }
  1140. }
  1141. .el-tag {
  1142. .el-tag__content {
  1143. color: white;
  1144. }
  1145. }
  1146. .show-detail-icon {
  1147. width: 24px;
  1148. height: 24px;
  1149. margin-top: 4px;
  1150. display: flex;
  1151. align-items: center;
  1152. justify-content: center;
  1153. border-radius: 4px;
  1154. background-color: white;
  1155. color: #737373;
  1156. &:hover {
  1157. cursor: pointer;
  1158. scale: 1.12;
  1159. background-color: #5b5d5d;
  1160. color: white;
  1161. }
  1162. }
  1163. }
  1164. </style>