SurgeryArrangement.vue 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208
  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. import {xcMessage} from "@/utils/xiaochan-element-plus";
  728. const currentPage = ref(1);
  729. const pageSize = ref(30);
  730. const emergencyCount = ref(0);
  731. const wardList = ref([]);
  732. const allRooms = ref([]);
  733. const surStaffs = ref([]);
  734. const aneStaffs = ref([]);
  735. let statusList = reactive([
  736. { code: "0", name: "全部" },
  737. { code: "1", name: "申请" },
  738. { code: "2", name: "安排" },
  739. { code: "3", name: "确认" },
  740. { code: "d", name: "取消" },
  741. ]);
  742. const dateRange = ref([shortcuts[0].value[0], shortcuts[0].value[1]]);
  743. let queryParam = reactive({
  744. ward: "",
  745. patNo: "",
  746. status: "0",
  747. startTime: "",
  748. endTime: "",
  749. jzFlag: false,
  750. });
  751. const surgeryList = ref([]);
  752. const cptSrgLst = ref([])
  753. const displayRoom = ref('ALL')
  754. function handleChangeDisplay(val) {
  755. if (val === "ALL") {
  756. cptSrgLst.value = surgeryList.value;
  757. } else if (val === "NORMAL") {
  758. cptSrgLst.value = surgeryList.value.filter(item => {
  759. return !item.roomCode || (parseInt(item.roomCode) < 15)
  760. })
  761. } else {
  762. cptSrgLst.value = surgeryList.value.filter(item => {
  763. return item.roomCode && (parseInt(item.roomCode) >= 15)
  764. })
  765. }
  766. calEmergencyCount(cptSrgLst.value)
  767. }
  768. function calEmergencyCount(list) {
  769. emergencyCount.value = 0
  770. list.forEach(item => {
  771. if (stringNotBlank(item.urgentClinicFlag)) {
  772. if (item.urgentClinicFlag === "1") {
  773. emergencyCount.value++;
  774. }
  775. }
  776. });
  777. }
  778. let surgeryListForPrint = computed(() => {
  779. return surgeryList.value.filter(item => {
  780. return item.status !== "d";
  781. });
  782. });
  783. const clickQuery = () => {
  784. if (listIsBlank(dateRange.value)) {
  785. ElMessage.error("请先输入日期");
  786. return;
  787. }
  788. let dateS = getDateRangeFormatDate(dateRange.value);
  789. queryParam.startTime = dateS.startTime;
  790. queryParam.endTime = dateS.endTime;
  791. selectSurgeryArrangements(queryParam).then(res => {
  792. surgeryList.value = res;
  793. handleChangeDisplay(displayRoom.value);
  794. }).catch(() => {
  795. surgeryList.value = []
  796. });
  797. };
  798. const handleCurrentChange = val => {
  799. currentPage.value = val;
  800. };
  801. const differChargedRows = ({ row }) => {
  802. if (row.chargeSum && row.chargeSum > 0) {
  803. return "charged-row";
  804. }
  805. if (row.status === "d") {
  806. return "canceled-row";
  807. }
  808. };
  809. const surgeryExecuted = row => {
  810. if (row.status === "3") {
  811. ElMessage({
  812. message: "已完成的手术不可取消。",
  813. type: "error",
  814. duration: 2500,
  815. showClose: true,
  816. });
  817. return true;
  818. }
  819. return false;
  820. };
  821. const arrangementExecuted = row => {
  822. if (row.arrangementExecuted === 1) {
  823. ElMessage({
  824. message: "已接的手术不可取消。",
  825. type: "error",
  826. duration: 2500,
  827. showClose: true,
  828. });
  829. return true;
  830. }
  831. return false;
  832. };
  833. const changeSurgeryStatus = (row, status) => {
  834. if (!surgeryExecuted(row) && !arrangementExecuted(row)) {
  835. currentRow.value = row;
  836. updateSurgeryStatus(row.recordId, status).then(() => {
  837. currentRow.value.status = status;
  838. });
  839. }
  840. };
  841. const changeArrangementExecuted = row => {
  842. currentRow.value = row;
  843. const targetVal = row.arrangementExecuted === 0 ? 1 : 0;
  844. updateArrangement(row.recordId, "arrangement_executed", targetVal)
  845. .then(() => {
  846. currentRow.value.arrangementExecuted = targetVal;
  847. if (targetVal === 1) {
  848. ElMessageBox.confirm("是否向手术医生发送通知?",'提示', {
  849. type: "warning",
  850. }).then(() => {
  851. notifyDoctor(row).then(res2 => {
  852. xcMessage.success(res2)
  853. });
  854. });
  855. }
  856. }
  857. );
  858. };
  859. const showSearch = ref(false);
  860. const titleOfSearch = ref("");
  861. const currentRow = ref({});
  862. const currentKey = ref("");
  863. const beforeSearch = (row, col) => {
  864. currentRow.value = row;
  865. currentKey.value = col;
  866. titleOfSearch.value = "手术医生";
  867. showSearch.value = true;
  868. };
  869. const handleClickSearchResult = item => {
  870. showSearch.value = false;
  871. handleArrangementChange(
  872. currentRow.value.recordId,
  873. currentKey.value,
  874. item.code
  875. ).then(() => {
  876. switch (currentKey.value) {
  877. case 'doctor_zd':
  878. currentRow.value.doctorZd = item.code;
  879. currentRow.value.doctorZdName = item.name;
  880. break;
  881. case 'doctor_1':
  882. currentRow.value.doctor1 = item.code;
  883. currentRow.value.doctor1Name = item.name;
  884. break;
  885. case 'doctor_2':
  886. currentRow.value.doctor2 = item.code;
  887. currentRow.value.doctor2Name = item.name;
  888. break;
  889. }
  890. });
  891. };
  892. const oldSelection = reactive({
  893. column: "",
  894. value: "",
  895. });
  896. const handleSelectionFocus = (row, column) => {
  897. currentRow.value = row;
  898. oldSelection.column = column;
  899. oldSelection.value = row[column];
  900. };
  901. const handleSelectionChange = (orderId, column, value) => {
  902. handleArrangementChange(orderId, column, value)
  903. .then(() => {})
  904. .catch(() => {
  905. currentRow.value[oldSelection.column] = oldSelection.value;
  906. });
  907. };
  908. const beforeChargeOpTime = row => {
  909. ElMessageBox.prompt("请输入手术时间:", "提示", {
  910. confirmButtonText: "确定",
  911. cancelButtonText: "取消",
  912. inputValue: row.opDatetime,
  913. inputPattern:
  914. /^[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])$/,
  915. inputErrorMessage: "请输入正确的时间格式",
  916. })
  917. .then(({ value }) => {
  918. handleArrangementChange(row.recordId, "op_datetime", value).then(() => {
  919. row.opDatetime = value;
  920. });
  921. })
  922. .catch(() => {});
  923. };
  924. const filterPromptMessage = key => {
  925. switch (key) {
  926. case "remark":
  927. return { title: "请输入备注", column: "remark" };
  928. case "preoperativeVisit":
  929. return { title: "请输入术前访视", column: "preoperative_visit" };
  930. case "preoperativePreparation":
  931. return {
  932. title: "请输入术前准备完善情况",
  933. column: "preoperative_preparation",
  934. };
  935. }
  936. };
  937. const inputContent = (row, key) => {
  938. let message = filterPromptMessage(key);
  939. ElMessageBox.prompt(message.title, "提示", {
  940. confirmButtonText: "确定",
  941. cancelButtonText: "取消",
  942. inputValue: row[key],
  943. })
  944. .then(({ value }) => {
  945. let inputVal = value ? value : "";
  946. handleArrangementChange(row.recordId, message.column, inputVal).then(
  947. () => {
  948. row[key] = inputVal;
  949. }
  950. );
  951. })
  952. .catch(() => {});
  953. };
  954. const handleArrangementChange = (orderId, column, value) => {
  955. return new Promise((resolve, reject) => {
  956. updateArrangement(orderId, column, value)
  957. .then(() => {
  958. resolve();
  959. })
  960. .catch(() => {
  961. reject();
  962. });
  963. });
  964. };
  965. const doctorAdvise = row => {
  966. router.push({
  967. name: "yiZhuLuRu",
  968. params: {
  969. inpatientNo: row.inpatientNo,
  970. admissTimes: row.admissTimes,
  971. },
  972. });
  973. };
  974. const filterUrgentClinicFlag = flag => {
  975. switch (flag) {
  976. case "0":
  977. return "普通";
  978. case "1":
  979. return "急诊";
  980. case "2":
  981. return "择期";
  982. case "3":
  983. return "限期";
  984. default:
  985. return "";
  986. }
  987. };
  988. const filterSsbc = ssbc => {
  989. switch (ssbc) {
  990. case "1":
  991. return "正常";
  992. case "2":
  993. return "加班";
  994. default:
  995. return "";
  996. }
  997. };
  998. const filterTwFlag = flag => {
  999. switch (flag) {
  1000. case "0":
  1001. return "否";
  1002. case "1":
  1003. return "是";
  1004. default:
  1005. return "";
  1006. }
  1007. };
  1008. const filterOpScale = scale => {
  1009. switch (scale) {
  1010. case "4":
  1011. return "四级手术";
  1012. case "3":
  1013. return "三级手术";
  1014. case "2":
  1015. return "二级手术";
  1016. case "1":
  1017. return "一级手术";
  1018. default:
  1019. return "";
  1020. }
  1021. };
  1022. const nowdate = ref("");
  1023. const nowdatetime = ref("");
  1024. const clickPrint = () => {
  1025. nowdate.value = formatDate(new Date());
  1026. nowdatetime.value = formatDatetime(new Date());
  1027. let LODOP = getLodop();
  1028. let pagePrint =
  1029. "<body>" + document.getElementById("printArea").innerHTML + "</body>";
  1030. LODOP.PRINT_INIT("surgeryArrangement");
  1031. LODOP.SET_PRINT_PAGESIZE(2, "210mm", "297mm", "");
  1032. LODOP.SET_PRINT_MODE("RESELECT_PRINTER", true);
  1033. LODOP.SET_PRINT_MODE("PRINT_PAGE_PERCENT", "Full-Width");
  1034. LODOP.ADD_PRINT_HTM("2mm", "2mm", "100%", "100%", pagePrint);
  1035. LODOP.SET_SHOW_MODE("LANDSCAPE_DEFROTATED", 1);
  1036. LODOP.PREVIEW();
  1037. };
  1038. const statisticsRequest = reactive({
  1039. startDate: null,
  1040. endDate: null,
  1041. statisticsLabel: "BY_DEPARTMENT",
  1042. });
  1043. const statisticsDateRange = ref([]);
  1044. const surgeryStatisticsVisible = ref(false);
  1045. const surgeryStatistics = ref([]);
  1046. function showSurgeryStatistics() {
  1047. statisticsDateRange.value = [shortcuts[0].value[0], shortcuts[0].value[1]];
  1048. surgeryStatisticsVisible.value = true;
  1049. }
  1050. function executeQueryStatistics() {
  1051. let temp = getDateRangeFormatDate(statisticsDateRange.value);
  1052. statisticsRequest.startDate = temp.startTime;
  1053. statisticsRequest.endDate = temp.endTime;
  1054. queryStatistics(statisticsRequest).then(res => {
  1055. surgeryStatistics.value = res;
  1056. });
  1057. }
  1058. const currentStatistics = reactive({
  1059. key: "",
  1060. list: [],
  1061. });
  1062. function showStatisticsDetail(key) {
  1063. if (key === currentStatistics.key) {
  1064. currentStatistics.key = "";
  1065. currentStatistics.list = [];
  1066. return;
  1067. }
  1068. currentStatistics.key = key;
  1069. currentStatistics.list = surgeryStatistics.value.surgeryMap[key];
  1070. }
  1071. onMounted(() => {
  1072. initLodop();
  1073. nowdate.value = formatDate(new Date());
  1074. nowdatetime.value = formatDatetime(new Date());
  1075. getDicList().then(res => {
  1076. wardList.value = res.allWards;
  1077. allRooms.value = res.allRooms;
  1078. surStaffs.value = res.surStaffs;
  1079. aneStaffs.value = res.aneStaffs;
  1080. });
  1081. clickQuery();
  1082. });
  1083. </script>
  1084. <style lang="scss">
  1085. .surgery-arrangement {
  1086. .el-input__inner {
  1087. color: black !important;
  1088. }
  1089. .el-input--small {
  1090. .el-input__wrapper {
  1091. padding: 1px 4px;
  1092. background-color: transparent;
  1093. }
  1094. }
  1095. .el-table {
  1096. .el-input__suffix {
  1097. display: none;
  1098. }
  1099. .cell {
  1100. line-height: 16px;
  1101. padding-left: 2px;
  1102. padding-right: 2px;
  1103. }
  1104. .cell-border {
  1105. border: 1px solid #555;
  1106. color: black;
  1107. padding: 0;
  1108. }
  1109. .el-table-fixed-column--right {
  1110. .cell {
  1111. width: 100%;
  1112. background: white;
  1113. position: absolute;
  1114. top: 0;
  1115. bottom: 0;
  1116. display: flex;
  1117. align-items: center;
  1118. .el-button {
  1119. margin-left: 2px;
  1120. span {
  1121. margin-left: 0;
  1122. }
  1123. }
  1124. }
  1125. }
  1126. .charged-row {
  1127. background: rgba(142, 252, 142, 0.8);
  1128. }
  1129. .canceled-row * {
  1130. color: red;
  1131. }
  1132. }
  1133. .el-tag {
  1134. .el-tag__content {
  1135. color: white;
  1136. }
  1137. }
  1138. .show-detail-icon {
  1139. width: 24px;
  1140. height: 24px;
  1141. margin-top: 4px;
  1142. display: flex;
  1143. align-items: center;
  1144. justify-content: center;
  1145. border-radius: 4px;
  1146. background-color: white;
  1147. color: #737373;
  1148. &:hover {
  1149. cursor: pointer;
  1150. scale: 1.12;
  1151. background-color: #5b5d5d;
  1152. color: white;
  1153. }
  1154. }
  1155. }
  1156. </style>