You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1003 lines
36 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 months ago
1 year ago
2 years ago
2 years ago
2 years ago
1 year ago
2 months ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 month ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
4 weeks ago
2 years ago
2 years ago
4 weeks ago
2 years ago
4 weeks ago
2 years ago
2 years ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
1 year ago
1 month ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 month ago
1 year ago
1 month ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div style="display: flex;">
  3. <div>
  4. <div v-show="checkPagePriv(pagePriv.privs, '采图')">
  5. <el-button type="primary" class="btnClass" @click="btnGetPic" :disabled="doctorBtnDisabled('btnGetPic')"
  6. size="small">采图</el-button>
  7. </div>
  8. <div v-show="checkPagePriv(pagePriv.privs, '导图')">
  9. <el-button type="primary" class="btnClass" @click="btnExpPic" :disabled="doctorBtnDisabled('btnExpPic')"
  10. size="small">导图</el-button>
  11. </div>
  12. <div v-show="checkPagePriv(pagePriv.privs, '保存')">
  13. <el-button type="primary" class="btnClass" @click="btnSavePic" :disabled="doctorBtnDisabled('btnSavePic')"
  14. size="small">保存</el-button>
  15. </div>
  16. <el-dropdown v-show="checkPagePriv(pagePriv.privs, '导图')" :disabled="doctorBtnDisabled('btnExpPic')">
  17. <span class="el-dropdown-link" style="color: #222531; font-weight: 700">
  18. <el-button type="primary" class="btnClass" :disabled="doctorBtnDisabled('btnExpPic')">更多</el-button>
  19. </span>
  20. <el-dropdown-menu slot="dropdown">
  21. <el-dropdown-item v-show="checkPagePriv(pagePriv.privs, 'Dcm')" @click.native="btnBrowseDcm"
  22. :disabled="doctorBtnDisabled('btnBrowseDcm')">Dcm</el-dropdown-item>
  23. <el-dropdown-item v-show="checkPagePriv(pagePriv.privs, '裁图')" @click.native="btnCutPic"
  24. :disabled="doctorBtnDisabled('btnCutPic')">裁剪图片</el-dropdown-item>
  25. <el-dropdown-item v-show="checkPagePriv(pagePriv.privs, '清理pacs结果')" @click.native="btnClean"
  26. :disabled="doctorBtnDisabled('btnClean')">清理pacs结果</el-dropdown-item>
  27. </el-dropdown-menu>
  28. </el-dropdown>
  29. </div>
  30. <!-- -->
  31. <div :style="`overflow-x: scroll;width:${Math.floor((window.pageWidth - 200 - 110 - 15 - 4))}px;`">
  32. <div style="display: flex;">
  33. <div class="demo-image__preview" v-for="(item, index) in checkPictures" :key="item.id"
  34. style="display: inline-block; padding: 0 0 0 2px">
  35. <div style="
  36. position: relative;
  37. font-size: 24px;
  38. margin: -6px 0 0 55px;
  39. height: 30px;
  40. z-index: 2;
  41. ">
  42. <el-tooltip content="删除该图" placement="bottom" effect="light">
  43. <i class="el-icon-close" @click="btnDelImage(index)" v-show="!doctorBtnDisabled('btnDelImage')"
  44. style="color: red; cursor: pointer"></i>
  45. </el-tooltip>
  46. </div>
  47. <div style="margin-top: -25px">
  48. <el-image style="width: 80px; height: 80px; border-radius: 5px" :src="imageFilePlus(item.pictureFilename)"
  49. :preview-src-list="previewSrcList(checkPictures, item)">
  50. </el-image>
  51. </div>
  52. <div style="display: flex">
  53. <div style="margin: -6px 2px 0 1px">
  54. <el-tooltip content="是否打印" placement="bottom" effect="light">
  55. <el-checkbox v-model="item.isPrintTrans" @change="btnSavePic"
  56. :disabled="doctorBtnDisabled('btnSavePic')"></el-checkbox>
  57. </el-tooltip>
  58. </div>
  59. <!--
  60. <div style="font-size: 12px; margin: -2px 0 0 1px">打印</div>
  61. -->
  62. <div style="font-size: 15px; margin: -5px 2px 0 2px">
  63. <el-tooltip content="保存后,图片将按序号从小到大排序" placement="bottom" effect="light">
  64. <input placeholder="排序" v-model="item.displayOrder" @onkeyup="validateInteger(e, index)"
  65. style="width: 30px" :disabled="doctorBtnDisabled('btnSavePic')" />
  66. </el-tooltip>
  67. </div>
  68. <div style="margin: -6px 0 0 2px">
  69. <el-tooltip content="是否报告图片" placement="bottom" effect="light">
  70. <el-checkbox v-model="item.pictureFileType" @change="btnSavePic" true-label="1" false-label="0"
  71. :disabled="doctorBtnDisabled('btnSavePic')"></el-checkbox>
  72. </el-tooltip>
  73. </div>
  74. </div>
  75. </div>
  76. </div>
  77. </div>
  78. <el-dialog title="图片上传" :visible.sync="dialogCheckPictureUpload" :close-on-click-modal="false" width="800px"
  79. @close="getCheckPictures(doctorCheck.RegisterCheckId)">
  80. <CheckPictureUpload :registerCheckId="doctorCheck.RegisterCheckId" :uploadSeq="uploadSeq"
  81. :closePicUpload="closePicUpload" />
  82. </el-dialog>
  83. <el-dialog title="Dcm查看" :visible.sync="dialogDcm" :close-on-click-modal="false" fullscreen @close="iframeSrc = ''">
  84. <div style="display: flex;">
  85. <div>
  86. <iframe :src="iframeSrc" :height="window.pageHeight - 85" :width="window.pageWidth - 260"></iframe>
  87. </div>
  88. <div style="width: 240px;margin-left: 2px;">
  89. <div style="margin-top: 5px;">
  90. <span style="color: #232748;">人员信息</span>
  91. <div style="display: flex;">
  92. <span style="width: 80px;margin: 7px 0;">检查条码</span>
  93. <el-input ref="checkRequestNo" placeholder="检查条码" v-model="checkRequestNo" size="small" clearable
  94. @keyup.native.enter="onQueryByPacsNo(checkRequestNo)" @focus="onFocus" disabled />
  95. </div>
  96. <div style="display: flex;">
  97. <span style="width: 80px;margin: 7px 0;">姓名</span>
  98. <el-input v-model="dataTransOpts.tableS.patient_register.patientName" size="small" disabled />
  99. </div>
  100. <div style="display: flex;">
  101. <span style="width: 80px;margin: 7px 0;">性别</span>
  102. <el-input v-model="dataTransOpts.tableS.patient_register.sexName" size="small" disabled />
  103. </div>
  104. <div style="display: flex;">
  105. <span style="width: 80px;margin: 7px 0;">年龄</span>
  106. <el-input v-model="dataTransOpts.tableS.patient_register.age" size="small" disabled />
  107. </div>
  108. </div>
  109. <div style="margin-top: 5px;">
  110. <div>
  111. <span>检查结果</span>
  112. <el-radio-group v-model="tabPosition">
  113. <el-radio :label="'top'">横排</el-radio>
  114. <el-radio :label="'left'">纵排</el-radio>
  115. </el-radio-group>
  116. </div>
  117. <el-tabs :tab-position="tabPosition" v-model="tabChoosed">
  118. <el-tab-pane v-for="(item, seq) in doctorCheck.checkItemList" :label="dispLabel(item.itemName)"
  119. :name="seq + ''" :key="seq">
  120. <el-input style="width: 100%;" type="textarea" v-model="item.result" placeholder="请输入检查结果"
  121. :disabled="doctorBtnDisabled('save')"
  122. :autosize="{ minRows: Math.floor((window.pageHeight - 550) / 24), maxRows: 18 }" />
  123. <div style="display: flex;justify-content: space-between;">
  124. <div></div>
  125. <div>
  126. <el-tooltip :content="`给 ${item.itemName} 项目,赋默认结果`" placement="top">
  127. <i class="el-icon-edit" @click="btnDefResult(seq)"
  128. style="font-size: 18px;color: blue;cursor:pointer;margin-right: 10px;"></i>
  129. </el-tooltip>
  130. <el-tooltip :content="`清除 ${item.itemName} 项目的检查结果`" placement="top">
  131. <i class="el-icon-delete" @click="btnClear(seq)"
  132. style="font-size: 18px;color: red;cursor:pointer;margin-right: 10px;"></i>
  133. </el-tooltip>
  134. </div>
  135. </div>
  136. </el-tab-pane>
  137. </el-tabs>
  138. </div>
  139. <div style="margin-top: 5px;">
  140. <span style="color: #232748;">检查结论</span>
  141. <el-table row-key="id" :data="doctorCheck.checkSummaryList" size="samll" height="186" width="100%" border>
  142. <el-table-column width="30" align="center">
  143. <template slot-scope="scope">
  144. <el-tag class="moveSummary" style="height:25px;padding:0 2px;cursor: move;background-color: #EEEEEE;">
  145. <div style="width: 16px;">{{ scope.$index + 1 }}</div>
  146. </el-tag>
  147. </template>
  148. </el-table-column>
  149. <el-table-column prop="summary" label="小结">
  150. <template slot="header">
  151. <div style="display: flex;justify-content:space-between;">
  152. <div>小结</div>
  153. <div></div>
  154. </div>
  155. </template>
  156. <template slot-scope="scope">
  157. <div style="display: flex;">
  158. <el-input type="textarea" v-model="scope.row.summary" :autosize="{ minRows: 1, maxRows: 100 }"
  159. placeholder="请输入小结">
  160. </el-input>
  161. <el-button type="danger" style="min-width:23px;padding:2px;" icon="el-icon-delete"
  162. @click="delSum(scope.$index)" size="small"></el-button>
  163. </div>
  164. </template>
  165. </el-table-column>
  166. </el-table>
  167. </div>
  168. <div style="display: flex;justify-content: space-between;margin-top: 10px;">
  169. <div></div>
  170. <div>
  171. <!--
  172. <el-button type="primary" @click="btnTest" class="commonbutton">测试</el-button>
  173. -->
  174. <el-button type="primary" @click="btnChooseBigtext" :disabled="doctorBtnDisabled('save')"
  175. class="commonbutton">选择描述</el-button>
  176. <el-button type="primary" @click="btnOkBigtext" :disabled="doctorBtnDisabled('save')"
  177. class="commonbutton">保存结果</el-button>
  178. </div>
  179. </div>
  180. </div>
  181. </div>
  182. </el-dialog>
  183. <!--Pacs结果录入模版-->
  184. <el-dialog :title="'Pacs结果录入模版 -- ' + doctorCheck.asbitemName" :visible.sync="dialogWin.PacsTemplate" width="880px"
  185. :close-on-click-modal="false">
  186. <PacsTemplate :refParams="pacsParams" :refFuncOther="handlePacsResult" />
  187. </el-dialog>
  188. <el-dialog title="裁图" :visible.sync="dialogWinCutPic" width="1300px" :close-on-click-modal="false">
  189. <PacsCutPic />
  190. </el-dialog>
  191. </div>
  192. </template>
  193. <script>
  194. import moment from "moment";
  195. import { mapState } from "vuex";
  196. import { Loading } from "element-ui";
  197. import { getapi, postapi, putapi, deletapi } from "@/api/api";
  198. import { getPagePriv, checkPagePriv, deepCopy, arrayExistObj } from "../../utlis/proFunc";
  199. import { hadoopGet, hadoopPost, hadoopPut, hadoopDel } from "../../api/hadoopApi"
  200. import CheckPictureUpload from "./CheckPictureUpload.vue";
  201. import PacsTemplate from "./PacsTemplate.vue";
  202. import PacsCutPic from "./PacsCutPic.vue";
  203. export default {
  204. components: {
  205. CheckPictureUpload, PacsTemplate, PacsCutPic
  206. },
  207. props: ["doctorBtnDisabled", "save"],
  208. data() {
  209. return {
  210. sysConfig: {}, //
  211. pagePriv: {
  212. routeUrlorPageName: 'doctorCheck', //当前页面归属路由或归属页面权限名称
  213. privs: [] // 页面权限
  214. },
  215. checkRequestNo: '',
  216. dialogDcm: false,
  217. iframeSrc: '',
  218. pacsParams: {
  219. from: 'dcm',
  220. refresh: -1,
  221. row: {},
  222. index: 0,
  223. result: '',
  224. summary: ''
  225. },
  226. tabPosition: 'top',
  227. tabChoosed: "0",
  228. checkPictures: [
  229. // {
  230. // id: "1",
  231. // registerCheckId: "registerCheckId",
  232. // isPrint: "Y",
  233. // isPrintTrans: true,
  234. // pictureFilename:
  235. // "https://fuss10.elemecdn.com/8/27/f01c15bb73e1ef3793e64e6b7bbccjpeg.jpeg",
  236. // },
  237. // {
  238. // id: "2",
  239. // registerCheckId: "registerCheckId",
  240. // isPrint: "Y",
  241. // isPrintTrans: true,
  242. // pictureFilename:
  243. // "https://fuss10.elemecdn.com/1/8e/aeffeb4de74e2fde4bd74fc7b4486jpeg.jpeg",
  244. // },
  245. ],
  246. //图片上传
  247. dialogCheckPictureUpload: false,
  248. uploadSeq: 0, //第几次点图片上传,每点一次清空前次所选图片
  249. // 裁图
  250. dialogWinCutPic: false,
  251. cutPicParam: {},
  252. pictureFileType: '1'
  253. };
  254. },
  255. created() {
  256. //获取用户当前页面的权限
  257. let userPriv = window.sessionStorage.getItem('userPriv')
  258. if (userPriv) this.pagePriv.privs = deepCopy(getPagePriv(this.pagePriv.routeUrlorPageName))
  259. this.sysConfig = JSON.parse(window.sessionStorage.getItem('sysConfig'))
  260. // console.log('this.sysConfig checkPictures', this.sysConfig)
  261. },
  262. //挂载完成
  263. mounted() {
  264. // 监听来自 Electron 的调用
  265. if (this.$peisAPI) {
  266. //采集图像
  267. this.$peisAPI.onEventFromPictureHotKeyMain((data) => {
  268. this.acceptHotKeyData('add', data)
  269. });
  270. //采集图像设为打印
  271. this.$peisAPI.onEventFromPictureAndPrintHotKeyMain((data) => {
  272. this.acceptHotKeyData('addPrint', data)
  273. });
  274. //设为打印
  275. this.$peisAPI.onEventFromPicturePrintHotKeyMain(() => {
  276. this.acceptHotKeyData('print')
  277. });
  278. //取消打印
  279. this.$peisAPI.onEventFromPictureCancelPrintHotKeyMain(() => {
  280. this.acceptHotKeyData('unPrint')
  281. });
  282. //删除图像
  283. this.$peisAPI.onEventFromPictureDeleteHotKeyMain(() => {
  284. this.acceptHotKeyData('delete')
  285. });
  286. }
  287. if (this.dataTransOpts.tableS.register_check.id) {
  288. this.getCheckPictures(this.dataTransOpts.tableS.register_check.id);
  289. }
  290. },
  291. computed: {
  292. ...mapState([
  293. "window",
  294. "dict",
  295. "dialogWin",
  296. "dataTransOpts",
  297. "doctorCheck",
  298. "patientRegister",
  299. "customerOrg"
  300. ]),
  301. lmoment(date, forMat) {
  302. return moment(new Date(date)).format(forMat);
  303. },
  304. },
  305. methods: {
  306. checkPagePriv,
  307. // 根据checkId获取图片列表信息
  308. getCheckPictures(registerCheckId) {
  309. this.checkPictures = [];
  310. if (!registerCheckId) {
  311. return;
  312. }
  313. // {
  314. // "registerCheckId": "3a0f6a3c-88a5-d5f7-d59b-ef3b3807490b",
  315. // "pictureFilename": "https://fuss10.elemecdn.com/8/27/f01c15bb73e1ef3793e64e6b7bbccjpeg.jpeg",
  316. // "isPrint": "N",
  317. // "displayOrder": 1,
  318. // "creatorName": "admin",
  319. // "lastModifierName": "admin",
  320. // "lastModificationTime": "2023-12-15T15:24:08",
  321. // "lastModifierId": "3a0c4180-107c-0c89-b25b-0bd34666dcec",
  322. // "creationTime": "2023-12-15T15:24:06",
  323. // "creatorId": "3a0c4180-107c-0c89-b25b-0bd34666dcec",
  324. // "id": "3a0f6a3c-88a5-d5f7-d59b-ef3b38074901"
  325. // }
  326. hadoopGet('pacsApi', `/api/app/registercheckpicture/getregistercheckpictureinregistercheckid?RegisterCheckId=${registerCheckId}`)
  327. // getapi(`/api/app/registercheckpicture/getregistercheckpictureinregistercheckid?RegisterCheckId=${registerCheckId}`)
  328. .then((res) => {
  329. if (res.code > -1) {
  330. this.checkPictures = res.data
  331. this.checkPictures.forEach(e => {
  332. e.isPrintTrans = e.isPrint == "Y" ? true : false
  333. });
  334. }
  335. });
  336. },
  337. // 生成 图片预览列表
  338. previewSrcList(oriList, curImag) {
  339. let srcList = []
  340. let image = curImag.pictureFilename.indexOf('http') > -1
  341. ? curImag.pictureFilename
  342. : (this.sysConfig.pacsApi || this.sysConfig.apiurl) + curImag.pictureFilename;
  343. srcList.push(image + `?r=${Math.random()}`)
  344. let lfind = arrayExistObj(oriList, 'id', curImag.id)
  345. if (lfind > -1) {
  346. for (let i = lfind + 1; i < oriList.length; i++) {
  347. let e = oriList[i];
  348. image = this.imageFilePlus(e.pictureFilename + `?r=${Math.random()}`)
  349. srcList.push(image)
  350. }
  351. for (let index = 0; index < lfind; index++) {
  352. let e = oriList[index];
  353. image = this.imageFilePlus(e.pictureFilename + `?r=${Math.random()}`)
  354. srcList.push(image)
  355. }
  356. }
  357. return srcList
  358. },
  359. //删除小结
  360. delSum(index) {
  361. this.$confirm("此操作将删除该记录, 是否继续?", "提示", {
  362. confirmButtonText: "是",
  363. cancelButtonText: "否",
  364. type: "warning",
  365. }).then(() => {
  366. this.doctorCheck.checkSummaryList.splice(index, 1);
  367. }).catch(err => {
  368. if (err == "cancel") {
  369. // this.$message.info("已取消删除");
  370. console.log('已取消删除')
  371. }
  372. });
  373. },
  374. // 图片文件补全路径
  375. imageFilePlus(fileName) {
  376. if (fileName.indexOf('base64') > -1 || fileName.indexOf('http') > -1) {
  377. return fileName
  378. } else {
  379. return (this.sysConfig.pacsApi || this.sysConfig.apiurl) + fileName
  380. }
  381. },
  382. // 采图
  383. btnGetPic() {
  384. if (!this.doctorCheck.RegisterCheckId) {
  385. this.$message.warning({ showClose: true, message: "未选中组合项目!" });
  386. return;
  387. }
  388. if (!this.$peisAPI) {
  389. this.$message.info({ showClose: true, message: "此功能,需要在壳客户端才可运行!" })
  390. return
  391. }
  392. let toOutShell = {
  393. barCode: this.doctorCheck.checkRequestNo,
  394. patientName: this.dataTransOpts.tableS.patient_register.patientName,
  395. sexName: this.dataTransOpts.tableS.patient_register.sexName,
  396. age: (this.dataTransOpts.tableS.patient_register.age || '') + '',
  397. asbitemName: this.doctorCheck.checkRequestNo||'temp'
  398. }
  399. // console.log('this.$peisAPI.imageAcquisition', JSON.stringify(toOutShell))
  400. let loading = Loading.service({
  401. lock: true,
  402. text: "正在加载中,请稍后",
  403. spinner: "el-icon-loading",
  404. background: "rgba(0, 0, 0, 0)",
  405. customClass: "boxStyle"
  406. });
  407. this.$peisAPI.imageAcquisition(JSON.stringify(toOutShell))
  408. .then(async (res) => {
  409. let lres = JSON.parse(res)
  410. console.log('this.$peisAPI.imageAcquisition', lres)
  411. if (lres.code > -1) {
  412. for (let i = 0; i < lres.data.length; i++) {
  413. let item = lres.data[i];
  414. // FilePath:
  415. // Image
  416. // ImageFormat
  417. let baseHead = 'data:image/jpeg;base64,'
  418. switch (item.ImageFormat) {
  419. case 'png':
  420. case 'bmp':
  421. baseHead = `data:image/${item.ImageFormat};base64,`
  422. break;
  423. default:
  424. break;
  425. }
  426. this.checkPictures.push({ pictureFilename: baseHead + item.Image })
  427. let fileName = item.FilePath
  428. let dotIndex = fileName.lastIndexOf('\\');
  429. let pointIndex = fileName.lastIndexOf('.');
  430. if (dotIndex > -1) fileName = fileName.substring(dotIndex + 1, pointIndex || fileName.length);
  431. let body = {
  432. registerCheckId: this.dataTransOpts.tableS.register_check.id,
  433. pictureBaseStrs: [{
  434. fileName,
  435. localPathName: item.FilePath,
  436. pictureBaseStr: baseHead + item.Image,
  437. isPrint:'N'
  438. }],
  439. pictureFileType: '0' //采图暂定图0,上传暂定报告1 this.pictureFileType
  440. }
  441. try {
  442. //await postapi('/api/app/RegisterCheckPicture/InstrumentMapping', body)
  443. await hadoopPost('pacsApi', '/api/app/RegisterCheckPicture/InstrumentMapping', body)
  444. } catch (error) {
  445. console.log('btnGetPic err', error)
  446. }
  447. }
  448. this.getCheckPictures(this.dataTransOpts.tableS.register_check.id)
  449. } else {
  450. console.log('this.$peisAPI.imageAcquisition', lres.message)
  451. }
  452. }).catch(err => {
  453. this.$message.error(err)
  454. }).finally(() => {
  455. loading.close()
  456. });
  457. },
  458. // 接收热键采图
  459. // windows.peisAPI.receive("acceptHotKeyData",() => {
  460. // this.$message.success({showClose:true,message:'调用热键成功'})
  461. // }),
  462. acceptHotKeyData(oprType, data) {
  463. //
  464. console.log('接收壳端热键采图参数 acceptHotKeyData', oprType, data)
  465. //this.$message.success({ showClose: true, message: '调用热键成功' })
  466. if (!this.dataTransOpts.tableS.register_check.id) {
  467. console.log("没有选中检查项目")
  468. return
  469. }
  470. // 设置图片打印或不打印
  471. if (oprType == 'print' || oprType == 'unPrint') {
  472. let count = this.checkPictures.length
  473. if (count == 0) return
  474. // 最后采图的记录
  475. let picRd = this.checkPictures[count - 1]
  476. if (!picRd.id) return
  477. if (oprType == 'print') {
  478. picRd.isPrintTrans = true
  479. picRd.isPrint = 'Y'
  480. } else {
  481. picRd.isPrintTrans = false
  482. picRd.isPrint = 'N'
  483. }
  484. let body = [{
  485. registerCheckId: picRd.registerCheckId,
  486. pictureFilename: picRd.pictureFilename,
  487. pictureFileType: picRd.pictureFileType,
  488. registerCheckPictureId: picRd.id,
  489. isPrintTrans: picRd.isPrintTrans,
  490. isPrint: picRd.isPrint
  491. }]
  492. postapi("/api/app/registercheckpicture/UpdateRegisterCheckPictureStatusMany", body)
  493. .then((res) => {
  494. if (res.code < 0) {
  495. console.log('热键更新图片打印标识失败:', res.message)
  496. }else{
  497. this.getCheckPictures(this.dataTransOpts.tableS.register_check.id)
  498. }
  499. })
  500. .catch(err => {
  501. console.log('热键更新图片打印标识失败:', err)
  502. });
  503. } else if (oprType == 'delete') {
  504. let count = this.checkPictures.length
  505. if (count == 0) return
  506. // 最后采图的记录
  507. let picRd = this.checkPictures[count - 1]
  508. if (!picRd.id) return
  509. postapi(`/api/app/registercheckpicture/deleteregistercheckpicturemany`, [picRd.id])
  510. .then(res => {
  511. if (res.code > -1) {
  512. this.checkPictures.splice(count - 1, 1)
  513. this.getCheckPictures(this.dataTransOpts.tableS.register_check.id)
  514. } else {
  515. console.log("热键删除图片打印标识失败:", res.message)
  516. }
  517. })
  518. .catch(err => {
  519. console.log("热键删除图片打印标识失败:", err)
  520. })
  521. } else {
  522. try {
  523. let item = data.data[0]
  524. let baseHead = 'data:image/jpeg;base64,'
  525. switch (item.ImageFormat) {
  526. case 'png':
  527. case 'bmp':
  528. baseHead = `data:image/${item.ImageFormat};base64,`
  529. break;
  530. default:
  531. break;
  532. }
  533. let isPrintTrans = false
  534. if(oprType == 'addPrint'){
  535. item.isPrint = 'Y'
  536. isPrintTrans = true
  537. }else{
  538. item.isPrint = 'N'
  539. }
  540. // item.isPrintTrans 是否打印
  541. this.checkPictures.push({ pictureFilename: baseHead + item.Image ,isPrintTrans})
  542. let fileName = item.FilePath
  543. let dotIndex = fileName.lastIndexOf('\\');
  544. if (dotIndex > -1) fileName = fileName.substring(dotIndex, fileName.length);
  545. let body = {
  546. registerCheckId: this.dataTransOpts.tableS.register_check.id,
  547. pictureBaseStrs: [{
  548. fileName,
  549. localPathName: item.FilePath,
  550. pictureBaseStr: baseHead + item.Image,
  551. isPrint:item.isPrint
  552. }],
  553. pictureFileType: '0' //采图暂定图0,上传暂定报告1 this.pictureFileType
  554. }
  555. hadoopPost('pacsApi', '/api/app/RegisterCheckPicture/InstrumentMapping', body)
  556. .then(() => {
  557. this.getCheckPictures(this.dataTransOpts.tableS.register_check.id)
  558. })
  559. .catch(err => {
  560. console.log('热键采图失败', err)
  561. })
  562. } catch (error) {
  563. console.log('热键采图失败', error)
  564. }
  565. }
  566. },
  567. // 显示tab标签名称,过长处理
  568. dispLabel(itemName) {
  569. return itemName.length > 5 ? (itemName.substring(0, 4) + "…") : itemName
  570. },
  571. // 清除结果
  572. btnClear(seq) {
  573. if (this.doctorBtnDisabled('save')) {
  574. this.$message.warning({ showClose: true, message: "已保存,不可操作!" })
  575. return
  576. }
  577. this.doctorCheck.checkItemList[seq].result = ''
  578. },
  579. // 默认结果
  580. btnDefResult(seq) {
  581. if (this.doctorBtnDisabled('save')) {
  582. this.$message.warning({ showClose: true, message: "已保存,不可操作!" })
  583. return
  584. }
  585. this.doctorCheck.checkItemList[seq].result = this.doctorCheck.checkItemList[seq].defaultResult
  586. },
  587. // 浏览Dcm文件
  588. btnBrowseDcm() {
  589. this.checkRequestNo = this.doctorCheck.checkRequestNo
  590. this.pacsParams.result = this.doctorCheck.checkItemList[0].result
  591. let summary = ''
  592. this.doctorCheck.checkSummaryList.forEach(e => {
  593. summary += e.summary
  594. });
  595. this.pacsParams.summary = summary
  596. this.pacsParams.row = deepCopy(this.doctorCheck.checkItemList[0])
  597. this.pacsParams.index = 0
  598. this.pacsParams.refresh++
  599. // console.log('pacsParams', this.pacsParams)
  600. let token = window.sessionStorage.getItem('token')
  601. this.iframeSrc = `${this.sysConfig.dcmViewers}/?mrn=${this.doctorCheck.checkRequestNo}&token=${token}&pacsapi=${this.sysConfig.pacsApiHttps}`
  602. // this.iframeSrc = `${this.sysConfig.dcmViewers}/viewer?StudyInstanceUIDs=1.3.12.2.1107.5.1.4.79623.30000024091203062645300000022`
  603. this.tabPosition = this.doctorCheck.checkItemList.length > 2 ? 'left' : 'top'
  604. this.tabChoosed = "0"
  605. this.dialogDcm = true
  606. },
  607. // 选择描述与结论
  608. btnChooseBigtext() {
  609. // console.log('this.pacsParams', this.pacsParams)
  610. this.pacsParams.index = parseInt(this.tabChoosed)
  611. this.pacsParams.refresh++
  612. this.dialogWin.PacsTemplate = true
  613. },
  614. // 确定描述与结论
  615. btnOkBigtext() {
  616. console.log('this.pacsParams', this.pacsParams)
  617. // this.doctorCheck.checkItemList[0].result = this.pacsParams.result
  618. /*
  619. this.doctorCheck.checkSummaryList = [{
  620. id: Math.random(),
  621. registerCheckId: this.doctorCheck.RegisterCheckEdit.id,
  622. summary: this.pacsParams.summary,
  623. summaryFlag: 'N',
  624. }]
  625. */
  626. if (this.doctorCheck.checkSummaryList.length == 0) {
  627. this.$message.warning({ showClose: true, message: "请填写检查结论" })
  628. return
  629. }
  630. this.save()
  631. this.dialogDcm = false
  632. },
  633. // 处理 pacs 结果录入的情况
  634. handlePacsResult(row, index, pacsResult) {
  635. Object.assign(this.pacsParams, pacsResult)
  636. },
  637. // 浏览Dcm文件
  638. btnBrowseDcmBak() {
  639. if (!this.doctorCheck.RegisterCheckId) {
  640. this.$message.warning({ showClose: true, message: "未选中组合项目!" });
  641. return;
  642. }
  643. // 创建一个新的 <a> 元素
  644. let a = document.createElement('a');
  645. // 设置 href 属性为要跳转的 URL
  646. a.href = `${this.sysConfig.dcmViewers}/?mrn=24071610696`;
  647. //(可选)设置 target 属性,比如在新窗口打开
  648. a.target = '_blank';
  649. //(可选)防止浏览器将链接添加到历史记录
  650. a.rel = 'noopener noreferrer';
  651. // 将新创建的 <a> 元素添加到 DOM 中
  652. // 注意:这一步是可选的,如果你只想模拟点击而不想在页面上显示 <a> 元素,可以省略这一步
  653. // document.body.appendChild(a);
  654. // 模拟点击 <a> 元素
  655. a.click();
  656. //(可选)移除刚才添加到 DOM 中的 <a> 元素
  657. // 如果你选择了将 <a> 元素添加到 DOM 中,现在可以移除它
  658. // document.body.removeChild(a);
  659. },
  660. btnBrowseDcmBak2() {
  661. let userName = "peis", key = "peis@123"
  662. // let encodedAuthstring = btoa(this.stringToAscIIBytes(`${userName}:${key}`));
  663. let encodedAuthstring = this.toBase64FromUtf8(`${userName}:${key}`);
  664. console.log('encodedAuthstring', encodedAuthstring)
  665. const url = 'http://192.168.4.161:8042/ohif/viewer?url=../studies/dcdc7b20-fe11f38d-f5357ad7-139cd2cd-c0bd3701/ohif-dicom-json';
  666. const Authorization = 'Basic ' + encodedAuthstring;
  667. fetch(url, {
  668. headers: {
  669. 'Authorization': Authorization
  670. }
  671. })
  672. .then(response => response.json())
  673. .then(data => console.log(data))
  674. .catch(error => console.error('Error:', error));
  675. },
  676. toBase64FromUtf8(str) {
  677. // 使用 TextEncoder 将字符串转换为UTF-8字节序列
  678. const encoder = new TextEncoder();
  679. const bytes = encoder.encode(str);
  680. // 将字节序列转换为二进制字符串
  681. let binaryString = '';
  682. for (let byte of bytes) {
  683. binaryString += String.fromCharCode(byte);
  684. }
  685. // 使用 btoa 将二进制字符串转换为Base64
  686. return btoa(binaryString);
  687. },
  688. //导图(上传图片)
  689. btnExpPic() {
  690. if (!this.doctorCheck.RegisterCheckId) {
  691. this.$message.warning({ showClose: true, message: "未选中组合项目!" });
  692. return;
  693. }
  694. this.uploadSeq++;
  695. this.dialogCheckPictureUpload = true;
  696. },
  697. btnClean() {
  698. if (!this.doctorCheck.RegisterCheckId) {
  699. this.$message.warning({ showClose: true, message: "未选中组合项目!" });
  700. return;
  701. }
  702. postapi("/api/app/PacsBusiness/DeletePacsCheckDicomDataByRegisterCheckId", {
  703. registerCheckId: this.doctorCheck.RegisterCheckId
  704. })
  705. .then((res) => {
  706. if (res.code > -1) {
  707. }
  708. });
  709. },
  710. // 裁图/修图/
  711. btnCutPicBak() {
  712. // 跨域了
  713. this.dialogWinCutPic = true
  714. this.$refs.imgCutterModal.handleOpen({
  715. name: "1.png",
  716. src: "http://192.168.2.74:9529/PacsCheckPictureImg/pacs/2024/8/29//3a141f59-cf4c-5e34-966d-aec0a0eea94c//2408010001_0005.jpg.jpg",
  717. });
  718. },
  719. btnCutPic() {
  720. if (this.checkPictures.length == 0) {
  721. this.$message.warning({ showClose: true, message: "暂无可裁图片!" });
  722. return;
  723. }
  724. if (!this.$peisAPI) {
  725. this.$message.info({ showClose: true, message: "此功能,需要在壳客户端才可运行!" })
  726. return
  727. }
  728. let token = window.sessionStorage.getItem("token");
  729. let toOutShell = {
  730. asbitemName: this.doctorCheck.asbitemName,
  731. images: this.checkPictures,
  732. token,
  733. };
  734. this.$peisAPI.imageCut(JSON.stringify(toOutShell))
  735. .then(res => {
  736. let lres = JSON.parse(res)
  737. if (lres.code > -1) {
  738. this.getCheckPictures(this.dataTransOpts.tableS.register_check.id);
  739. } else {
  740. console.log('裁图失败', lres.message)
  741. }
  742. })
  743. .catch(err => {
  744. console.log('裁图失败', err)
  745. })
  746. },
  747. //关闭上传图片窗口
  748. closePicUpload() {
  749. this.dialogCheckPictureUpload = false;
  750. },
  751. btnSavePic() {
  752. if (!this.doctorCheck.RegisterCheckId) {
  753. this.$message.warning({ showClose: true, message: "未选中组合项目!" });
  754. return;
  755. }
  756. let body = [];
  757. // [
  758. // {
  759. // "registerCheckPictureId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", // 新增无需传此值
  760. // "registerCheckId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  761. // "pictureFilename": "string",
  762. // "isPrint": "string",
  763. // "displayOrder": 0
  764. // }
  765. // ]
  766. if (this.checkPictures.length == 0) {
  767. this.$message.warning({ showClose: true, message: "没有可保存的图片数据!" });
  768. return;
  769. }
  770. let checkPictures = deepCopy(this.checkPictures);
  771. checkPictures.sort((a, b) => {
  772. let seq1 = 0;
  773. let seq2 = 0;
  774. try {
  775. seq1 = parseInt(a.displayOrder);
  776. } catch (error) {
  777. seq1 = 0;
  778. }
  779. try {
  780. seq2 = parseInt(b.displayOrder);
  781. } catch (error) {
  782. seq2 = 0;
  783. }
  784. return seq1 - seq2;
  785. });
  786. checkPictures.forEach((e) => {
  787. let item = {
  788. registerCheckId: e.registerCheckId,
  789. pictureFilename: e.pictureFilename,
  790. pictureFileType: e.pictureFileType
  791. };
  792. if (e.id) item.registerCheckPictureId = e.id;
  793. if (e.isPrintTrans) {
  794. item.isPrint = "Y";
  795. } else {
  796. item.isPrint = "N";
  797. }
  798. body.push(item);
  799. });
  800. postapi("/api/app/registercheckpicture/UpdateRegisterCheckPictureStatusMany", body)
  801. .then((res) => {
  802. if (res.code > -1) {
  803. this.getCheckPictures(checkPictures[0].registerCheckId);
  804. }
  805. });
  806. },
  807. // 删除图片
  808. btnDelImage(index) {
  809. let body = [this.checkPictures[index].id];
  810. this.$confirm("此操作将永久删除该记录, 是否继续?", "提示", {
  811. confirmButtonText: "是",
  812. cancelButtonText: "否",
  813. type: "warning",
  814. })
  815. .then(() => {
  816. return postapi(`/api/app/registercheckpicture/deleteregistercheckpicturemany`, body);
  817. })
  818. .then((res) => {
  819. if (res && res.code > -1) {
  820. this.checkPictures.splice(index, 1);
  821. }
  822. })
  823. .catch((err) => {
  824. if (err == "cancel") {
  825. this.$message.info({ showClose: true, message: "已取消" });
  826. }
  827. });
  828. },
  829. validateInteger(e, index) {
  830. var regex = /^[0-9]*$/;
  831. console.log(e, index);
  832. if (!regex.test(e.value)) {
  833. // 如果输入不满足整数条件,则清除输入框内容
  834. e.value = "";
  835. }
  836. },
  837. // 通过检查条码查询相关数据
  838. onQueryByPacsNo(checkRequestNo) {
  839. this.checkRequestNo = checkRequestNo
  840. this.$refs['checkRequestNo'].select()
  841. postapi('/api/app/PacsBusiness/GetPatientRegisterWithCheckResultByCheckRequestNo', { checkRequestNo })
  842. .then(res => {
  843. if (res.code > -1) {
  844. // 人员信息
  845. this.dataTransOpts.tableS.patient_register = res.data.patientRegisterDetail
  846. // 组合项目
  847. this.doctorCheck.RegisterCheckList = [res.data.registerCheckDetail]
  848. // 组合项目明细
  849. this.doctorCheck.checkItemList = res.data.registerCheckItemDetails
  850. // 小结与建议
  851. this.doctorCheck.checkSummaryList = res.data.registerCheckSummaryDetails
  852. this.doctorCheck.checkSuggestionList = res.data.registerCheckSuggestionDetails
  853. // 上次结果
  854. this.doctorCheck.preResult = res.data.lastTimeAsbitemResultDetail
  855. // 检查情况
  856. this.doctorCheck.RegisterCheckEdit = res.data.registerCheckDetail
  857. // 图片
  858. this.checkPictures = res.data.registerCheckPictureDetails
  859. this.checkPictures.forEach(e => {
  860. e.isPrintTrans = e.isPrint == "Y" ? true : false
  861. });
  862. this.iframeSrc = ''
  863. this.btnBrowseDcm()
  864. }
  865. })
  866. },
  867. onFocus(event) {
  868. this.$refs['checkRequestNo'].select()
  869. }
  870. },
  871. //监听事件
  872. watch: {
  873. //检查项目未切换换时 也可以强制刷新数据
  874. "dataTransOpts.refresh.register_check_item.M": {
  875. // immediate: true,
  876. handler(newVal, oldVal) {
  877. console.log(`watch 检查图片 newVal:${newVal} oldVal:${oldVal} registerCheckId: ${this.dataTransOpts.tableS.register_check.id}`);
  878. if (newVal != oldVal) this.getCheckPictures(this.dataTransOpts.tableS.register_check.id);
  879. }
  880. },
  881. },
  882. };
  883. </script>
  884. <style scoped>
  885. .query {
  886. margin-left: 10px;
  887. margin-right: 2px;
  888. padding: 1px 1px;
  889. }
  890. .btnClass {
  891. margin: 2px 2px 0;
  892. height: 26px;
  893. min-width: 40px;
  894. padding: 5px 5px;
  895. /*原始 默认值 10px 10px */
  896. }
  897. /* 强制出现滚动条 */
  898. ::-webkit-scrollbar {
  899. height: 0.5rem;
  900. }
  901. ::-webkit-scrollbar-thumb {
  902. background-color: #ccc;
  903. border-radius: 0.25rem;
  904. }
  905. </style>