AllCaseFrontSheet.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  1. <template>
  2. <el-container>
  3. <el-header height="36px" style="margin-top: 8px">
  4. <el-date-picker
  5. v-model="dateRange"
  6. type="daterange"
  7. range-separator="至"
  8. start-placeholder="开始日期"
  9. end-placeholder="结束日期"
  10. :shortcuts="shortcuts"
  11. style="width: 260px"
  12. ></el-date-picker>
  13. <el-select v-model="overviewParam.ward" style="width: 130px" placeholder="请选择科室" filterable clearable>
  14. <el-option v-for="item in userWards" :key="item.code" :value="item.code" :label="item.name"></el-option>
  15. </el-select>
  16. <el-select v-model="overviewParam.fileStatus" style="width: 90px">
  17. <el-option label="未签收" value="0"></el-option>
  18. <el-option label="已签收" value="1"></el-option>
  19. </el-select>
  20. <el-select v-model="overviewParam.lateFlag" style="width: 90px">
  21. <el-option label="全部" value="3"></el-option>
  22. <el-option label="迟交" value="1"></el-option>
  23. <el-option label="未迟交" value="0"></el-option>
  24. </el-select>
  25. <el-input v-model="overviewParam.bah" style="width: 110px" placeholder="住院号" clearable></el-input>
  26. <el-button type="primary" icon="el-icon-search" @click="searchPatient">检索</el-button>
  27. <el-button type="primary" icon="el-icon-check" @click="archiveBa">签收</el-button>
  28. <el-button type="primary" icon="el-icon-s-operation" @click="showAdvanceSearch = true">高级条件检索</el-button>
  29. <el-divider direction="vertical"></el-divider>
  30. <el-dropdown trigger="click" type="primary" @command="handleCommand">
  31. <el-button type="primary">功能菜单<i class="el-icon-arrow-down el-icon--right"></i> </el-button>
  32. <template #dropdown>
  33. <el-dropdown-menu>
  34. <el-dropdown-item icon="el-icon-printer" command="unSign">解除签收</el-dropdown-item>
  35. <el-dropdown-item icon="el-icon-printer" command="dismissCount" divided>出院患者统计</el-dropdown-item>
  36. <el-dropdown-item icon="el-icon-printer" command="exportLateData">导出迟交病案</el-dropdown-item>
  37. <el-dropdown-item icon="el-icon-printer" command="print1" divided>打印正面</el-dropdown-item>
  38. <el-dropdown-item icon="el-icon-printer" command="print2">打印反面</el-dropdown-item>
  39. <el-dropdown-item icon="el-icon-printer" command="confirmPrint">确认已打印</el-dropdown-item>
  40. </el-dropdown-menu>
  41. </template>
  42. </el-dropdown>
  43. </el-header>
  44. <el-container>
  45. <el-aside width="270px">
  46. <el-table :data="overview.slice((currentPage - 1) * 15, currentPage * 15)" :height="tableHeight" stripe highlight-current-row @row-click="fetchSheetInfo">
  47. <el-table-column label="姓名" width="70">
  48. <template #default="scope">
  49. <img class="sex-icon" :src="scope.row.sex === 1 ? maleIcon : femaleIcon" />
  50. {{ scope.row.name }}
  51. </template>
  52. </el-table-column>
  53. <el-table-column label="住院号-次数" width="80">
  54. <template #default="scope">
  55. <span style="font-weight: bold; color: black">{{ scope.row.bah }}</span
  56. >-{{ scope.row.times }}
  57. </template>
  58. </el-table-column>
  59. <el-table-column prop="doctorName" label="医生" width="60"></el-table-column>
  60. <el-table-column prop="signDate" label="签收日期"></el-table-column>
  61. </el-table>
  62. <el-pagination small :hide-on-single-page="false" :page-size="15" layout="prev, pager, next" @current-change="handleCurrentPageChange" :total="overview.length">
  63. </el-pagination>
  64. </el-aside>
  65. <el-main>
  66. <div style="display: flex">
  67. <div :style="mainInfo">
  68. <div id="headpage">
  69. <HeadPage :patient="sheet" :dics="dics" />
  70. </div>
  71. <div id="tailpage" style="margin-left: 70px">
  72. <TailPage :patient="sheet" :dics="dics" />
  73. </div>
  74. </div>
  75. <div class="page-wrapper" :style="messageArea">
  76. <div class="page-inner">
  77. <el-tag type="success" size="small">当前科室CD型病例比例:{{ cdPercentage }}</el-tag>
  78. <div style="border-bottom: 1px solid black; margin: 6px 0 6px 0"></div>
  79. <div v-show="forceVerifies.length > 0" style="padding: 8px 0 4px 0; font-weight: bold">以下条目为强制要求,请完善。</div>
  80. <div v-for="(item, index) in forceVerifies" :key="index" class="message-item" :style="messageColor(index)" @click="handleClickMessage(item.code, index)">
  81. {{ index + 1 }}、{{ item.name }}
  82. </div>
  83. <div v-show="adviceVerifies.length > 0" style="padding: 8px 0 4px 0; font-weight: bold">以下条目为建议执行,不做强制要求。</div>
  84. <div v-for="(item, index) in adviceVerifies" :key="index" style="padding: 6px; margin-bottom: 6px; border-radius: 4px; background: #eea7a752; color: #ff2b2b">
  85. {{ index + 1 }}、{{ item.name }}
  86. </div>
  87. </div>
  88. </div>
  89. </div>
  90. </el-main>
  91. </el-container>
  92. <el-dialog v-model="showAdvanceSearch" title="高级条件检索" width="380px">
  93. <div style="margin-top: 5px">
  94. <el-tag type="info">医生条件</el-tag>
  95. <div style="margin-top: 5px">
  96. &nbsp;&nbsp;医生姓名:<el-input v-model="advanceSearch.doctorName" style="width: 160px" clearable @click="showSearchData('advanceSearchDoctor')"></el-input>
  97. </div>
  98. </div>
  99. <div style="margin-top: 10px">
  100. <el-tag type="info">患者条件</el-tag>
  101. <div style="margin-top: 5px">
  102. &nbsp;&nbsp;诊断编码:<el-input v-model="advanceSearch.icdCode" style="width: 160px" clearable @click="showSearchData('advanceSearchDiag')"></el-input>
  103. </div>
  104. <div style="margin-top: 5px">
  105. &nbsp;&nbsp;手术编码:<el-input v-model="advanceSearch.surgeryCode" style="width: 160px" clearable @click="showSearchData('advanceSearchSurgery')"></el-input>
  106. </div>
  107. <div style="margin-top: 5px">
  108. &nbsp;&nbsp;患者性别:
  109. <el-select v-model="advanceSearch.sex" style="width: 100px" clearable>
  110. <el-option v-for="item in dics.getSexCode" :key="item.code" :value="item.code" :label="item.name"></el-option>
  111. </el-select>
  112. </div>
  113. </div>
  114. <div style="width: 100%; text-align: right; margin-top: 15px">
  115. <el-button icon="el-icon-search" type="primary" @click="doAdvanceSearch">开始检索</el-button>
  116. </div>
  117. </el-dialog>
  118. <el-dialog v-model="showSearch" title="数据搜索" width="700px">
  119. 检索依据:
  120. <el-select v-model="searchMethod" style="width: 100px">
  121. <el-option v-for="item in searchMethods" :key="item.code" :label="item.name" :value="item.code"></el-option>
  122. </el-select>
  123. &nbsp;&nbsp;&nbsp;&nbsp; 搜索内容:
  124. <el-input
  125. ref="searchInput"
  126. v-model="searchContent"
  127. prefix-icon="el-icon-search"
  128. placeholder="请输入搜索内容"
  129. style="width: 160px"
  130. clearable
  131. @input="executeSearch"
  132. ></el-input>
  133. <el-table :data="searchResults" height="400" stripe highlight-current-row @row-click="handleSelectSearch">
  134. <el-table-column prop="code" label="编码" width="200"></el-table-column>
  135. <el-table-column prop="name" label="名称" width="450"></el-table-column>
  136. </el-table>
  137. <div style="margin-top: 15px; width: 100%; text-align: right">
  138. <el-button type="primary" icon="el-icon-arrow-left" @click="lastPage" :disabled="currentSRPage === 1">上一页</el-button>
  139. <el-button type="primary" icon="el-icon-arrow-right" @click="nextPage" :disabled="currentSRPage > 1 && searchResults.length < 10">下一页</el-button>
  140. </div>
  141. </el-dialog>
  142. <el-dialog v-model="showDismissCount" title="出院患者统计" width="70%">
  143. <el-date-picker v-model="dismissCountMonth" type="month" style="width: 110px" placeholder="请选择" :clearable="false"></el-date-picker>
  144. <el-select v-model="dismissCountType" style="width: 120px" @change="dismissCountdata = []">
  145. <el-option :value="1" label="按科室计数"></el-option>
  146. <el-option :value="2" label="按明细计数"></el-option>
  147. <el-option :value="3" label="死亡患者计数"></el-option>
  148. </el-select>
  149. <el-divider direction="vertical"></el-divider>
  150. <el-button icon="el-icon-search" type="primary" @click="fetchDismissCount">获取统计数据</el-button>
  151. <el-button icon="el-icon-download" type="primary" @click="exportDismissCount">导出Excel</el-button>
  152. <div v-if="dismissCountType === 1">
  153. <el-table :data="dismissCountdata" stripe height="360">
  154. <el-table-column prop="deptName" label="科室"></el-table-column>
  155. <el-table-column prop="dismissCount" label="出院人数"></el-table-column>
  156. <el-table-column prop="signedCount" label="已签收"></el-table-column>
  157. <el-table-column prop="unsignCount" label="未签收"></el-table-column>
  158. </el-table>
  159. </div>
  160. <div v-else>
  161. <el-table :data="dismissCountdata.slice((currentDismissCountPage - 1) * 10, currentDismissCountPage * 10)" stripe height="360">
  162. <el-table-column prop="patNo" label="住院号"></el-table-column>
  163. <el-table-column prop="times" label="住院次数"></el-table-column>
  164. <el-table-column prop="name" label="姓名"></el-table-column>
  165. <el-table-column prop="gender" label="性别"></el-table-column>
  166. <el-table-column prop="age" label="年龄"></el-table-column>
  167. <el-table-column prop="admissDate" label="入院时间"></el-table-column>
  168. <el-table-column v-if="dismissCountType === 2" prop="disDate" label="出院时间"></el-table-column>
  169. <el-table-column v-if="dismissCountType === 3" prop="disDate" label="死亡时间"></el-table-column>
  170. <el-table-column prop="inHospDays" label="住院天数"></el-table-column>
  171. <el-table-column prop="totalCharge" label="住院费用"></el-table-column>
  172. <el-table-column prop="admissDept" label="入院科室"></el-table-column>
  173. <el-table-column prop="disDept" label="出院科室"></el-table-column>
  174. <el-table-column prop="zkWard" label="转科科室"></el-table-column>
  175. <el-table-column prop="disDiag" label="出院主诊断"></el-table-column>
  176. <el-table-column prop="blfx" label="病例分型"></el-table-column>
  177. <el-table-column prop="kzr" label="科主任"></el-table-column>
  178. <el-table-column prop="zzys" label="主治医师"></el-table-column>
  179. <el-table-column prop="zyys" label="住院医师"></el-table-column>
  180. <el-table-column prop="fdcrb" label="法定传染病"></el-table-column>
  181. </el-table>
  182. <el-pagination
  183. :hide-on-single-page="false"
  184. :page-size="10"
  185. layout="prev, pager, next, total"
  186. @current-change="handleCurrentDismissCountPageChange"
  187. :total="dismissCountdata.length"
  188. >
  189. </el-pagination>
  190. </div>
  191. </el-dialog>
  192. </el-container>
  193. </template>
  194. <script>
  195. import { yesOrNo, haveOrNot, searchMethods, autopsies } from './common'
  196. import { computed, onActivated, onMounted, reactive, ref, watchEffect } from 'vue'
  197. import store from '@/store'
  198. import { operations } from '@/data/index'
  199. import {
  200. basOutPatients,
  201. executeAdvanceSearch,
  202. executeConfirmPrint,
  203. executePrintVerify,
  204. executeSaveVerify,
  205. executeUnArchiveBa,
  206. getAllDictionary,
  207. getAllWards,
  208. getSheetInfo,
  209. sheetSearch,
  210. analyzeDismissCount,
  211. } from '@/api/case-front-sheet'
  212. import maleIcon from '@/assets/male-icon.png'
  213. import femaleIcon from '@/assets/female-icon.png'
  214. import { ElMessage, ElMessageBox } from 'element-plus'
  215. import { shortcuts } from '@/data/shortcuts'
  216. import { formatDate, getOneMonthOffset } from '@/utils/date'
  217. import { initLodop, getLodop } from '@/utils/c-lodop'
  218. import { formatMonth } from '@/utils/date'
  219. import HeadPage from '../../../components/inpatient/frontsheet-printpage/HeadPage.vue'
  220. import TailPage from '../../../components/inpatient/frontsheet-printpage/TailPage.vue'
  221. import { Export } from '../../../utils/ExportExcel'
  222. export default {
  223. components: {
  224. HeadPage,
  225. TailPage,
  226. },
  227. setup() {
  228. const cdStyle = computed(() => {
  229. return {
  230. position: 'absolute',
  231. top: '77px',
  232. left: '590px',
  233. }
  234. })
  235. const currentPage = ref(1)
  236. const handleCurrentPageChange = (val) => {
  237. currentPage.value = val
  238. }
  239. const userWards = ref([])
  240. const windowSize = store.state.app.windowSize
  241. const tableHeight = windowSize.h - 75
  242. const overview = ref([])
  243. const sheet = ref({
  244. disdiagList: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  245. surgeryList: [{}, {}, {}, {}, {}],
  246. })
  247. const mainInfo = {
  248. height: windowSize.h - 45 + 'px',
  249. padding: '0 20px',
  250. overflowY: 'scroll',
  251. }
  252. const dics = ref({})
  253. const overviewParam = reactive({
  254. ward: '',
  255. start: '',
  256. end: '',
  257. fileStatus: '0',
  258. lateFlag: '3',
  259. bah: '',
  260. })
  261. const cdPercentage = ref('')
  262. const isLateDataMode = ref(false)
  263. const searchPatient = () => {
  264. overviewParam.start = formatDate(dateRange.value[0])
  265. overviewParam.end = formatDate(dateRange.value[1])
  266. basOutPatients(overviewParam).then((res) => {
  267. isLateDataMode.value = overviewParam.lateFlag === '1'
  268. cdPercentage.value = res.cdPercentage
  269. overview.value = res.list
  270. if (res.list.length === 1) {
  271. fetchSheetInfo(res.list[0])
  272. }
  273. })
  274. }
  275. const dateRange = ref([])
  276. const fetchSheetInfo = (row) => {
  277. if (row.bah !== sheet.value.bah || row.times !== sheet.value.admissTimes) {
  278. forceVerifies.value = []
  279. adviceVerifies.value = []
  280. }
  281. getSheetInfo(row.bah, row.times, 2).then((res) => {
  282. sheet.value = res
  283. })
  284. }
  285. const showSearch = ref(false)
  286. const insertDiag = ref(false)
  287. watchEffect(() => {
  288. if (showSearch.value) {
  289. searchResults.value = []
  290. setTimeout(() => {
  291. searchInput.value.focus()
  292. }, 300)
  293. } else {
  294. insertDiag.value = false
  295. }
  296. })
  297. const searchInput = ref(null)
  298. const searchUrl = ref('')
  299. const searchTargetCode = ref('')
  300. const searchTargetName = ref('')
  301. const searchContent = ref('')
  302. const currentSRPage = ref(1)
  303. const lastPage = () => {
  304. currentSRPage.value -= 1
  305. fetchSearchData()
  306. }
  307. const nextPage = () => {
  308. currentSRPage.value += 1
  309. fetchSearchData()
  310. }
  311. const fetchSearchData = () => {
  312. const param = {
  313. method: searchMethod.value,
  314. target: searchUrl.value,
  315. content: searchContent.value,
  316. responceType: sheet.value.responceType,
  317. page: currentSRPage.value,
  318. ybType: sheet.value.ybType,
  319. treatType: sheet.value.treatType,
  320. }
  321. sheetSearch(param).then((res) => {
  322. searchResults.value = res
  323. })
  324. }
  325. const executeSearch = () => {
  326. if (searchContent.value.length < 2 && searchContent.value !== '-') return
  327. currentSRPage.value = 1
  328. if (searchContent.value === '-') {
  329. searchResults.value = [{ code: '-', name: '-' }]
  330. } else {
  331. fetchSearchData()
  332. }
  333. }
  334. const showDismissCount = ref(false)
  335. const dismissCountdata = ref([])
  336. const dismissCountMonth = ref(formatMonth(new Date()))
  337. const dismissCountType = ref(1)
  338. const fetchDismissCount = () => {
  339. dismissCountMonth.value = formatMonth(dismissCountMonth.value)
  340. analyzeDismissCount(dismissCountType.value, dismissCountMonth.value).then((res) => {
  341. dismissCountdata.value = res
  342. })
  343. }
  344. const exportDismissCount = () => {
  345. if (dismissCountdata.value.length === 0) {
  346. ElMessage({
  347. message: '没有可以导出的数据!',
  348. type: 'warning',
  349. duration: 2000,
  350. showClose: true,
  351. })
  352. return
  353. }
  354. let name = ''
  355. let title = {}
  356. if (dismissCountType.value === 1) {
  357. title = {
  358. deptName: '科室',
  359. dismissCount: '出院人数',
  360. signedCount: '已签收',
  361. unsignCount: '未签收',
  362. }
  363. name = '科室出院人数统计'
  364. } else {
  365. title = {
  366. patNo: '住院号',
  367. times: '住院次数',
  368. name: '姓名',
  369. gender: '性别',
  370. age: '年龄',
  371. admissDate: '入院时间',
  372. admissDept: '入院科室',
  373. zkWard: '转科科室',
  374. disDate: dismissCountType.value === 2 ? '出院时间' : '死亡时间',
  375. inHospDays: '住院天数',
  376. totalCharge: '住院费用',
  377. disDept: '出院科室',
  378. disDiag: '出院主诊断',
  379. blfx: '病例分型',
  380. kzr: '科主任',
  381. zzys: '主治医师',
  382. zyys: '住院医师',
  383. fdcrb: '法定传染病',
  384. }
  385. name = dismissCountType.value === 2 ? '出院明细统计' : '死亡患者统计'
  386. }
  387. const fileName = `【${dismissCountMonth.value}】${name}`
  388. Export(dismissCountdata.value, title, fileName)
  389. }
  390. const handleCommand = (val) => {
  391. switch (val) {
  392. case 'dismissCount':
  393. showDismissCount.value = true
  394. break
  395. case 'exportLateData':
  396. exportLateDataExel()
  397. break
  398. case 'print1':
  399. beforePrint(1)
  400. break
  401. case 'print2':
  402. beforePrint(2)
  403. break
  404. case 'confirmPrint':
  405. confirmCopyPrint()
  406. break
  407. case 'unSign':
  408. unArchiveBa()
  409. break
  410. }
  411. }
  412. const exportLateDataExel = () => {
  413. if (!isLateDataMode.value) {
  414. ElMessage({
  415. message: '请先查询迟交病案。',
  416. type: 'warning',
  417. duration: 2500,
  418. showClose: true,
  419. })
  420. return
  421. }
  422. if (overview.value.length === 0) {
  423. ElMessage({
  424. message: '没有可以导出的数据!',
  425. type: 'warning',
  426. duration: 2000,
  427. showClose: true,
  428. })
  429. return
  430. }
  431. const title = {
  432. name: '姓名',
  433. genderName: '性别',
  434. bah: '住院号',
  435. times: '住院次数',
  436. bedNo: '床位',
  437. admissDate: '入院时间',
  438. disDate: '出院时间',
  439. deptName: '出院科室',
  440. doctorName: '管床医生',
  441. lateDays: '迟交天数',
  442. signDate: '签收日期',
  443. }
  444. Export(overview.value, title, '迟交病案')
  445. }
  446. const searchMethod = ref('alpha')
  447. const searchResults = ref([])
  448. const showSearchData = (flag) => {
  449. if (flag === 'advanceSearchDoctor') {
  450. searchUrl.value = 'employee'
  451. searchTargetCode.value = 'advanceSearch'
  452. searchTargetName.value = 'doctor'
  453. } else if (flag === 'advanceSearchDiag') {
  454. searchUrl.value = 'normalDiag'
  455. searchTargetCode.value = 'advanceSearch'
  456. searchTargetName.value = 'icd'
  457. } else {
  458. searchUrl.value = 'surgery'
  459. searchTargetCode.value = 'advanceSearch'
  460. searchTargetName.value = 'surgery'
  461. }
  462. showSearch.value = true
  463. }
  464. const showAdvanceSearch = ref(false)
  465. const advanceSearch = reactive({
  466. doctorCode: '',
  467. doctorName: '',
  468. icdCode: '',
  469. icdName: '',
  470. surgeryCode: '',
  471. surgeryName: '',
  472. sex: null,
  473. })
  474. const doAdvanceSearch = () => {
  475. advanceSearch.start = formatDate(dateRange.value[0])
  476. advanceSearch.end = formatDate(dateRange.value[1])
  477. if (!advanceSearch.doctorName) {
  478. advanceSearch.doctorCode = ''
  479. }
  480. executeAdvanceSearch(advanceSearch).then((res) => {
  481. overview.value = res
  482. showAdvanceSearch.value = false
  483. })
  484. }
  485. const handleSelectSearch = (item) => {
  486. switch (searchTargetName.value) {
  487. case 'doctor':
  488. advanceSearch.doctorCode = item.code
  489. advanceSearch.doctorName = item.name
  490. break
  491. case 'icd':
  492. advanceSearch.icdCode = item.code
  493. advanceSearch.icdName = item.name
  494. break
  495. case 'surgery':
  496. advanceSearch.surgeryCode = item.code
  497. advanceSearch.surgeryName = item.name
  498. break
  499. }
  500. searchContent.value = ''
  501. showSearch.value = false
  502. }
  503. const nullPatient = () => {
  504. if (!sheet.value.bah) {
  505. ElMessage({
  506. message: '请先选择患者!',
  507. type: 'warning',
  508. duration: 2500,
  509. showClose: true,
  510. })
  511. return true
  512. }
  513. return false
  514. }
  515. const beforePrint = (flag) => {
  516. if (nullPatient()) return
  517. const param = {
  518. sheet: sheet.value,
  519. }
  520. executePrintVerify(param)
  521. .then(() => {
  522. execPrint(flag)
  523. })
  524. .catch((e) => {
  525. forceVerifies.value = e.data.force
  526. adviceVerifies.value = e.data.advice
  527. if (e.data.force.length === 0) {
  528. execPrint(flag)
  529. }
  530. })
  531. }
  532. const execPrint = (flag) => {
  533. LODOP = getLodop()
  534. const prntStyle = `<style>*{font-size:10pt} table,th,td {border: 1px solid black;border-collapse: collapse;} td,th {height: 24px;padding-left: 4px;}</style>`
  535. const prntContent = flag === 1 ? document.getElementById('headpage').innerHTML : document.getElementById('tailpage').innerHTML
  536. let pagePrint = prntStyle + '<body>' + prntContent + '</body>'
  537. LODOP.PRINT_INIT('casefrontsheet')
  538. LODOP.SET_PRINT_PAGESIZE(1, '210mm', '297mm', '')
  539. LODOP.SET_PRINT_MODE('FULL_WIDTH_FOR_OVERFLOW', true) // 整宽不变形
  540. LODOP.ADD_PRINT_HTM('2mm', '0.5mm', '209.5mm', '295mm', pagePrint)
  541. LODOP.SET_PRINT_STYLE('ItemType', 3)
  542. LODOP.PREVIEW()
  543. }
  544. const archiveBa = () => {
  545. if (nullPatient()) {
  546. return
  547. }
  548. const param = {
  549. opType: 2,
  550. sheet: sheet.value,
  551. }
  552. executeSaveVerify(param)
  553. .then((res) => {
  554. ElMessage({
  555. message: '操作成功。',
  556. type: 'success',
  557. duration: 2500,
  558. showClose: true,
  559. })
  560. })
  561. .catch((e) => {
  562. forceVerifies.value = e.data
  563. })
  564. }
  565. const unArchiveBa = () => {
  566. if (nullPatient()) {
  567. return
  568. }
  569. ElMessageBox.confirm('是否确认解除签收患者【' + sheet.value.name + '】的病案首页?', '提示', {
  570. type: 'warning',
  571. confirmButtonText: '解除签收',
  572. cancelButtonText: '取消',
  573. })
  574. .then(() => {
  575. const param = {
  576. opType: 3,
  577. sheet: sheet.value,
  578. }
  579. executeUnArchiveBa(param).then((res) => {
  580. ElMessage({
  581. message: res,
  582. type: 'success',
  583. duration: 2500,
  584. showClose: true,
  585. })
  586. })
  587. })
  588. .catch(() => {})
  589. }
  590. const confirmCopyPrint = () => {
  591. if (nullPatient()) {
  592. return
  593. }
  594. if (sheet.value.fileStatus === 2) {
  595. ElMessageBox.alert('此病案首页已确认过打印!', '提示', {
  596. showCancelButton: false,
  597. type: 'warning',
  598. }).then(() => {})
  599. return
  600. }
  601. ElMessageBox.confirm('是否确认患者【' + sheet.value.name + '】的病案首页已打印,此操作将不可逆转!', '提示', {
  602. confirmButtonText: '确定',
  603. cancelButtonText: '取消',
  604. type: 'warning',
  605. })
  606. .then(() => {
  607. executeConfirmPrint({ sheet: sheet.value }).then(() => {
  608. ElMessage({
  609. message: '操作成功',
  610. type: 'success',
  611. duration: 2500,
  612. showClose: true,
  613. })
  614. })
  615. })
  616. .catch(() => {})
  617. }
  618. const messageArea = {
  619. width: windowSize.w - 1380 + 'px',
  620. height: windowSize.h - 65 + 'px',
  621. padding: '0 16px',
  622. overflowY: 'scroll',
  623. }
  624. const forceVerifies = ref([])
  625. const adviceVerifies = ref([])
  626. const currentMessageIndex = ref(null)
  627. const messageColor = (id) => {
  628. return currentMessageIndex.value === id
  629. ? {
  630. background: '#ff2b2b',
  631. color: 'white',
  632. }
  633. : {
  634. background: '#eea7a752',
  635. color: '#ff2b2b',
  636. }
  637. }
  638. const handleClickMessage = (id, index) => {
  639. currentMessageIndex.value = index
  640. let ele = document.getElementById(id)
  641. let i = 0
  642. let timer = setInterval(() => {
  643. ele.style.background = i % 2 == 0 ? '#fd4343' : 'transparent'
  644. i++
  645. if (i > 5) {
  646. clearInterval(timer)
  647. }
  648. }, 500)
  649. }
  650. const currentDismissCountPage = ref(1)
  651. const handleCurrentDismissCountPageChange = (val) => {
  652. currentDismissCountPage.value = val
  653. }
  654. onActivated(() => {
  655. initLodop()
  656. })
  657. onMounted(() => {
  658. getAllDictionary().then((res) => {
  659. res.getOperations = operations
  660. res.getYesOrNo = yesOrNo
  661. res.getHaveOrNot = haveOrNot
  662. res.getAutopsies = autopsies
  663. dics.value = res
  664. getAllWards().then((res1) => {
  665. userWards.value = res1
  666. const t = getOneMonthOffset()
  667. dateRange.value[0] = t.start
  668. dateRange.value[1] = t.end
  669. })
  670. })
  671. })
  672. return {
  673. currentPage,
  674. handleCurrentPageChange,
  675. forceVerifies,
  676. adviceVerifies,
  677. messageColor,
  678. handleClickMessage,
  679. messageArea,
  680. cdStyle,
  681. maleIcon,
  682. femaleIcon,
  683. userWards,
  684. searchPatient,
  685. tableHeight,
  686. overview,
  687. mainInfo,
  688. sheet,
  689. dics,
  690. overviewParam,
  691. cdPercentage,
  692. searchMethods,
  693. fetchSheetInfo,
  694. showSearchData,
  695. showSearch,
  696. searchInput,
  697. searchContent,
  698. searchMethod,
  699. searchResults,
  700. currentSRPage,
  701. executeSearch,
  702. lastPage,
  703. nextPage,
  704. beforePrint,
  705. handleSelectSearch,
  706. dateRange,
  707. shortcuts,
  708. handleCommand,
  709. showAdvanceSearch,
  710. advanceSearch,
  711. doAdvanceSearch,
  712. showDismissCount,
  713. dismissCountdata,
  714. dismissCountMonth,
  715. dismissCountType,
  716. fetchDismissCount,
  717. exportDismissCount,
  718. archiveBa,
  719. currentDismissCountPage,
  720. handleCurrentDismissCountPageChange,
  721. }
  722. },
  723. }
  724. </script>
  725. <style scoped>
  726. :deep(.el-dialog__body) {
  727. padding-top: 0;
  728. }
  729. .keyboard {
  730. margin-left: 5px;
  731. padding: 0.2rem 0.4rem;
  732. font-size: 87.5%;
  733. color: #fff;
  734. background-color: #212529;
  735. border-radius: 0.2rem;
  736. }
  737. select,
  738. input {
  739. outline: none;
  740. border: none;
  741. height: 20px;
  742. line-height: 20px;
  743. border-radius: 0;
  744. background: transparent;
  745. border-bottom: 1px solid #333333;
  746. -webkit-appearance: none;
  747. -moz-appearance: none;
  748. appearance: none;
  749. }
  750. input[type='number'] {
  751. -moz-appearance: textfield;
  752. }
  753. select ::-ms-expand {
  754. display: none;
  755. }
  756. textarea {
  757. outline: none;
  758. border: none;
  759. background-color: transparent;
  760. }
  761. table th {
  762. border: 1px solid black;
  763. text-align: center;
  764. }
  765. table td {
  766. border: 1px solid black;
  767. }
  768. .page-inner {
  769. padding: 10px 0 0 0;
  770. border-radius: 12px;
  771. text-align: justify;
  772. }
  773. .message-item {
  774. padding: 6px;
  775. margin-bottom: 6px;
  776. border-radius: 4px;
  777. }
  778. .message-item:hover {
  779. cursor: pointer;
  780. }
  781. .page-wrapper {
  782. position: relative;
  783. margin: 0 auto;
  784. background: #fff;
  785. border-radius: 20px;
  786. text-align: justify;
  787. /* 高斯模糊,过滤器 */
  788. filter: drop-shadow(0px 0px 15px #bbb);
  789. }
  790. </style>