CashierProcessInfo.vue 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071
  1. <template>
  2. <div class="layout_container">
  3. <header>
  4. <div style="height:25px;margin-bottom: 5px">
  5. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  6. <el-button :disabled="saveFlag" icon="Check" type="primary" @click="saveCashData">保存</el-button>
  7. <el-button :disabled="qxFlag" icon="Minus" type="danger" @click="cancelCash">取消出纳</el-button>
  8. <el-button type="primary" icon="RefreshLeft" @click="chongZhiData" >清空</el-button>
  9. <el-button type="warning" icon="Money" @click="openPos" >智能POS工具包</el-button>
  10. </div>
  11. <!-- <div style="text-align:center;font-weight: 700;margin-top: 15px;height:100px;r:1px solid red" id="qrcode"></div> -->
  12. <PatientBaseList ref="patientBaseListRef" :inOutFlag="1" @selectPatientInfo="selectPatient"></PatientBaseList>
  13. </header>
  14. <div class="layout_main">
  15. <el-container>
  16. <el-header style="height: 90px">
  17. <div style="width: 100%" >
  18. <el-form label-width="100px" size="large">
  19. <el-row style="width: 100%">
  20. <el-col :span="4" >
  21. <el-form-item v-show="setShowFlag" label="结算类型:">
  22. <el-input v-model="settData.settleTypeName" disabled style="width: 100px"></el-input>
  23. </el-form-item>
  24. </el-col>
  25. <el-col :span="4" >
  26. <el-form-item v-show="setShowFlag" label="自付:">
  27. <el-input v-model="settData.zfJe" disabled style="width: 100px"></el-input>
  28. </el-form-item>
  29. </el-col>
  30. <el-col :span="4" >
  31. <el-form-item v-show="setShowFlag" :label="settData.settleName">
  32. <el-input v-model="settData.settle" disabled style="width: 100px"></el-input>
  33. </el-form-item>
  34. </el-col>
  35. <el-col :span="4" >
  36. <el-form-item v-show="setShowFlag" label="实收:">
  37. <el-input-number v-model="settData.ssJe" :controls="false" :precision="2" :min="0" />
  38. </el-form-item>
  39. </el-col>
  40. <el-col :span="4" >
  41. <el-form-item v-show="setShowFlag" label="找还:">
  42. <el-input v-model="settData.zhje" disabled style="width: 80px"></el-input>
  43. </el-form-item>
  44. </el-col>
  45. <el-col :span="4" v-if="fpVersion ==='0'">
  46. <el-form-item label="当前发票号:">
  47. <span style="display: inline-block;width: 110px;background-color: #0f5e0f;text-align: center;color: #2eff00;font-size: 18px">{{settData.currentNoStr}}</span>
  48. </el-form-item>
  49. </el-col>
  50. </el-row>
  51. </el-form>
  52. </div>
  53. </el-header>
  54. <el-container>
  55. <el-aside style="width: 60%">
  56. <div style="height: 60%">
  57. <div class="border_solid layout_overflow_auto" style="float: left;width: 40%;height: 100%">
  58. <el-divider border-style="dashed" content-position="left" >记账信息</el-divider>
  59. <el-table :data="jzInfoList" style="width: 100%" height="200">
  60. <el-table-column property="ybType" label="类型" />
  61. <el-table-column property="ybJzJe" label="金额" />
  62. </el-table>
  63. </div>
  64. <div class="border_solid layout_overflow_auto" style="float: right;width: 58%;height: 100%">
  65. <el-divider border-style="dashed" content-position="left" >交款信息</el-divider>
  66. <el-table :data="jkInfoList" style="width: 100%" height="130">
  67. <el-table-column width="80" label="操作" >
  68. <template #default="scope">
  69. <el-button v-if="scope.row.settType ==='交纳' && (scope.row.depoType==='3' || scope.row.depoType==='O') " type="primary" @click="shuaKa(scope.row,scope.$index)">刷卡/扫码</el-button>
  70. </template>
  71. </el-table-column>
  72. <el-table-column property="settType" width="50" >
  73. <template #default="scope">
  74. <span v-if="scope.row.settType ==='退款'" style="color: blue;font-size: 15px">{{scope.row.settType}}</span>
  75. <span v-if="scope.row.settType !=='退款'" style="color: red;font-size: 15px">{{scope.row.settType}}</span>
  76. </template>
  77. </el-table-column>
  78. <el-table-column property="depoType" label="类型" >
  79. <template #default="scope">
  80. <el-select v-model="scope.row.depoType" size="default" style="width: 100px">
  81. <el-option v-for="item in zdChequeTypes" :key="item.code" :label="item.name" :value="item.code"></el-option>
  82. </el-select>
  83. </template>
  84. </el-table-column>
  85. <el-table-column property="depoAmount" label="金额" width="120">
  86. <template #default="scope">
  87. <el-input-number v-model="scope.row.depoAmount" @blur="calcJkJe" :controls="false" :precision="2" :min="0" size="large" style="width: 100px;"/>
  88. </template>
  89. </el-table-column>
  90. <el-table-column property="chequeNo" label="凭证号" >
  91. <template #default="scope">
  92. <el-input v-model="scope.row.chequeNo" size="default" style="width: 100px"/>
  93. </template>
  94. </el-table-column>
  95. <el-table-column >
  96. <template #default="scope">
  97. <el-button icon="Plus" @click="addJkInfo"></el-button>
  98. <el-button icon="Minus" @click="delJkInfo(scope.$index)" ></el-button>
  99. </template>
  100. </el-table-column>
  101. </el-table>
  102. <div v-if="jkInfoList.length > 0" style="width: 200px;margin-left: 100px" class="layout_overflow_auto">
  103. <el-descriptions size="large" :column="1" border >
  104. <el-descriptions-item label="交纳:" label-class-name="red-color">
  105. <span style="color: red; font-size: 24px; font-weight: bold" >{{jkHj.jnZj}} </span>
  106. </el-descriptions-item>
  107. <el-descriptions-item label="退款:" label-class-name="blue-color">
  108. <span style="color: blue; font-size: 24px; font-weight: bold">{{jkHj.tkZj}} </span>
  109. </el-descriptions-item>
  110. <el-descriptions-item label="总计:">
  111. <span style="font-size: 24px;font-weight: bold">{{jkHj.zj}} </span>
  112. </el-descriptions-item>
  113. </el-descriptions>
  114. </div>
  115. </div>
  116. </div>
  117. <div style="height: 30%">
  118. <el-divider border-style="dashed" content-position="left" >发票信息</el-divider>
  119. <div class="border_solid layout_overflow_auto" style="float: left;width: 50%;height: 100%">
  120. <el-table :data="zyInfoList" style="width: 100%" highlight-current-row @row-click="fetchZyData" height="180">
  121. <el-table-column property="ledgerSn" label="账页" />
  122. <el-table-column property="accountDate" label="结算日期" />
  123. <el-table-column label="类型" >
  124. <template #default="scope">
  125. {{getZySettType(scope.row)}}
  126. </template>
  127. </el-table-column>
  128. <el-table-column property="cashDate" label="出纳日期" />
  129. <el-table-column property="responceTypeName" label="结账身份" />
  130. </el-table>
  131. </div>
  132. <div class="border_solid layout_overflow_auto" style="float: right;width: 49%;height: 100%">
  133. <el-table :data="zyFpInfoList" style="width: 100%" height="180">
  134. <el-table-column label="操作" width="240" >
  135. <template #default="scope">
  136. <el-button v-if="scope.row.inpatientNo !=null && fpVersion==='1'" icon="Printer" type="success" @click="selectPrintZyFp(scope.row)"></el-button>
  137. <el-button v-if="scope.row.inpatientNo !=null && fpVersion==='1'" icon="Upload" title="上传电子发票" type="primary" @click="uploadZyFp(scope.row,3)"></el-button>
  138. <el-button v-if="scope.row.inpatientNo !=null && fpVersion==='1'" icon="Download" title="下载电子发票" type="primary" @click="downDzFp(scope.row)"></el-button>
  139. <el-button v-if="scope.row.inpatientNo !=null && fpVersion==='1'" icon="Delete" title="作废电子发票" type="danger" @click="uploadZyFp(scope.row,4)"></el-button>
  140. <el-button v-if="scope.row.inpatientNo !=null && fpVersion==='1'" icon="Download" title="下载已作废电子发票" type="danger" @click="downDzFp(scope.row)"></el-button>
  141. </template>
  142. </el-table-column>
  143. <el-table-column property="ledgerSn" label="账页" />
  144. <el-table-column v-if="fpVersion === '0'" property="receiptNo" label="发票号" />
  145. <el-table-column property="responceUnitName" label="类型" />
  146. <el-table-column property="totalCharge" label="发票金额" />
  147. </el-table>
  148. </div>
  149. </div>
  150. </el-aside>
  151. <el-main style="width: 40%">
  152. <el-tabs v-model="activeName" @tab-change="tabClick">
  153. <el-tab-pane label="已交押金" name="one">
  154. <el-table :data="yjYjList" style="width: 100%;" :height="350">
  155. <el-table-column property="ledgerSn" label="账页" />
  156. <!-- <el-table-column label="打印操作" >-->
  157. <!-- <template #default="scope">-->
  158. <!-- <el-button v-if="scope.row.status ==='1'" icon="Printer" type="success" @click="printFp(scope.row)">打印</el-button>-->
  159. <!-- </template>-->
  160. <!-- </el-table-column>>-->
  161. <el-table-column property="depoDate" label="日期" />
  162. <el-table-column label="事务">
  163. <template #default="{row}">
  164. <span
  165. :class="row.statusName === '结算补交'
  166. ? 'red-color' : ''"
  167. >
  168. {{row.statusName}}
  169. </span>
  170. </template>
  171. </el-table-column>
  172. <el-table-column property="depoAmount" label="金额" />
  173. <el-table-column property="receiptNo" label="收据" />
  174. <el-table-column property="depoTypeName" label="类型" />
  175. <el-table-column property="chequeNo" label="支票号" />
  176. <el-table-column property="opIdCodeName" label="操作员" />
  177. </el-table>
  178. <div>
  179. <el-descriptions size="large" :column="2" border style="width:100%;" >
  180. <el-descriptions-item label="预交张数:">
  181. <span class="f-size">{{yjHz.yjZs}} </span>
  182. </el-descriptions-item>
  183. <el-descriptions-item label="预交合计:">
  184. <span class="f-size">{{yjHz.yjHj}} </span>
  185. </el-descriptions-item>
  186. <el-descriptions-item >
  187. </el-descriptions-item>
  188. <el-descriptions-item label="直退合计:" label-class-name="red-color">
  189. <span class="f-size" style="color: red">
  190. {{yjHz.ztHj}}
  191. </span>
  192. </el-descriptions-item>
  193. <el-descriptions-item >
  194. </el-descriptions-item>
  195. <el-descriptions-item label="实际预交:">
  196. <span class="f-size">{{yjHz.sjYj}} </span>
  197. </el-descriptions-item>
  198. </el-descriptions>
  199. </div>
  200. </el-tab-pane>
  201. <el-tab-pane label="可出纳列表" name="two">
  202. <div class="layout_overflow_auto" style="width: 100%;height: 100%">
  203. <el-table :data="kcnList" highlight-current-row @row-click="fetchCnPatient" style="width: 100%;" :height="450">
  204. <el-table-column property="actFlagName" label="在院/出院" />
  205. <el-table-column property="inpatientNo" label="住院号" />
  206. <el-table-column property="admissTimes" label="住院次数" />
  207. <el-table-column property="name" label="姓名" />
  208. <el-table-column property="bedNo" label="床号" />
  209. <el-table-column property="settle" label="补/退" />
  210. <el-table-column property="wardName" label="病房" />
  211. <el-table-column property="accountDate" label="结算时间" />
  212. <el-table-column property="admissDate" label="入院日期" />
  213. </el-table>
  214. </div>
  215. </el-tab-pane>
  216. </el-tabs>
  217. </el-main>
  218. </el-container>
  219. </el-container>
  220. </div>
  221. </div>
  222. <PosTransaction ref="posTransactionRef"></PosTransaction>
  223. <el-dialog v-model="zyFpPrintVisible" title="发票打印" width="450" center>
  224. <div style="width: 100%;clear: both;" ref="dzfphtml">
  225. <div style="clear: both;">
  226. <div style="font-size:17px;float:left;width: 50%;">
  227. <div><svg id="barcode" height="20"></svg></div>
  228. <div style="margin-left: 3px;margin-top: 15px;">患者姓名:{{ dzfpData.name }}</div>
  229. <div style="margin-left: 3px;">结算金额:{{ dzfpData.fee }}</div>
  230. <div style="margin-left: 3px;">票据号码:{{ dzfpData.fpNo }}</div>
  231. <div style="margin-left: 3px;">票据代码:{{ dzfpData.fpCode }}</div>
  232. <div style="margin-left: 3px;">发票日期:{{ dzfpData.fpDate }}</div>
  233. </div>
  234. <div style="font-size:15px;float:left;width: 50%;">
  235. <div style="text-align:center;font-weight: 700;font-size:24px;padding-top: -14px">沭阳铭和医院</div>
  236. <div style="text-align:center;font-weight: 700;font-size:18px;margin-top: 5px;">电子发票信息</div>
  237. <div style="text-align:center;font-weight: 700;font-size:14px;margin-top: 25px;">扫码下载电子票据</div>
  238. <div style="text-align:center;font-weight: 700;margin-top: 15px;" id="qrcode"></div>
  239. </div>
  240. </div>
  241. </div>
  242. <template #footer>
  243. <div class="dialog-footer">
  244. <el-button @click="printZyFpToLodop">打印</el-button>
  245. <el-button @click="zyFpPrintVisible = false">取消</el-button>
  246. </div>
  247. </template>
  248. </el-dialog>
  249. <!-- <el-dialog
  250. v-model="dzfpVisible"
  251. width="400"
  252. title="下载电子发票"
  253. @closed="clearSelectDzfp"
  254. >
  255. <template #footer>
  256. <div class="dialog-footer">
  257. <el-button type="success" @click="downDzFp(selectDzfpRow,selectDzfpTypeFlag,'1')">打印电子发票二维码</el-button>
  258. <el-button type="primary" @click="downDzFp(selectDzfpRow,selectDzfpTypeFlag,'0')">下载电子发票pdf文件</el-button>
  259. </div>
  260. </template>
  261. </el-dialog> -->
  262. </template>
  263. <script setup >
  264. import PatientBaseList from "@/components/zfsf/PatientInfoHead.vue"
  265. import PosTransaction from "@/components/zfsf/PosTransaction.vue"
  266. import {ref} from "vue";
  267. import {queryCurrentNo} from '@/api/zfsf/sfbillno.js'
  268. import {queryCashierProcessInfo,
  269. queryPatientZyLedgerFile,
  270. checkCashierProcess,
  271. queryKyCashierList,
  272. queryZyReceipt,
  273. queryZyDepositFileList,
  274. saveCashierData,
  275. queryZdChequeType,
  276. cancelCashierData,
  277. queryPrintZyFpData,
  278. updatePrintZyFpData,
  279. selectDzfpUploadAboutSerialNo,
  280. queryFpVersion
  281. } from '@/api/zfsf/cashier-process.js'
  282. import {getLodop, initLodop} from '@/utils/c-lodop'
  283. import {consume} from '@/api/zfsf/pos-transaction.js'
  284. import {stringIsBlank} from "@/utils/blank-utils";
  285. import { ElMessage, ElMessageBox } from 'element-plus'
  286. import {getDateDiffToDay, getFormatDatetime} from "@/utils/date";
  287. import router from "@/router";
  288. import {queryHospitalName} from "@/api/zy-gl/zy-daily.js";
  289. import {queryLastWindowsIpAddress} from "@/api/zy-gl/admission-registration.js";
  290. import JsBarcode from 'jsbarcode'
  291. import {qrcanvas} from 'qrcanvas'
  292. const hospitalName = ref('')
  293. const zyFpPrintVisible = ref(false)
  294. const saveFlag = ref(false)
  295. const qxFlag =ref(true)
  296. const activeName = ref('one')
  297. const patientInfo = ref({
  298. inpatientNo : "",
  299. admissTimes : null,
  300. ledgerSn : null,
  301. name : '',
  302. wardName : ''
  303. }
  304. )
  305. const printCode = ref(-1)
  306. const dzfpVisible = ref(false)
  307. const dzfpSerialNo = ref(null)
  308. const setShowFlag = ref(false)
  309. const patientBaseListRef = ref(null)
  310. const posTransactionRef = ref(null)
  311. // 支付方式字典集合
  312. const zdChequeTypes = ref([])
  313. // 结算数据
  314. const settData = ref({
  315. settleTypeName:'',
  316. zfJe:0,
  317. settle:0,
  318. settleName:'',
  319. zhje:0,
  320. ssJe:0,
  321. currentNoStr:'',
  322. })
  323. // 结算数据
  324. const dzfpData = ref({
  325. inpatientNo:'',
  326. admissTimes:'',
  327. fee:'',
  328. name:'',
  329. fpCode:'',
  330. fpNo:'',
  331. fpDate:'',
  332. qrcode:'',
  333. })
  334. const dzfphtml = ref(null)
  335. const openPos = ()=>{
  336. posTransactionRef.value.openOuter()
  337. }
  338. const chongZhiData = ()=>{
  339. clearData(true)
  340. qxFlag.value = false
  341. patientBaseListRef.value.clearAllData()
  342. }
  343. //保存出纳操作
  344. const saveCashData = ()=>{
  345. ElMessageBox.confirm('请确认是否要保存?', '提示', {
  346. type: 'warning',
  347. confirmButtonText: '是',
  348. cancelButtonText: '否',
  349. }).then(()=>{
  350. let param = {
  351. inpatientNo : patientInfo.value.inpatientNo,
  352. admissTimes : patientInfo.value.admissTimes,
  353. ledgerSn : patientInfo.value.ledgerSn,
  354. opId : userIdCode.value,
  355. depositFileList :[]
  356. }
  357. if(jzInfoList.value.length > 0){
  358. let ob = {
  359. status : '4',
  360. windowNo : '2',
  361. depoAmount : jzInfoList.value[jzInfoList.value.length-1].ybJzJe,
  362. depoType : '2',
  363. chequeNo : '',
  364. psordnum : '',
  365. agtordnum : '',
  366. transDate : '',
  367. parChannel : '',
  368. traceNo : '',
  369. receiptNo : '',
  370. }
  371. param.depositFileList.push(ob);
  372. }
  373. for (let i = 0; i < jkInfoList.value.length; i++) {
  374. let obj = {
  375. status : jkInfoList.value[i].settType === '退款' ? '2' : '4',
  376. windowNo : '2',
  377. depoAmount : jkInfoList.value[i].depoAmount,
  378. depoType : jkInfoList.value[i].depoType,
  379. chequeNo : jkInfoList.value[i].chequeNo,
  380. psordnum : '',
  381. agtordnum : '',
  382. transDate : '',
  383. parChannel : '',
  384. traceNo : '',
  385. receiptNo : '',
  386. }
  387. param.depositFileList.push(obj)
  388. }
  389. saveCashierData(param).then(res=> {
  390. chongZhiData()
  391. })
  392. })
  393. }
  394. // 取消出纳
  395. const cancelCash = ()=>{
  396. ElMessageBox.confirm('请确认是否要取消出纳?', '提示', {
  397. type: 'warning',
  398. confirmButtonText: '是',
  399. cancelButtonText: '否',
  400. }).then(()=>{
  401. cancelCashierData(patientInfo.value).then(res=>{
  402. chongZhiData()
  403. })
  404. })
  405. }
  406. const getYeay = (val)=>{
  407. return val.substring(0,4)
  408. }
  409. const getMoth = (val)=>{
  410. return val.substring(5,7)
  411. }
  412. const getDay = (val)=>{
  413. return val.substring(8,10)
  414. }
  415. // 刷卡 支付
  416. const shuaKa = (row,index)=>{
  417. let obj = {
  418. chequeType : row.depoType,
  419. amt : row.depoAmount,
  420. type : 1
  421. }
  422. consume(obj).then(res=>{
  423. jkInfoList.value[index].psordnum = res.refNo
  424. jkInfoList.value[index].agtordnum = res.wxAliPayOrderNo
  425. jkInfoList.value[index].transDate = res.transDate
  426. jkInfoList.value[index].parChannel = res.payChannel
  427. jkInfoList.value[index].traceNo = res.traceNo
  428. jkInfoList.value[index].receiptNo = res.lsOrderNo
  429. })
  430. }
  431. const selectPatient =(val)=>{
  432. if(fpVersion.value ==='0'){
  433. queryCurrentNo({cashId:userIdCode.value}).then(res=>{
  434. settData.value.currentNoStr = res.currentNoStr
  435. })
  436. }
  437. // 查询账页信息
  438. queryPatientZyLedgerFile(val).then(res=>{
  439. zyInfoList.value = res
  440. if( res.length > 0){
  441. dzfpSerialNo.value=res[0].zySerialNo;
  442. let index = getSettInfoIndex(res)
  443. if(index === -1){
  444. dealSettData(res[res.length-1].inpatientNo,res[res.length-1].admissTimes,res[res.length-1].ledgerSn)
  445. }else {
  446. dealSettData(res[index].inpatientNo,res[index].admissTimes,res[index].ledgerSn)
  447. }
  448. }else {
  449. ElMessage.error('没有结算账页信息!')
  450. }
  451. })
  452. }
  453. // 检查是否有结算信息 未出纳的 下标
  454. const getSettInfoIndex = (val)=>{
  455. for (let i = 0; i < val.length; i++) {
  456. if(!stringIsBlank(val[i].accountDate) && stringIsBlank(val[i].cashDate)){
  457. return i
  458. }
  459. }
  460. return -1;
  461. }
  462. const fetchZyData = (row)=>{
  463. dealSettData(row.inpatientNo,row.admissTimes,row.ledgerSn)
  464. }
  465. // 选择出纳病人
  466. const fetchCnPatient = (row)=>{
  467. ElMessageBox.confirm('是否要进行出纳操作?', '提示', {
  468. type: 'warning',
  469. confirmButtonText: '是',
  470. cancelButtonText: '否',
  471. }).then(()=>{
  472. patientBaseListRef.value.fetchPatientData({inpatientNo:row.inpatientNo,admissTimes:row.admissTimes,inOutStatusFlag:row.actFlag})
  473. })
  474. }
  475. const dealSettData = (inpatientNo,admissTimes,ledgerSn)=>{
  476. let param = {
  477. inpatientNo : inpatientNo,
  478. admissTimes : admissTimes,
  479. ledgerSn : ledgerSn
  480. }
  481. checkCashierProcess(param).then(res =>{
  482. if(res.mzByJz != null){
  483. ElMessageBox.confirm(`该病人存在门诊欠款${res.mzByJz}是否继续出纳`, {
  484. distinguishCancelAndClose: true,
  485. cancelButtonText: '否',
  486. confirmButtonText: '是',
  487. }).then(() => {
  488. getCashierProcessInfo(param,res.zyLedgerFile,res)
  489. })
  490. .catch(action=>{
  491. if(action === 'cancel'){
  492. clearData(true)
  493. }
  494. })
  495. }else {
  496. getCashierProcessInfo(param,res.zyLedgerFile,res)
  497. }
  498. })
  499. }
  500. const getCashierProcessInfo = (param,zyLedgerFile,checkParam)=>{
  501. if(zyLedgerFile && stringIsBlank(zyLedgerFile.accountDate)){
  502. setShowFlag.value = false
  503. clearData(false)
  504. qxFlag.value = true
  505. ElMessage.error('不存在病人已结算待出纳信息!')
  506. patientBaseListRef.value.showCashName('未结算')
  507. }else {
  508. qxFlag.value = true
  509. patientBaseListRef.value.showCashName('已结算')
  510. }
  511. if(zyLedgerFile && !stringIsBlank(zyLedgerFile.cashDate)){
  512. let tempCashDate = zyLedgerFile.cashDate.substring(0,10) +' 00:00:00'
  513. let days = getDateDiffToDay(tempCashDate,new Date())
  514. if(days === 0){
  515. qxFlag.value = false
  516. }else {
  517. qxFlag.value = true
  518. }
  519. setShowFlag.value = false
  520. clearData(false)
  521. patientBaseListRef.value.showCashName('已出纳')
  522. ElMessage.error(`该病人已经在${zyLedgerFile.cashDate}做过出纳处理`)
  523. }
  524. if(checkParam.zYTotalFee != null){
  525. setShowFlag.value = false
  526. clearData(true)
  527. ElMessage.error(`该病人账页总费用${checkParam.zYTotalFee}和明细总费用${checkParam.mxTotalFee}不一致请重新结算再做出纳处理`)
  528. return
  529. }
  530. patientInfo.value.inpatientNo = param.inpatientNo
  531. patientInfo.value.admissTimes = param.admissTimes
  532. patientInfo.value.ledgerSn = param.ledgerSn
  533. queryFpAndYjj(param)
  534. if(!stringIsBlank(zyLedgerFile.accountDate) && stringIsBlank(zyLedgerFile.cashDate)){
  535. queryCashierProcessInfo(param).then(res=>{
  536. setSettData(res.settData)
  537. setJkInfoList(res.settData)
  538. setJzInfo(res.settData);
  539. setShowFlag.value = true
  540. })
  541. }
  542. }
  543. const fpVersion = ref('0')
  544. const userIdCode = ref('')
  545. onMounted(()=>{
  546. initLodop()
  547. queryFpVersion().then((res)=>{
  548. fpVersion.value =res
  549. })
  550. queryHospitalName().then(res=>hospitalName.value = res)
  551. try {
  552. let patInfo = JSON.parse(window.atob(router.currentRoute.value.params.patientInfo))
  553. userIdCode.value = patInfo.userIdCode
  554. }catch (e){
  555. }
  556. queryZdChequeType().then(res=>{
  557. zdChequeTypes.value = res
  558. })
  559. queryLastWindowsIpAddress().then(res=>{
  560. printCode.value = res.zyPrintIndex
  561. })
  562. // setTimeout(()=>{
  563. // const labelCanvas = qrcanvas({
  564. // data: "http://einvoice.jsczt.cn/d/4730209e87b15674ba6",
  565. // size: 50,
  566. // })
  567. // let src = canvasToBase64(labelCanvas);
  568. // let wxPayQrCardHtml =`<img src="${src}" style="width: 100px;height: 100px"/><div style="width: 140px;margin-top: 2px;"></img>`;
  569. // console.log("dzfpData",wxPayQrCardHtml)
  570. // document.getElementById('qrcode').innerHTML = '';
  571. // document.getElementById('qrcode').innerHTML = wxPayQrCardHtml
  572. // },1000)
  573. })
  574. // 查询发票和预交金
  575. const queryFpAndYjj = (param)=>{
  576. queryZyReceipt(param).then(res=>{
  577. zyFpInfoList.value = res
  578. })
  579. queryZyDepositFileList(param).then(res=>{
  580. yjYjList.value = res.yjYj
  581. yjHz.value.sjYj = res.sjYj
  582. yjHz.value.yjZs = res.yjZs
  583. yjHz.value.ztHj = res.ztHj
  584. yjHz.value.yjHj = res.yjHj
  585. patientInfo.value.name = res.patInfo.name
  586. patientInfo.value.wardName = res.patInfo.wardName
  587. })
  588. }
  589. const clearData = (zyFlag)=>{
  590. if(zyFlag){
  591. zyInfoList.value = []
  592. }
  593. jkHj.value.zj = 0
  594. jkHj.value.tkZj = 0
  595. jkHj.value.jnZj = 0
  596. jzInfoList.value = []
  597. jkInfoList.value = []
  598. zyFpInfoList.value = []
  599. yjYjList.value = []
  600. settData.value.settleTypeName = ''
  601. settData.value.zfJe = 0
  602. settData.value.settle = 0
  603. settData.value.settleName = ''
  604. settData.value.zhje = 0.00
  605. settData.value.ssJe = 0.00
  606. patientInfo.value.inpatientNo = ''
  607. patientInfo.value.admissTimes = null
  608. patientInfo.value.ledgerSn = null
  609. patientInfo.value.name = ''
  610. patientInfo.value.wardName = ''
  611. yjHz.value.sjYj = 0
  612. yjHz.value.yjHj = 0
  613. yjHz.value.yjZs = 0
  614. yjHz.value.ztHj = 0
  615. }
  616. const setSettData = (val)=>{
  617. settData.value.settleName = val.settleName
  618. settData.value.settleTypeName = val.settleTypeName
  619. settData.value.zhje = 0.00
  620. settData.value.ssJe = 0.00
  621. settData.value.settle = Math.abs(val.settle)
  622. settData.value.zfJe = val.lastBalance
  623. }
  624. const setJzInfo = (settData)=>{
  625. jzInfoList.value = []
  626. if(settData.ybJzJe && settData.ybJzJe != 0){
  627. jzInfoList.value.push({
  628. ybType : '医保记账',
  629. ybJzJe :settData.ybJzJe
  630. })
  631. jzInfoList.value.push({
  632. ybType : '记账总计',
  633. ybJzJe :settData.ybJzJe
  634. });
  635. jzInfoList.value.push({
  636. ybType : '医院负担金额',
  637. ybJzJe :settData.hospPartamt
  638. });
  639. }
  640. }
  641. // 新增交款信息
  642. const addJkInfo = ()=>{
  643. let obj = {
  644. settType : '',
  645. depoType : 'A',
  646. depoAmount : 0,
  647. chequeNo : '',
  648. psordnum : '',
  649. agtordnum : '',
  650. transDate : '',
  651. parChannel : '',
  652. traceNo : '',
  653. receiptNo : '',
  654. }
  655. let tkZj= jkInfoList.value.filter(item=>item.settType === '退款').reduce((pre,cur)=>{
  656. return pre + cur.depoAmount ;
  657. },0)
  658. let jnZj= jkInfoList.value.filter(item=>item.settType === '交纳').reduce((pre,cur)=>{
  659. return pre + cur.depoAmount ;
  660. },0)
  661. if(settData.value.settleName === '补交:'){
  662. if((jnZj - tkZj) <= Math.abs(settData.value.settle)){
  663. obj.settType ='交纳'
  664. obj.depoAmount = Math.abs(jnZj - tkZj -Math.abs(settData.value.settle))
  665. }else {
  666. obj.settType ='退款'
  667. obj.depoAmount = Math.abs(jnZj - tkZj -Math.abs(settData.value.settle))
  668. }
  669. }else {
  670. if((tkZj - jnZj) >= Math.abs(settData.value.settle)){
  671. obj.settType ='交纳'
  672. obj.depoAmount = Math.abs(tkZj - jnZj -Math.abs(settData.value.settle))
  673. }else {
  674. obj.settType ='退款'
  675. obj.depoAmount = Math.abs(tkZj - jnZj -Math.abs(settData.value.settle))
  676. }
  677. }
  678. jkInfoList.value.push(obj)
  679. calcJkJe()
  680. }
  681. const delJkInfo = (index)=>{
  682. if(jkInfoList.value.length === 1){
  683. ElMessage.error("交款信息不能为空")
  684. return
  685. }
  686. jkInfoList.value.splice(index, 1)
  687. calcJkJe()
  688. }
  689. const jkHj = ref({
  690. jnZj : 0,
  691. tkZj : 0,
  692. zj : 0
  693. })
  694. const calcJkJe = ()=>{
  695. let tkZj= jkInfoList.value.filter(item=>item.settType === '退款').reduce((pre,cur)=>{
  696. return pre + cur.depoAmount ;
  697. },0)
  698. let jnZj= jkInfoList.value.filter(item=>item.settType === '交纳').reduce((pre,cur)=>{
  699. return pre + cur.depoAmount ;
  700. },0)
  701. jkHj.value.jnZj = parseFloat(Number(jnZj).toFixed(2))
  702. jkHj.value.tkZj = parseFloat(Number(tkZj).toFixed(2))
  703. jkHj.value.zj = parseFloat(Number(Math.abs(jkHj.value.jnZj - jkHj.value.tkZj)).toFixed(2))
  704. }
  705. const setJkInfoList = (val)=>{
  706. jkInfoList.value = []
  707. let obj = {
  708. settType : '',
  709. depoType : 'A',
  710. depoAmount : 0,
  711. chequeNo : '',
  712. psordnum : '',
  713. agtordnum : '',
  714. transDate : '',
  715. parChannel : '',
  716. traceNo : '',
  717. receiptNo : '',
  718. }
  719. obj.settType = val.settle > 0 ? '退款' : '交纳';
  720. // let hospPartamt = val.hospPartamt ? val.hospPartamt : 0;
  721. obj.depoAmount = Math.abs(val.settle);
  722. jkInfoList.value.push(obj)
  723. calcJkJe()
  724. }
  725. // 记账信息数据
  726. const jzInfoList = ref([])
  727. // 交款信息
  728. const jkInfoList = ref([])
  729. // 账页信息
  730. const zyInfoList = ref([])
  731. // 账页发票信息
  732. const zyFpInfoList = ref([])
  733. // 已交押金
  734. const yjYjList = ref([])
  735. // 预交汇总
  736. const yjHz = ref({
  737. yjZs : 0,
  738. sjYj : 0,
  739. yjHj : 0,
  740. ztHj : 0,
  741. })
  742. // 可出纳数据
  743. const kcnList = ref([])
  744. const tabClick = ()=>{
  745. if(activeName.value ==='two'){
  746. let startDate = getDateTiffDays(1).substring(0,10) + ' 00:00:00'
  747. let endDate = getDateTiffDays(1).substring(0,10) + ' 23:59:59'
  748. queryKyCashierList({startDate:startDate,endDate:endDate}).then(res=>{
  749. kcnList.value = res
  750. })
  751. }
  752. }
  753. //打印发票
  754. // const printFp = (row)=>{
  755. //
  756. // let LODOP = getLodop();
  757. // LODOP.PRINT_INIT('预交金')
  758. // LODOP.SET_PRINT_PAGESIZE(2, 0, 0, '')
  759. // LODOP.SET_PRINT_STYLE('FontSize', 9)
  760. // LODOP.ADD_PRINT_TEXT('8mm', '50mm', '220mm', '7mm', patientInfo.value.wardName)
  761. // LODOP.ADD_PRINT_TEXT('14mm', '50mm', '220mm', '7mm', patientInfo.value.name)
  762. // LODOP.ADD_PRINT_TEXT('20mm', '50mm', '220mm', '7mm', '紧急联系人:13908453983')
  763. // LODOP.ADD_PRINT_TEXT('30mm', '50mm', '220mm', '7mm', getYeay(row.depoDate)+'.'+getMoth(row.depoDate)+'.'+getDay(row.depoDate))
  764. // LODOP.ADD_PRINT_TEXT('40mm', '50mm', '220mm', '7mm', row.opIdCodeName)
  765. // LODOP.PREVIEW()
  766. //
  767. // }
  768. const zyFpCss = `
  769. #zyFpId{ width: 640px;}
  770. #headDiv p {
  771. line-height: 10px;
  772. }
  773. .comSpan{
  774. display: inline-block;
  775. width: 60px;
  776. }
  777. .spanW{
  778. display: inline-block;
  779. width: 60px;
  780. }
  781. .comH {
  782. height: 24px;
  783. }
  784. .comM{
  785. margin-left: 90px;
  786. }`
  787. const printZyFp = ()=>{
  788. let param = {
  789. inpatientNo :printZyFpInfo.value.inpatientNo,
  790. admissTimes :printZyFpInfo.value.admissTimes,
  791. ledgerSn :printZyFpInfo.value.ledgerSn,
  792. printFlag :printFlag.value ? '1' : '0',
  793. receiptNo : settData.value.currentNoStr,
  794. opId : userIdCode.value
  795. }
  796. updatePrintZyFpData(param).then(res=>{
  797. let LODOP = getLodop()
  798. LODOP.PRINT_INIT('住院发票') // 初始化打印机 名字
  799. LODOP.SET_PRINT_PAGESIZE(1, '256mm', '156mm', '') // 设置纸张大小
  800. LODOP.SET_PRINT_MODE('FULL_WIDTH_FOR_OVERFLOW', true) // 整宽不变形
  801. LODOP.ADD_PRINT_HTM('1mm', '3mm', '100%', '100%', '<style>' + zyFpCss + '</style>' + '<body>' + document.getElementById('zyFpId').innerHTML + '</body>') //要打印的内容
  802. LODOP.PREVIEW() // 关闭
  803. })
  804. }
  805. const printZyFpInfo = ref({})
  806. const selectPrintZyFp = (row)=>{
  807. console.log("dzfpData",row)
  808. zyFpPrintVisible.value = true
  809. let params = {
  810. inpatientNo:row.inpatientNo,
  811. admissTimes:row.admissTimes,
  812. // serialNo:dzfpSerialNo.value
  813. }
  814. selectDzfpUploadAboutSerialNo(params).then(res=>{
  815. if(res.res_url){
  816. dzfpData.value={
  817. inpatientNo:row.inpatientNo,
  818. admissTimes:row.admissTimes,
  819. name:patientInfo.value.name,
  820. fee:row.totalCharge,
  821. fpCode:res.op_code,
  822. fpNo:res.fp_no,
  823. fpDate:res.blue_issue_date,
  824. qrcode:res.res_url
  825. }
  826. JsBarcode('#barcode',row.inpatientNo, {
  827. renderer: "svg",
  828. lineColor: '#000000', //线条颜色
  829. width: 1, //线宽
  830. height: 30, //条码高度
  831. displayValue: true, //是否显示文字信息
  832. fontSize: 18,
  833. });
  834. console.log("row",dzfpData.value.qrcode)
  835. const labelCanvas = qrcanvas({
  836. data: dzfpData.value.qrcode,
  837. size: 50,
  838. })
  839. let src = canvasToBase64(labelCanvas);
  840. let wxPayQrCardHtml =`<img src="${src}" style="width: 100px;height: 100px"/><div style="width: 140px;margin-top: 2px;"></img>`;
  841. console.log("dzfpData",wxPayQrCardHtml)
  842. document.getElementById('qrcode').innerHTML = '';
  843. document.getElementById('qrcode').innerHTML = wxPayQrCardHtml
  844. // console.log("dzfpData",dzfpData.value)
  845. // printZyFpToLodop()
  846. } else {
  847. ElMessage.error("未获取到电子发票,请重新上传发票!");
  848. }
  849. dzfpVisible.value = false
  850. })
  851. }
  852. const printZyFpToLodop = ()=>{
  853. console.log("dzfpData",dzfphtml.value.innerHTML)
  854. zyFpPrintVisible.value = false
  855. let LODOP = getLodop();
  856. LODOP.PRINT_INIT("检查检验申请单");
  857. LODOP.SET_PRINT_PAGESIZE(1, "120mm", "80mm", "CreateCustomPage");
  858. LODOP.SET_PRINT_MODE("PRINT_PAGE_PERCENT", "Full-Width");
  859. LODOP.SET_PRINT_MODE("PRINT_START_PAGE", 1);
  860. LODOP.SET_PRINT_MODE("PRINT_END_PAGE", 1);
  861. LODOP.ADD_PRINT_HTM(0, '8mm', '100%', '100%', dzfphtml.value.innerHTML)
  862. // LODOP.ADD_PRINT_HTM("1mm", "1mm", "100%", "100%", dzfphtml.value);
  863. LODOP.PREVIEW();
  864. }
  865. const canvasToBase64=(canvas, type = 'image/png', quality = 0.92)=> {
  866. try {
  867. // 检查是否是有效的canvas元素
  868. if (!(canvas instanceof HTMLCanvasElement)) {
  869. throw new Error('传入的不是Canvas元素');
  870. }
  871. // toDataURL()方法参数:
  872. // 第一个参数是图像格式,默认为'image/png'
  873. // 第二个参数是质量,仅对'image/jpeg'和'image/webp'有效,范围0-1
  874. const base64String = canvas.toDataURL(type, quality);
  875. // 如果需要纯Base64字符串(去掉dataURL前缀),可以这样处理:
  876. // const pureBase64 = base64String.split(',')[1];
  877. return base64String;
  878. } catch (error) {
  879. console.error('转换Canvas到Base64失败:', error);
  880. return null;
  881. }
  882. }
  883. const selectDzfpRow = ref({})
  884. const selectDzfpTypeFlag = ref(null)
  885. const openDzfp = (row,typeFlag)=>{
  886. console.log("selectDzfpRow",JSON.stringify(row))
  887. selectDzfpRow.value = row
  888. selectDzfpTypeFlag.value = typeFlag
  889. dzfpVisible.value = true
  890. }
  891. const uploadZyFp=(row,typeFlag)=>{
  892. row['typeFlag'] = typeFlag
  893. let typeFlagStr = typeFlag == 3 ? '上传' : '作废'
  894. ElMessageBox.prompt("备注", "提示", {
  895. type: "warning",
  896. confirmButtonText: "确定"+typeFlagStr,
  897. cancelButtonText: "取消",
  898. })
  899. .then(({value}) => {
  900. row['remark'] = value
  901. queryPrintZyFpData(row).then(res=>{
  902. ElMessage.success(typeFlagStr+"电子发票成功!");
  903. })
  904. })
  905. }
  906. const clearSelectDzfp = ()=>{
  907. selectDzfpRow.value = {}
  908. selectDzfpTypeFlag.value = null
  909. }
  910. const downDzFp = (row)=>{
  911. console.log("downDzFp",row)
  912. let params = {
  913. inpatientNo:row.inpatientNo,
  914. admissTimes:row.admissTimes
  915. }
  916. selectDzfpUploadAboutSerialNo(params).then(res=>{
  917. // console.log("row",JSON.stringify(res))
  918. if(res.res_url){
  919. window.open(res.res_url)
  920. } else {
  921. ElMessage.error("未获取到电子发票,请重新上传发票!");
  922. }
  923. dzfpVisible.value = false
  924. })
  925. }
  926. const base64ToArrayBuffer = (base64) => {
  927. var bloBString = window.atob(base64);
  928. var bloBLen = bloBString .length;
  929. var bytes = new Uint8Array(bloBLen);
  930. for (var i = 0; i < bloBLen; i++) {
  931. var ascii = bloBString .charCodeAt(i);
  932. bytes[i] = ascii;
  933. }
  934. return bytes;
  935. };
  936. const printFlag = ref(true)
  937. const getZySettType= (row)=>{
  938. if(stringIsBlank(row.accountDate)){
  939. return '未结算'
  940. }else {
  941. if(stringIsBlank(row.cashDate)){
  942. return '未出纳'
  943. }else {
  944. return '已出纳'
  945. }
  946. }
  947. }
  948. </script>
  949. <style scoped>
  950. .border_solid{
  951. border: 1px #808080 solid
  952. }
  953. .f-size{
  954. font-size: 18px;
  955. }
  956. .comSpan{
  957. display: inline-block;
  958. width: 60px;
  959. }
  960. .spanW{
  961. display: inline-block;
  962. width: 60px;
  963. }
  964. .comH {
  965. height: 24px;
  966. }
  967. .comM{
  968. margin-left: 90px;
  969. }
  970. #zyFpId p {
  971. line-height: 10px;
  972. }
  973. </style>