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.

1144 lines
40 KiB

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