west_pharmacy_send.js 202 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620
  1. //@ sourceURL=west_pharmacy_send.js
  2. var LODOP; //声明为全局变量
  3. var printIndex;
  4. var mzCfPrintIndex = window.localStorage["mzCfPrintIndex"];
  5. var ekCfPrintIndex = window.localStorage["ekCfPrintIndex"];
  6. var jzCfPrintIndex = window.localStorage["jzCfPrintIndex"];
  7. var zsdPrintIndex = window.localStorage["zsdPrintIndex"];
  8. var bqPrintIndex = window.localStorage["bqPrintIndex"];
  9. var fskPrintIndex = window.localStorage["fskPrintIndex"];
  10. var winNo = window.localStorage["winNo"];
  11. var groupNo = window.localStorage["groupNo"];
  12. let coreId // 病人id
  13. let mzHistoryDays = 30 // 门诊历史处方前置天数
  14. let isTyOk = false;
  15. var hospitalName ='沭阳铭和医院';
  16. let yf;
  17. // ================= 新增:追溯码扫描状态跟踪变量 =================
  18. // 目的:支持智能追溯码匹配功能,记录每个药品的扫描状态和退药数量
  19. // 修改时间:2025年
  20. // 修改原因:实现只扫描退药数量对应追溯码的功能,提高工作效率
  21. // 变量说明:
  22. // - scannedCodesMap: 记录每个药品已扫描的追溯码数组,格式:{药品编码: [追溯码1, 追溯码2, ...]}
  23. // - refundQuantityMap: 记录每个药品的退药数量,格式:{药品编码: 退药数量}
  24. let scannedCodesMap = {}; // 记录每个药品的扫描情况
  25. let refundQuantityMap = {}; // 记录每个药品的退药数量
  26. $(function () {
  27. getAjaxRequst("/thmz/queryHospitalName",{},true,function (res) {
  28. hospitalName = res.data
  29. $('.hospitalName').text(hospitalName)
  30. })
  31. init_daterangepicker();
  32. // 查看门诊历史处方前置天数
  33. mzHistoryDays = parseInt(!initSysParametersByCode('mzHistoryDays') ? '30' : initSysParametersByCode('mzHistoryDays'))
  34. $(".selectpicker").selectpicker({
  35. dropuAuto: false
  36. });
  37. if (groupNo == null || winNo == null) {
  38. return errorMesageSimaple('药房参数未设置,请在发药参数设置中设置');
  39. }
  40. yf = selectYfInfo(groupNo)
  41. // if (yf.xyFlag === '1') {
  42. // $('#autoCellNumberDiv').hide();
  43. // }
  44. openSocket("FY");
  45. $("input").each(function () {
  46. this.onkeydown = function (e) { // 监听键盘事件
  47. let theEvent = window.event || e;
  48. let code = theEvent.keyCode || theEvent.which;
  49. if (code == 13) {//回车事件
  50. $("#btn_query").click(); //触发搜索按钮点击事件
  51. }
  52. }
  53. });
  54. initTbTable();
  55. initDynamicSelect("allMzUnitCode", "unitCode");
  56. //重置查询参数
  57. $('#btn_clean').click(function () {
  58. cleanParams();
  59. });
  60. $('#btn_clean_history').click(function () {
  61. $('#reportRangeList span').html(moment().subtract(mzHistoryDays, 'days').format('YYYY-MM-DD') + ' - ' + moment().format('YYYY-MM-DD'));
  62. });
  63. $("#btn_query_history").click(function (t) {
  64. callHistoryDetail();
  65. });
  66. $("#btn_query").click(function (t) {
  67. initTbTable();
  68. });
  69. $("#sendAndMatch").click(function (t) {
  70. initTbTable();
  71. });
  72. $("#btn_radiology_send").click(function (t) {
  73. initRadiologyTable();
  74. });
  75. $("#btn_batch_send").click(function (t) {
  76. var rows = $("#tb_table").bootstrapTable('getSelections');
  77. if (rows.length == 0) {
  78. return errorMesageSimaple('请选择你要进行发药处理的处方');
  79. }
  80. var tem = [];
  81. for (let i = 0; i < rows.length; i++) {
  82. let item = rows[i];
  83. item.groupNo = groupNo;
  84. item.chargeDate = null;//后台转换异常,临时赋空
  85. tem.push({
  86. mzChargeDetail: item,
  87. winNo: winNo
  88. });
  89. if (item.confirmFlag != 5 && item.confirmFlag != 0) {
  90. return errorMesageSimaple('包含非未发药处方,发药失败');
  91. }
  92. }
  93. if (!confirm("确定要对选中的处方进行发药处理吗?")) {
  94. return;
  95. }
  96. batchSendMedicineProcessing(tem);
  97. });
  98. $("#btn_ty").click(function (t) {
  99. saveRefundMedicine();
  100. });
  101. $("#btn_cancel_ty").click(function (t) {
  102. saveCancelRefundMedicine();
  103. });
  104. $("#sendDispose").click(function (t) {
  105. let orderNo = $("#orderNoLabel").val();
  106. let receiptNo = $("#receiptNoLabel").val();
  107. let times = $("#timesLabel").val();
  108. let name = $("#nameLabel").val();
  109. let patientId = $("#patientIdLabel").val();
  110. let realNo = $("#realNoLabel").val();
  111. // 从全局变量获取药师执业资格证号
  112. let pharPracCertNo = window.currentPharPracCertNo || '';
  113. // 先验证追溯码数量,再决定是否发药
  114. validateTracCodgQuantity(realNo, orderNo, receiptNo, times, patientId, name, pharPracCertNo);
  115. });
  116. // 追溯码数量确认弹框的确认发药按钮
  117. $("#confirmTracCodgSend").click(function (t) {
  118. // ================= 新增:确认发药时再次验证追溯码数量 =================
  119. // 目的:确保追溯码数量与处方数量完全匹配才能发药
  120. // 获取处方明细表格数据
  121. let tableData = $("#tb_table_right").bootstrapTable('getData');
  122. let hasMismatch = false;
  123. let mismatchMessage = '';
  124. console.log('确认发药时验证追溯码数量,表格数据:', tableData);
  125. // 遍历每种药品,检查追溯码数量
  126. for (let i = 0; i < tableData.length; i++) {
  127. let drug = tableData[i];
  128. let prescriptionQuantity = parseInt(drug.quantity) || 0; // 处方数量
  129. let tracCodgCount = 0; // 追溯码数量
  130. // 中药免校验:drug_kind 为 '09' 或 '10' 时,跳过追溯码数量检查
  131. if (drug.drugKind === '09' || drug.drugKind === '10') {
  132. continue;
  133. }
  134. // 计算该药品的追溯码数量
  135. if (!isEmpty(drug.drugTracCodg)) {
  136. // 按<br>分割追溯码,过滤空值
  137. let tracCodgList = drug.drugTracCodg.split('<br>').filter(code => code.length > 0);
  138. tracCodgCount = tracCodgList.length;
  139. }
  140. console.log('药品:', drug.drugname, '处方数量:', prescriptionQuantity, '追溯码数量:', tracCodgCount, '拆零状态:', drug.serial);
  141. // ================= 修改:根据药品类型区分验证逻辑 =================
  142. // 目的:拆零药品必须上传一个追溯码,不拆零药品维持原样
  143. // 判断逻辑:serial="01"为拆零药品,serial="99"为不拆零药品
  144. let isSplitDrug = (drug.serial === '01'); // 拆零药品
  145. let isNonSplitDrug = (drug.serial === '99'); // 不拆零药品
  146. // 拆零药品必须上传至少一个追溯码
  147. if (isSplitDrug && tracCodgCount === 0) {
  148. hasMismatch = true;
  149. mismatchMessage += '药品【' + drug.drugname + '】: 拆零药品必须上传至少一个追溯码;\n';
  150. console.log('拆零药品【' + drug.drugname + '】必须上传至少一个追溯码');
  151. }
  152. // 不拆零药品检查追溯码数量是否匹配
  153. if (isNonSplitDrug && tracCodgCount !== prescriptionQuantity) {
  154. hasMismatch = true;
  155. let difference = tracCodgCount - prescriptionQuantity;
  156. let differenceText = '';
  157. if (difference > 0) {
  158. differenceText = '多输入 ' + difference + ' 个';
  159. } else {
  160. differenceText = '缺少 ' + Math.abs(difference) + ' 个';
  161. }
  162. mismatchMessage += '药品【' + drug.drugname + '】: 处方数量 ' + prescriptionQuantity + ',追溯码数量 ' + tracCodgCount + ',' + differenceText + ';\n';
  163. }
  164. // ================= 修改结束 =================
  165. }
  166. // 如果数量不匹配,阻止发药并显示错误提示
  167. if (hasMismatch) {
  168. console.error('追溯码数量不匹配,阻止发药:', mismatchMessage);
  169. errorMesageSimaple('追溯码数量与处方数量不匹配,无法发药!\n\n' + mismatchMessage);
  170. return; // 阻止后续操作
  171. }
  172. // ================= 新增结束 =================
  173. // ================= 原代码(已隐藏,可能复用) =================
  174. /*
  175. // 获取存储的发药参数
  176. let sendParams = window.pendingSendParams;
  177. if (sendParams) {
  178. // 隐藏确认弹框
  179. $('#tracCodgConfirmModal').modal('hide');
  180. // 执行发药处理
  181. sendMedicineProcessing(sendParams.realNo, sendParams.orderNo, sendParams.receiptNo,
  182. sendParams.times, sendParams.patientId, sendParams.name, sendParams.pharPracCertNo);
  183. // 清除存储的参数
  184. window.pendingSendParams = null;
  185. }
  186. */
  187. // ================= 原代码结束 =================
  188. // ================= 新增:数量匹配时的处理逻辑 =================
  189. // 获取存储的发药参数
  190. let sendParams = window.pendingSendParams;
  191. if (sendParams) {
  192. // 隐藏确认弹框
  193. $('#tracCodgConfirmModal').modal('hide');
  194. // 执行发药处理
  195. sendMedicineProcessing(sendParams.realNo, sendParams.orderNo, sendParams.receiptNo,
  196. sendParams.times, sendParams.patientId, sendParams.name, sendParams.pharPracCertNo);
  197. // 清除存储的参数
  198. window.pendingSendParams = null;
  199. console.log('追溯码数量验证通过,执行发药处理');
  200. }
  201. // ================= 新增结束 =================
  202. });
  203. $("#printSend").click(function (t) {
  204. $('#zydybqModal').modal('hide');
  205. $("#zyypbq_name").attr("value", $("#zydyNameLabel").val());
  206. $("#zyypbq_sex").attr("value", $("#sexLabel").val());
  207. $("#zyypbq_age").attr("value", $("#ageLabel").val());
  208. $("#zyypbq_date").attr("value", $("#dateLabel").val());
  209. $("#zyypbq_comm").text($("#yfLabel").val());
  210. if ($("#syfsLabel").val() == 0) {
  211. $("#zybq_title").text("中药【口服】标签");
  212. } else {
  213. $("#zybq_title").text("中药【外用】标签");
  214. }
  215. LODOP = getLodop();
  216. LODOP.PRINT_INITA(6, 0, "50mm", "30mm", "中药标签");
  217. //设置默认打印机
  218. LODOP.SET_PRINTER_INDEX(bqPrintIndex);
  219. LODOP.SET_PRINT_PAGESIZE(1, '50mm', '30mm', "CreateCustomPage");
  220. LODOP.SET_SHOW_MODE("BKIMG_WIDTH", "50mm");
  221. LODOP.SET_SHOW_MODE("BKIMG_HEIGHT", "30mm");
  222. LODOP.SET_PRINT_MODE("CREATE_CUSTOM_PAGE_NAME", "中药标签");//对新建的纸张重命名
  223. LODOP.SET_PRINT_COPIES(parseInt($("#dyslLabel").val()));
  224. LODOP.ADD_PRINT_HTM("2mm", "2mm", "50mm", "30mm", $('#print_view_zybq').html());
  225. LODOP.PREVIEW();
  226. //LODOP.PREVIEW();
  227. });
  228. });
  229. /**
  230. * 批量发药处理
  231. */
  232. function batchSendMedicineProcessing(tem) {
  233. $("#btn_batch_send").attr("disabled", true);
  234. $.ajax({
  235. type: "POST",
  236. url: '/thmz/batchSendMedicineProcessing',
  237. contentType: "application/json;charset=UTF-8",
  238. dataType: "json",
  239. headers: {'Accept': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("token")},
  240. data: JSON.stringify(tem),
  241. success: function (res) {
  242. $("#btn_batch_send").attr("disabled", false);
  243. if (res == '401' || res == 401) {
  244. window.location.href = '/thmz/login/view'
  245. return;
  246. }
  247. initTbTable($('#tb_table').bootstrapTable('getOptions').pageNumber);
  248. if (res.code == 0) {
  249. successMesage(res);
  250. } else {
  251. errorMesage(res);
  252. }
  253. },
  254. error: function () {
  255. $("#btn_batch_send").attr("disabled", false);
  256. }
  257. });
  258. }
  259. /**
  260. * 获取按钮组选择的下标
  261. * @param id
  262. * @returns {number}
  263. */
  264. function getIndex(id) {
  265. var index = 0;
  266. var item = $("#" + id).find("button");
  267. for (var i = 0; i <= item.length; i++) {
  268. if ($(item[i]).hasClass("btn-primary")) {
  269. index = i;
  270. break;
  271. }
  272. }
  273. return index;
  274. }
  275. /**
  276. * 设置病人id
  277. */
  278. function setPatientId() {
  279. var patientId_or_cardNo = $("#patientId_or_cardNo").val();
  280. if (patientId_or_cardNo == '') {
  281. return $("#patientId").val("");
  282. }
  283. $.ajax({
  284. type: "GET",
  285. url: '/thmz/getByIcCardNo?icCardNo=' + patientId_or_cardNo,
  286. contentType: "application/json;charset=UTF-8",
  287. dataType: "json",
  288. headers: {'Accept': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("token")},
  289. success: function (res) {
  290. if (res == '401' || res == 401) {
  291. window.location.href = '/thmz/login/view'
  292. return;
  293. }
  294. if (res.code == 0) {
  295. if (res.data != null) {
  296. $("#patientId").val(res.data.patientId);
  297. } else {
  298. $("#patientId").val(patientId_or_cardNo);
  299. }
  300. }
  301. }
  302. });
  303. }
  304. /**
  305. * 列表类型按钮切换事件
  306. * @param object
  307. * @param realIndex 下标
  308. */
  309. function sendRefundButtonChange(object, realIndex) {
  310. $("#send_refund_group").find("button").each(function (index, element) {
  311. if ($(element).hasClass("btn-primary")) {
  312. $(element).removeClass("btn-primary").addClass("btn-default");
  313. }
  314. });
  315. if (realIndex == 0) {
  316. $("#confirmFlagSearch").empty();
  317. $("#confirmFlagSearch").append("<option value='0' selected>未发药</option>");
  318. $("#confirmFlagSearch").append("<option value='1'>已发药</option>");
  319. $("#confirmFlagSearch").selectpicker('refresh');
  320. $("#tb_table_right_ty").css("display", "none");
  321. $("#return_total_amount").css("display", "none");
  322. $("#btn_ty").addClass("hidden");
  323. $("#btn_cancel_ty").addClass("hidden");
  324. $("#btn_radiology_send").removeClass("hidden");
  325. $("#btn_batch_send").removeClass("hidden");
  326. } else {
  327. $("#confirmFlagSearch").empty();
  328. $("#confirmFlagSearch").append("<option value='2' selected>待退药</option>");
  329. $("#confirmFlagSearch").append("<option value='3'>已退药</option>");
  330. $("#confirmFlagSearch").selectpicker('refresh');
  331. $("#tb_table_right_ty").css("display", "");
  332. $("#btn_ty").removeClass("hidden");
  333. // ================= 新增:撤销退药按钮始终隐藏 =================
  334. // 目的:确保撤销退药按钮始终隐藏,防止误操作
  335. // 修改时间:2025年
  336. // 修改原因:业务需求,不允许撤销退药操作
  337. // 说明:注释掉显示逻辑,确保按钮始终隐藏
  338. // $("#btn_cancel_ty").removeClass("hidden");
  339. $("#btn_radiology_send").addClass("hidden");
  340. $("#btn_batch_send").addClass("hidden");
  341. }
  342. $(object).removeClass("btn-default").addClass("btn-primary");
  343. initTbTable();
  344. }
  345. /**
  346. * 发药处理
  347. */
  348. function sendMedicineProcessing(realNo, orderNo, receiptNo, times, patientId, name, pharPracCertNo) {
  349. $("#sendDispose").attr("disabled", true);
  350. $("#sendDrug").attr("disabled", true);
  351. // 收集药品追溯码数据
  352. let tableData = $("#tb_table_right").bootstrapTable('getData');
  353. let drugTracCodgData = [];
  354. for (let i = 0; i < tableData.length; i++) {
  355. if (!isEmpty(tableData[i].drugTracCodg)) {
  356. drugTracCodgData.push({
  357. drugTracCodg: tableData[i].drugTracCodg,
  358. patientId: tableData[i].patientId,
  359. times: tableData[i].times,
  360. receiptNo: tableData[i].receiptNo,
  361. orderNo: tableData[i].orderNo,
  362. itemNo: tableData[i].itemNo,
  363. chargeItemCode: tableData[i].chargeItemCode,
  364. serial: tableData[i].serial,
  365. groupNo: tableData[i].groupNo,
  366. realNo: tableData[i].realNo,
  367. specification: tableData[i].specification,
  368. drugName: tableData[i].drugname,
  369. abbrName: tableData[i].abbrName,
  370. unitPrice: tableData[i].unitPrice,
  371. flag: '0'
  372. });
  373. }
  374. }
  375. var temp = {
  376. winNo: winNo,
  377. mzChargeDetail: {
  378. groupNo: groupNo,
  379. realNo: realNo,
  380. orderNo: orderNo,
  381. receiptNo: receiptNo,
  382. times: times,
  383. patientId: patientId,
  384. name: name,
  385. windowsNoYf: winNo
  386. },
  387. drugTracCodgList: drugTracCodgData // 添加药品追溯码数据
  388. };
  389. console.log("sendMedicineProcessing1111111111111",temp)
  390. $.ajax({
  391. type: "POST",
  392. url: '/thmz/sendMedicineProcessing',
  393. contentType: "application/json;charset=UTF-8",
  394. dataType: "json",
  395. headers: {'Accept': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("token")},
  396. data: JSON.stringify(temp),
  397. success: function (res) {
  398. $("#sendDispose").attr("disabled", false);
  399. $("#sendDrug").attr("disabled", false);
  400. if (res == '401' || res == 401) {
  401. window.location.href = '/thmz/login/view'
  402. return;
  403. }
  404. if (res.code == 0) {
  405. // 发药成功后,调用医保接口
  406. callYbSaleGoodsItem(realNo, orderNo, receiptNo, times, patientId, name, pharPracCertNo);
  407. successMesage(res);
  408. $('#cfxxModal').modal('hide');
  409. $("#patientId").val('');
  410. initTbTable($('#tb_table').bootstrapTable('getOptions').pageNumber);
  411. // 发药成功后打印处方
  412. printPrescription(patientId, times, orderNo)
  413. } else {
  414. errorMesage(res);
  415. }
  416. },
  417. error: function () {
  418. $("#sendDispose").attr("disabled", false);
  419. $("#sendDrug").attr("disabled", false);
  420. }
  421. });
  422. }
  423. /**
  424. * 查询处方信息
  425. */
  426. function initTbTable(pageIndex) {
  427. // sendRefundGroup: 0: 发药; 1: 退药
  428. var sendRefundGroup = getIndex("send_refund_group");
  429. var visible = false;
  430. var qrsjVisible = false;
  431. var tysjVisible = false;
  432. var url = "/thmz/getSendMedicinePrescription";
  433. if (sendRefundGroup == 1) {
  434. visible = true;
  435. if ($("#confirmFlagSearch").val() == 2) {
  436. qrsjVisible = true;
  437. } else {
  438. tysjVisible = true;
  439. }
  440. url = "/thmz/getYfRefundMedicine";
  441. $("#tb_table_div").attr("class", "col-md-7 col-sm-7 col-xs-12");
  442. } else {
  443. $("#tb_table_div").attr("class", "");
  444. }
  445. $('#tb_table').bootstrapTable("destroy");
  446. $('#tb_table').bootstrapTable({
  447. url: url, //请求后台的URL(*)
  448. method: 'post', //请求方式(*)
  449. striped: true, //是否显示行间隔色
  450. cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
  451. pagination: true, //是否显示分页(*)
  452. sortable: true, //是否启用排序
  453. sortOrder: "asc", //排序方式
  454. queryParams: queryParams, //传递参数(*)
  455. sidePagination: $("#confirmFlagSearch").val() == 0 ? 'client' : 'server', //分页方式:client客户端分页,server服务端分页(*)
  456. pageNumber: pageIndex || 1, //初始化加载第一页,默认第一页
  457. pageSize: 15, //每页的记录行数(*)
  458. pageList: [25, 50, 100], //可供选择的每页的行数(*)
  459. search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
  460. singleSelect: sendRefundGroup == 1 ? true : false, // 多选checkbox
  461. strictSearch: true,
  462. showColumns: false, //是否显示所有的列
  463. showRefresh: false, //是否显示刷新按钮
  464. minimumCountColumns: 2, //最少允许的列数
  465. clickToSelect: true, //是否启用点击选中行
  466. uniqueId: "ID", //每一行的唯一标识,一般为主键列
  467. showToggle: false, //是否显示详细视图和列表视图的切换按钮
  468. cardView: false, //是否显示详细视图
  469. detailView: false,
  470. //rowStyle:rowStyle,//通过自定义函数设置行样式
  471. ajaxOptions: {
  472. headers: {
  473. 'Accept': 'application/json',
  474. 'Authorization': 'Bearer ' + localStorage.getItem("token")
  475. }
  476. },
  477. columns: [
  478. {
  479. field: 'checked',
  480. checkbox: true,
  481. align: "center",
  482. valign: 'middle',
  483. //visible: visible,
  484. formatter: function (value, row, index) {
  485. if (index == 0 && sendRefundGroup == 1) {
  486. $("#return_total_amount").css("display", "");
  487. fitfymx(row.patientId, row.times, row.receiptNo, row.orderNo, row.groupNo);
  488. return {
  489. checked: true//设置选中
  490. };
  491. }
  492. }
  493. }, {
  494. title: '操作',
  495. align: "center",
  496. valign: 'middle',
  497. visible: !visible,
  498. formatter: function (value, row, index) {
  499. var str = "";
  500. if (sendRefundGroup == 0) {
  501. str = '<button type="button" class="btn btn-primary btn-sm" title="打印" onclick="printInjectionOralMedicine(\'' + row.patientId + '\',\'' + row.orderNo + '\',\'' + row.realNo + '\',\'' + row.times + '\',\'' + row.receiptNo + '\',\'' + row.confirmFlag + '\');" style="color: #35D082;">打印 <i class="fa fa-print"></i></button>';
  502. // if (yf.xyFlag === '1') {
  503. // str += '<button type="button" class="btn btn-primary btn-sm" title="叫号" onclick="callNumber(\'' + row.patientId + '\',\'' + row.name + '\')">叫号 <i class="glyphicon glyphicon-bullhorn"></i></button>';
  504. // }
  505. // if (row.confirmFlag == 5 || row.confirmFlag == 0) {
  506. // let pharPracCertNoForSend = (row.pharPracCertNo || '').replace(/'/g, '\\\'');
  507. // str += '<button type="button" class="btn btn-primary btn-sm" title="发药" id="sendDrug" onclick="sendMedicineProcessing(\'' + row.realNo + '\',\'' + row.orderNo + '\',\'' + row.receiptNo + '\',\'' + row.times + '\',\'' + row.patientId + '\',\'' + row.name + '\',\'' + pharPracCertNoForSend + '\')">发药 <i class="fa fa-check-square-o"></i></button>';
  508. // }
  509. let pharPracCertNo = (row.pharPracCertNo || '').replace(/'/g, '\\\'');
  510. str += '<button type="button" class="btn btn-primary btn-sm" title="详细" onclick="prescriptionDetail(\'' + row.realNo + '\',\'' + row.orderNo + '\',\'' + row.receiptNo + '\',\'' + row.times + '\',\'' + row.patientId + '\',\'' + row.confirmFlag + '\',\'' + pharPracCertNo + '\')">详细 <i class="fa fa-plus"></i></button>';
  511. str += '<button type="button" class="btn btn-primary btn-sm" title="历史处方" onclick="prescriptionHistoryDetail(\'' + row.patientId + '\',\'' + 0 +'\')">历史处方 <i class="fa fa-eye"></i></button>';
  512. str += '<button type="button" class="btn btn-primary btn-sm" title="打印处方" onclick="printPrescription(\'' + row.patientId + '\',\'' + row.times + '\',\'' + row.orderNo +'\')">打印处方 <i class="fa fa-print"></i></button>';
  513. }
  514. return str;
  515. }
  516. }, {
  517. title: '操作',
  518. align: "center",
  519. valign: 'middle',
  520. visible: visible,
  521. formatter: function (value, row, index) {
  522. return '<button type="button" class="btn btn-primary btn-sm" title="匹配" onclick="matchingDrugCodg(\'' + row.patientId + '\',\'' + row.times + '\',\'' + row.receiptNo + '\',\'' + row.orderNo + '\',\'' + row.realNo + '\');" style="color: #35D082;">匹配药品</button>';
  523. }
  524. }, {
  525. field: 'confirmFlag',
  526. title: '状态',
  527. align: "center",
  528. valign: 'middle',
  529. width: 80,
  530. formatter: function (value, row, index) {
  531. if(value == '5') {
  532. return "<div style='background: #087f5b'><span>已配药</span></div>";
  533. } else if(value == '1') {
  534. return "<div style='background: #4dabf7'><span>已发药</span></div>";
  535. } else if(value == '0') {
  536. if(row.printFlag == '1'){
  537. return "<div style='background: #c3d94e'><span>配药中</span></div>";
  538. }
  539. return "<div style='background: #f59f00'><span>待配药</span></div>";
  540. } else if(value == '3') {
  541. return "<div style='background: #868e96'><span>已取消</span></div>";
  542. }
  543. return "<div style='background: #d9480f'><span>其他</span></div>";
  544. }
  545. }, {
  546. field: 'pdStatus',
  547. title: '排队状态',
  548. align: "center",
  549. valign: 'middle',
  550. visible: !visible,
  551. width: 80,
  552. formatter: function (value, row, index) {
  553. if(value == '0') {
  554. return "<div style='background: #087f5b'><span>已排队</span></div>";
  555. } else if(row.confirmFlag == '1') {
  556. return "<div style='background: #4dabf7'><span>已完成</span></div>";
  557. } else {
  558. return "<div style='background: #d9480f'><span>未排队</span></div>";
  559. }
  560. }
  561. }, {
  562. field: 'pdSort',
  563. title: '排队序号',
  564. align: "center",
  565. valign: 'middle',
  566. visible: !visible,
  567. }, {
  568. field: 'patientId',
  569. title: '病人ID',
  570. align: "center",
  571. valign: 'middle'
  572. }, {
  573. field: 'name',
  574. title: '姓名',
  575. align: "center",
  576. valign: 'middle'
  577. // formatter: function (value, row, index) {
  578. // if (sendRefundGroup == 0) {
  579. // for (let i = 0; i < pastList.length; i++) {
  580. // if (pastList[i].patient_id == row.patientId) {
  581. // return (row.lineUp !== 10000 ? '<span class="number-name" style="background: red">&nbsp;' + row.lineUp + '&nbsp;</span>&nbsp;' : '') + '<span style="color: red">' + value + '</span>';
  582. // }
  583. // }
  584. // }
  585. // return (row.lineUp !== 10000 ? '<span class="number-name">&nbsp;' + row.lineUp + '&nbsp;</span>&nbsp;' : '') + value;
  586. // }
  587. }, {
  588. field: 'orderNo',
  589. title: '处方号',
  590. align: "center",
  591. valign: 'middle'
  592. }, {
  593. field: 'warnDeptName',
  594. title: '申请科室',
  595. align: "center",
  596. valign: 'middle',
  597. }, {
  598. field: 'employeeName',
  599. title: '医生',
  600. align: "center",
  601. valign: 'middle',
  602. formatter: function (value, row, index) {
  603. if (value == null) {
  604. return row.doctorName;
  605. }
  606. return value;
  607. }
  608. }, {
  609. field: 'chargeDate',
  610. title: '缴费日期',
  611. align: "center",
  612. valign: 'middle',
  613. formatter: function (value, row, index) {
  614. if (value != null && value != "") {
  615. return format(value, "yyyy-MM-dd HH:mm:ss");
  616. }
  617. return "";
  618. }
  619. }, {
  620. field: 'realNo',
  621. title: '流水号',
  622. align: "center",
  623. valign: 'middle',
  624. }, {
  625. field: 'confirmTime',
  626. title: '确认日期',
  627. align: "center",
  628. valign: 'middle',
  629. visible: qrsjVisible,
  630. formatter: function (value, row, index) {
  631. if (value != null && value != "") {
  632. return format(value, "yyyy-MM-dd HH:mm:ss");
  633. }
  634. return "";
  635. }
  636. }, {
  637. field: 'inputTime',
  638. title: '退药日期',
  639. align: "center",
  640. valign: 'middle',
  641. visible: tysjVisible,
  642. formatter: function (value, row, index) {
  643. if (value != null && value != "") {
  644. return format(value, "yyyy-MM-dd HH:mm:ss");
  645. }
  646. return "";
  647. }
  648. }
  649. ],
  650. onClickRow: function (row) {
  651. if (sendRefundGroup == 1) {
  652. fitfymx(row.patientId, row.times, row.receiptNo, row.orderNo, row.groupNo);
  653. }
  654. },
  655. onCheck: function (row) {
  656. if (sendRefundGroup == 1) {
  657. // 退药模式下,复选框选择时同步更新右侧显示内容
  658. fitfymx(row.patientId, row.times, row.receiptNo, row.orderNo, row.groupNo);
  659. }
  660. },
  661. onDblClickRow: function (row) {
  662. if (sendRefundGroup === 0 && yf.xyFlag === '1') {
  663. printInjectionOralMedicine(row.patientId, row.orderNo, row.realNo, row.times, row.receiptNo, row.confirmFlag);
  664. }
  665. // 打印处方
  666. printPrescription(row.patientId, row.times, row.orderNo)
  667. },
  668. responseHandler: function (res) {
  669. console.log(res);
  670. if (res == '401' || res == 401) {
  671. window.location.href = '/thmz/login/view'
  672. return;
  673. }
  674. var ress = eval(res);
  675. // let reverse = getLineUpData(ress.data);
  676. // $('#tb_table').bootstrapTable('load', reverse);
  677. if (ress.code == -1) {
  678. if (ress.message != null && ress.message != '') {
  679. new PNotify({
  680. title: '错误提示',
  681. text: ress.message,
  682. type: 'error',
  683. hide: true,
  684. styling: 'bootstrap3'
  685. });
  686. }
  687. return {
  688. "total": 0,//总页数
  689. "rows": {} //数据
  690. };
  691. }
  692. return {
  693. "total": ress.total,//总页数
  694. "rows": ress.data //数据
  695. };
  696. },
  697. });
  698. }
  699. /**
  700. * 加载放射科发药记录
  701. */
  702. function initRadiologyTable() {
  703. $('#rad_send_record_table').bootstrapTable("destroy");
  704. $('#rad_send_record_table').bootstrapTable({
  705. url: "/thmz/getRadSendRecord", //请求后台的URL(*)
  706. method: 'post', //请求方式(*)
  707. striped: true, //是否显示行间隔色
  708. cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
  709. pagination: true, //是否显示分页(*)
  710. sortable: true, //是否启用排序
  711. sortOrder: "asc", //排序方式
  712. queryParams: radSendRecordQueryParams, //传递参数(*)
  713. sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
  714. pageNumber: 1, //初始化加载第一页,默认第一页
  715. pageSize: 5, //每页的记录行数(*)
  716. pageList: [5], //可供选择的每页的行数(*)
  717. search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
  718. singleSelect: true, // 单选checkbox
  719. strictSearch: true,
  720. showColumns: false, //是否显示所有的列
  721. showRefresh: false, //是否显示刷新按钮
  722. minimumCountColumns: 2, //最少允许的列数
  723. clickToSelect: true, //是否启用点击选中行
  724. uniqueId: "ID", //每一行的唯一标识,一般为主键列
  725. showToggle: false, //是否显示详细视图和列表视图的切换按钮
  726. cardView: false, //是否显示详细视图
  727. detailView: false,
  728. paginationDetailHAlign: ' hidden',//隐藏左侧分页信息
  729. toolbar: '#rad_send_record_toolbar',
  730. //rowStyle:rowStyle,//通过自定义函数设置行样式
  731. ajaxOptions: {
  732. headers: {
  733. 'Accept': 'application/json',
  734. 'Authorization': 'Bearer ' + localStorage.getItem("token")
  735. }
  736. },
  737. columns: [
  738. {
  739. field: 'startDate',
  740. title: '起始时间',
  741. align: "center",
  742. valign: 'middle',
  743. formatter: function (value, row, index) {
  744. if (index == 0) {
  745. initRadiologyStatTable(row.sendDate);
  746. }
  747. if (value != null && value != "") {
  748. return format(value, "yyyy-MM-dd");
  749. }
  750. return "";
  751. }
  752. }, {
  753. field: 'endDate',
  754. title: '截止时间',
  755. align: "center",
  756. valign: 'middle',
  757. formatter: function (value, row, index) {
  758. if (index == 0) {
  759. initRadiologyStatTable(row.sendDate);
  760. }
  761. if (value != null && value != "") {
  762. return format(value, "yyyy-MM-dd");
  763. }
  764. return "";
  765. }
  766. }, {
  767. field: 'name',
  768. title: '发药人',
  769. align: "center",
  770. valign: 'middle'
  771. }, {
  772. field: 'sendDate',
  773. title: '发药时间',
  774. align: "center",
  775. valign: 'middle',
  776. formatter: function (value, row, index) {
  777. if (value != null && value != "") {
  778. return format(value, "yyyy-MM-dd");
  779. }
  780. return "-";
  781. }
  782. }
  783. , {
  784. title: '操作',
  785. align: "center",
  786. valign: 'middle',
  787. formatter: function (value, row, index) {
  788. row.sendDate = (row.sendDate == null) ? '' : row.sendDate;
  789. var str = '<button type="button" class="registration-no-color-foot-button" title="打印" onclick="printRadSendMedicineStat(\'' + row.sendDate + '\',\'' + row.startDate + '\',\'' + row.endDate + '\');" style="color: #35D082;background:#fff"><i class="fa fa-print"></i></button>';
  790. if (index == 0 && row.pageIndex == 0) {
  791. str += '<button type="button" class="registration-no-color-foot-button" title="发药" id="sendRad" onclick="sendMedicineProcessingRad()" style="background:#fff"><i class="fa fa-check-square-o"></i></button>';
  792. }
  793. return str;
  794. }
  795. }
  796. ],
  797. onClickRow: function (row) {
  798. initRadiologyStatTable(row.sendDate);
  799. },
  800. onDblClickRow: function (row) {
  801. printRadSendMedicineStat(row.sendDate, row.startDate, row.endDate);
  802. },
  803. responseHandler: function (res) {
  804. if (res == '401' || res == 401) {
  805. window.location.href = '/thmz/login/view'
  806. return;
  807. }
  808. var ress = eval(res);
  809. if (ress.code == -1) {
  810. if (ress.message != null && ress.message != '') {
  811. new PNotify({
  812. title: '错误提示',
  813. text: ress.message,
  814. type: 'error',
  815. hide: true,
  816. styling: 'bootstrap3'
  817. });
  818. }
  819. return {
  820. "total": 0,//总页数
  821. "rows": {} //数据
  822. };
  823. }
  824. return {
  825. "total": ress.total,//总页数
  826. "rows": ress.data //数据
  827. };
  828. },
  829. });
  830. $("#radiologySendModal").modal();
  831. }
  832. /**
  833. * 加载放射科发药统计表格数据
  834. * @param sendDate
  835. */
  836. function initRadiologyStatTable(sendDate) {
  837. sendDate = (sendDate == null) ? '' : sendDate;
  838. $('#rad_send_stat_table').bootstrapTable("destroy");
  839. $('#rad_send_stat_table').bootstrapTable({
  840. url: "/thmz/getRadSendStat?confirmTime=" + sendDate, //请求后台的URL(*)
  841. method: 'GET', //请求方式(*)
  842. striped: true, //是否显示行间隔色
  843. cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
  844. pagination: true, //是否显示分页(*)
  845. sortable: true, //是否启用排序
  846. sortOrder: "asc", //排序方式
  847. queryParams: {}, //传递参数(*)
  848. sidePagination: "client", //分页方式:client客户端分页,server服务端分页(*)
  849. pageNumber: 1, //初始化加载第一页,默认第一页
  850. pageSize: 10, //每页的记录行数(*)
  851. pageList: [10, 25, 50, 100], //可供选择的每页的行数(*)
  852. search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
  853. singleSelect: true, // 单选checkbox
  854. strictSearch: true,
  855. showColumns: false, //是否显示所有的列
  856. showRefresh: false, //是否显示刷新按钮
  857. minimumCountColumns: 2, //最少允许的列数
  858. clickToSelect: true, //是否启用点击选中行
  859. uniqueId: "ID", //每一行的唯一标识,一般为主键列
  860. showToggle: false, //是否显示详细视图和列表视图的切换按钮
  861. cardView: false, //是否显示详细视图
  862. detailView: false,
  863. paginationDetailHAlign: ' hidden',//隐藏左侧分页信息
  864. toolbar: '#rad_send_stat_toolbar',
  865. //rowStyle:rowStyle,//通过自定义函数设置行样式
  866. ajaxOptions: {
  867. headers: {
  868. 'Accept': 'application/json',
  869. 'Authorization': 'Bearer ' + localStorage.getItem("token")
  870. }
  871. },
  872. columns: [
  873. {
  874. field: 'location',
  875. title: '货位号',
  876. align: "center",
  877. valign: 'middle'
  878. }, {
  879. field: 'name',
  880. title: '品名',
  881. align: "center",
  882. valign: 'middle'
  883. }, {
  884. field: 'manuName',
  885. title: '厂商',
  886. align: "center",
  887. valign: 'middle'
  888. }, {
  889. field: 'specification',
  890. title: '规格',
  891. align: "center",
  892. valign: 'middle'
  893. }, {
  894. field: 'quantity',
  895. title: '<span style="color: green">数量</span>',
  896. align: "center",
  897. valign: 'middle',
  898. formatter: function (value, row, index) {
  899. return '<span style="color: green">' + value + '</span>'
  900. }
  901. }, {
  902. field: 'stockAmount',
  903. title: '库存',
  904. align: "center",
  905. valign: 'middle'
  906. }
  907. ],
  908. responseHandler: function (res) {
  909. if (res == '401' || res == 401) {
  910. window.location.href = '/thmz/login/view'
  911. return;
  912. }
  913. var ress = eval(res);
  914. if (ress.code == -1) {
  915. if (ress.message != null && ress.message != '') {
  916. new PNotify({
  917. title: '错误提示',
  918. text: ress.message,
  919. type: 'error',
  920. hide: true,
  921. styling: 'bootstrap3'
  922. });
  923. }
  924. return {
  925. "total": 0,//总页数
  926. "rows": {} //数据
  927. };
  928. }
  929. return {
  930. "total": ress.total,//总页数
  931. "rows": ress.data //数据
  932. };
  933. },
  934. });
  935. }
  936. /**
  937. * 放射科发药处理
  938. */
  939. function sendMedicineProcessingRad() {
  940. if (!confirm("确定要进行发药处理吗?")) {
  941. return;
  942. }
  943. $("#sendRad").attr("disabled", true);
  944. $.ajax({
  945. type: "GET",
  946. url: '/thmz/sendMedicineProcessingRad',
  947. contentType: "application/json;charset=UTF-8",
  948. dataType: "json",
  949. headers: {'Accept': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("token")},
  950. data: {},
  951. success: function (res) {
  952. $("#sendRad").attr("disabled", false);
  953. if (res == '401' || res == 401) {
  954. window.location.href = '/thmz/login/view'
  955. return;
  956. }
  957. if (res.code == 0) {
  958. successMesage(res);
  959. initRadiologyTable();
  960. } else {
  961. errorMesage(res);
  962. }
  963. },
  964. error: function () {
  965. $("#sendRad").attr("disabled", false);
  966. }
  967. });
  968. }
  969. /**
  970. * 打印注射卡口服药品
  971. */
  972. function printInjectionOralMedicine(patientId, orderNo, realNo, times, receiptNo, confirmFlag) {
  973. if (yf.xyFlag === '1') {
  974. prescriptionDetail(realNo, orderNo, receiptNo, times, patientId, confirmFlag);
  975. }
  976. var tem = {
  977. mzChargeDetail: {
  978. patientId: patientId,
  979. orderNo: orderNo,
  980. realNo: realNo,
  981. times: times,
  982. receiptNo: receiptNo,
  983. groupNo: groupNo,
  984. },
  985. autoCellNumber: $('#autoCellNumber').prop('checked') ? 1 : 0,
  986. winNo: winNo
  987. };
  988. $.ajax({
  989. type: "POST",
  990. url: '/thmz/getPrintInjectionData',
  991. contentType: "application/json;charset=UTF-8",
  992. dataType: "json",
  993. headers: {'Accept': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("token")},
  994. data: JSON.stringify(tem),
  995. success: function (res) {
  996. if (res == '401' || res == 401) {
  997. window.location.href = '/thmz/login/view'
  998. return;
  999. }
  1000. console.log(res);
  1001. if (res.code === 0) {
  1002. if (yf.zcyFlag === '1') {
  1003. zyfdy(res.data);
  1004. } else {
  1005. xyfdy(res);
  1006. successMesage(res);
  1007. }
  1008. } else {
  1009. errorMesage(res);
  1010. }
  1011. }
  1012. });
  1013. }
  1014. /**
  1015. * 中药房打印
  1016. * @param data
  1017. */
  1018. function zyfdy(data) {
  1019. $('#zydybqform')[0].reset();
  1020. if (bqPrintIndex == null) {
  1021. return errorMesageSimaple('未设置标签打印机,请在发药参数设置中设置');
  1022. }
  1023. $('#zydyNameLabel').val(data[0].name);
  1024. $('#sexLabel').val(getSex(data[0].sex));
  1025. $('#ageLabel').val(data[0].age);
  1026. $('#dyslLabel').val(data[0].drugWin*2);
  1027. $('#dateLabel').val(format(new Date(), "MM-dd"));
  1028. $('#zydybqModal').modal();
  1029. }
  1030. /**
  1031. * 西药房打印
  1032. */
  1033. function xyfdy(res) {
  1034. var injections = new Array();//注射液
  1035. var drugs = new Array();//普通药品
  1036. for (let i = 0; i < res.data.length; i++) {
  1037. if (res.data[i].classCode == 2 || res.data[i].classCode == 7) {//给药方式 2:输液、雾化吸入、副药等等 7:注射、皮试、副药等等
  1038. injections[injections.length] = res.data[i];
  1039. } else if (res.data[i].classCode != 6) {//给药方式 6:领药 9:外用、局麻、喷用等等
  1040. drugs[drugs.length] = res.data[i];
  1041. }
  1042. }
  1043. if (injections.length == 0 && drugs.length == 0) {
  1044. return errorMesageSimaple('当前处方,无需打印注射单和标签');
  1045. }
  1046. let age = getBirthSlot(res.data[0].birthDay, res.data[0].priceTime);
  1047. if (injections.length > 0) {
  1048. if (zsdPrintIndex == null) {
  1049. return errorMesageSimaple('未设置注射单打印机,请在发药参数设置中设置');
  1050. }
  1051. let injectionsPrint = {};
  1052. for (let i = 0; i < injections.length; i++) {
  1053. if(injectionsPrint['group' + injections[i].groupOrder]){
  1054. injectionsPrint['group' + injections[i].groupOrder].push(injections[i])
  1055. } else {
  1056. injectionsPrint['group' + injections[i].groupOrder] = [injections[i]]
  1057. }
  1058. }
  1059. console.log("injectionsPrint",injectionsPrint);
  1060. console.log("res.data",res.data)
  1061. LODOP = getLodop()
  1062. // LODOP.PRINT_INITA(6, 0, "210mm", "148mm", "铭和医院门、急诊注射单");
  1063. // LODOP.SET_PRINT_STYLE("FontSize", 9); //字体大小
  1064. LODOP.PRINT_INITA(6, 0, "80mm", "80mm", "铭和医院门、急诊注射单");
  1065. LODOP.SET_PRINT_STYLE("FontSize", 9); //字体大小
  1066. //设置默认打印机
  1067. LODOP.SET_PRINTER_INDEX(zsdPrintIndex);
  1068. // LODOP.SET_PRINT_PAGESIZE(1, '210mm', '148mm', "CreateCustomPage");
  1069. // LODOP.SET_SHOW_MODE("BKIMG_WIDTH", "210mm");
  1070. // LODOP.SET_SHOW_MODE("BKIMG_HEIGHT", "148mm");
  1071. LODOP.SET_PRINT_PAGESIZE(1, '80mm', '80mm', "CreateCustomPage");
  1072. LODOP.SET_PRINT_MODE('FULL_WIDTH_FOR_OVERFLOW', true) // 整宽不变形
  1073. LODOP.SET_SHOW_MODE("BKIMG_WIDTH", "80mm");
  1074. LODOP.SET_SHOW_MODE("BKIMG_HEIGHT", "80mm");
  1075. LODOP.SET_PRINT_MODE("CREATE_CUSTOM_PAGE_NAME", "铭和医院门、急诊注射单");//对新建的纸张重命名
  1076. // 匹配 "YYYY-MM-DD" 格式的前缀
  1077. const brithDate = res.data[0].birthDay.match(/^\d{4}-\d{2}-\d{2}/);
  1078. const formattedDate = brithDate ? brithDate[0] : '日期格式错误';
  1079. const keys = Object.keys(injectionsPrint); //
  1080. const groupLength = keys.length;
  1081. for(let key in injectionsPrint){
  1082. // console.log(key,injectionsPrint[key])
  1083. let currentGroup = injectionsPrint[key];
  1084. const groupIndex = keys.indexOf(key);
  1085. let printHtmlStart = `
  1086. <table border style="width:100%;border-collapse: collapse;">
  1087. <tr>
  1088. <!-- <td style="border : none"></td>-->
  1089. <!-- <td style="border : none"></td>-->
  1090. <td colspan="4">
  1091. <span style="text-align: center">${groupIndex + 1 + ' / ' + groupLength}</span>
  1092. </td>
  1093. <!-- <td style="border : none"></td>-->
  1094. <!-- <td style="border : none"></td>-->
  1095. <!-- <td rowspan="2"></td>-->
  1096. </tr>
  1097. <tr>
  1098. <td colspan="4">
  1099. <span style="margin-right: 30px">姓名: ${res.data[0].name} </span>
  1100. <span>生日: ${formattedDate}</span>
  1101. </td>
  1102. <!-- <td colspan="2"></td>-->
  1103. <!-- <td></td>-->
  1104. </tr>
  1105. <tr>
  1106. <td colspan="3" >药品名称与规格</td>
  1107. <td>用量</td>
  1108. </tr>
  1109. `
  1110. let printHtmlEnd = `
  1111. <tr>
  1112. <td style="border-bottom: none;border-top: 1px solid black;">
  1113. <span style="margin-right: 10px">就诊卡</span>
  1114. </td>
  1115. <td colspan="2" style="border-bottom: none;border-top: 1px solid black;text-align: left">
  1116. <span>${res.data[0].patientId}</span>
  1117. </td>
  1118. <td style="border-bottom: none;border-top: 1px solid black;">
  1119. </td>
  1120. <!-- <td rowspan="4"></td>-->
  1121. </tr>
  1122. <tr>
  1123. <td style="border-bottom: none">流速</td>
  1124. <td style="border-bottom: none"></td>
  1125. <td style="border-bottom: none">频率</td>
  1126. <td style="border-bottom: none">${currentGroup[0].frequency}</td>
  1127. </tr>
  1128. <tr>
  1129. <td style="border-bottom: none">配药时间</td>
  1130. <td style="border-bottom: none"></td>
  1131. <td style="border-bottom: none">配药</td>
  1132. <td style="border-bottom: none"></td>
  1133. </tr>
  1134. <tr>
  1135. <td style="border-bottom: none">审核</td>
  1136. <td style="border-bottom: none"></td>
  1137. <td style="border-bottom: none">执行</td>
  1138. <td style="border-bottom: none"></td>
  1139. </tr>
  1140. </table>
  1141. `
  1142. let printHtmlMiddle = ``;
  1143. injectionsPrint[key].forEach((item,index)=>{
  1144. printHtmlMiddle += `
  1145. <tr>
  1146. <td colspan="3" style="border-bottom: none">${item.drugname}</td>
  1147. <td style="border-bottom: none">${item.drugQuan + item.drugUnitName}</td>
  1148. </tr>
  1149. `
  1150. })
  1151. let printStyle = `<style>
  1152. td{
  1153. /*border:none;*/
  1154. width: 25%;
  1155. font-size: 15px;padding: 2px;
  1156. text-align:center;
  1157. border-bottom: 1px solid black
  1158. }
  1159. tr{
  1160. /*border-bottom: 1px solid black !important; !* 强制生效 *!*/
  1161. }
  1162. /* 最后一行可去掉边框(可选) */
  1163. tr:last-child {
  1164. /*border-bottom: none;*/
  1165. }
  1166. </style>`
  1167. let printHtml = printStyle + printHtmlStart + printHtmlMiddle + printHtmlEnd;
  1168. // console.log("printHtml",printHtml);
  1169. LODOP.ADD_PRINT_HTM(0, 0, "100%", "100%", printHtml);
  1170. LODOP.NewPage()
  1171. }
  1172. // for (let i = 0; i < injectionsPrint.length; i++) {
  1173. // console.log("injectionsPrint[i]",injectionsPrint[i])
  1174. // let printHtml = `
  1175. // <table border="1" cellpadding="0" cellspacing="0" style="width:100%;">
  1176. // <tr>
  1177. // <td colspan="2" style="text-align:center;">
  1178. // <span>${i+1}/${injectionsPrint[i].length}</span>
  1179. // <span style="float:right;">0001</span>
  1180. // </td>
  1181. // </tr>
  1182. // </table>
  1183. // `
  1184. // console.log("printHtml",printHtml);
  1185. // LODOP.ADD_PRINT_HTM(0, 0, "100%", "100%", printHtml);
  1186. // // LODOP.NewPage()
  1187. // }
  1188. LODOP.PREVIEW()
  1189. // LODOP.PRINT();
  1190. }
  1191. //setPrint();
  1192. // if (injections.length > 0) {
  1193. // if (zsdPrintIndex == null) {
  1194. // return errorMesageSimaple('未设置注射单打印机,请在发药参数设置中设置');
  1195. // }
  1196. // $(".zsd_two_tr").remove();
  1197. // $(".zsd_one_tr_1").remove();
  1198. // $(".zsd_one_tr_2").remove();
  1199. // var patientInfoHtm = '<tr class="R">\n' +
  1200. // ' <td style="vertical-align: middle !important;width: 75px;text-align: center;"\n' +
  1201. // ' valign="top">姓名\n' +
  1202. // ' </td>\n' +
  1203. // ' <td style="vertical-align: middle !important;width: 100px;">\n' + res.data[0].name +
  1204. // ' </td>\n' +
  1205. // ' <td style="vertical-align: middle !important;width: 75px;text-align: center;">\n' +
  1206. // ' 性别\n' +
  1207. // ' </td>\n' +
  1208. // ' <td style="vertical-align: middle !important;width: 100px;text-align: left;">\n' + getSex(res.data[0].sex) +
  1209. // ' </td>\n' +
  1210. // ' <td style="vertical-align: middle !important;width: 75px;text-align: center;">\n' +
  1211. // ' 年龄\n' +
  1212. // ' </td>\n' +
  1213. // ' <td style="vertical-align: middle !important;width: 100px;text-align: left;">\n' + age +
  1214. // ' </td>\n' +
  1215. // ' <td style="vertical-align: middle !important;width: 75px;text-align: center;">\n' +
  1216. // ' ID号\n' +
  1217. // ' </td>\n' +
  1218. // ' <td style="vertical-align: middle !important;width: 100px;text-align: left;">\n' + res.data[0].patientId +
  1219. // ' </td>\n' +
  1220. // ' </tr>\n' +
  1221. // ' <tr class="zsd_one_tr_2">\n' +
  1222. // ' <td style="vertical-align: middle !important;width: 75px;text-align: center;">\n' +
  1223. // ' 医生\n' +
  1224. // ' </td>\n' +
  1225. // ' <td style="vertical-align: middle !important;width: 100px;text-align: left;">\n' + res.data[0].employeeName +
  1226. // ' </td>\n' +
  1227. // ' <td style="vertical-align: middle !important;width: 75px;text-align: center;">\n' +
  1228. // ' 诊断\n' +
  1229. // ' </td>\n' +
  1230. // ' <td colspan="5" style="vertical-align: middle !important;width: 250px;text-align: left;">\n' + res.data[0].icdText +
  1231. // ' </td>\n' +
  1232. // ' </tr>';
  1233. // $(".zsd_yp_tr").remove();
  1234. // $("#dateTime").html(format(new Date(), "yyyy-MM-dd HH:mm:ss"));
  1235. // $('#zsd_one').prepend(patientInfoHtm);
  1236. // var zsdYpHtm = '';
  1237. // for (let i = 0; i < injections.length; i++) {
  1238. // let data = injections[i];
  1239. // let manufactoryName = (data.manufactoryName == null || data.manufactoryName == '') ? '' : '(' + data.manufactoryName + ')';
  1240. // let groupOrder = (data.groupOrder == '' || data.groupOrder == null) ? data.chargeItemCode : data.groupOrder;
  1241. // let psFlag = '';
  1242. // if (data.groupOrder != '' || data.groupOrder != null) {
  1243. // for (let j = 0; j < injections.length; j++) {
  1244. // if (groupOrder === injections[j].groupOrder && injections[j].tryFlag === '1') {
  1245. // psFlag = '(需皮试)';
  1246. // break
  1247. // }
  1248. // }
  1249. // }
  1250. // zsdYpHtm += '<tr class="zsd_yp_tr">\n' +
  1251. // ' <td>&nbsp;&nbsp;</td>\n' +
  1252. // ' <td style="vertical-align: middle !important;width: 10px;text-align: center;">\n' + groupOrder +
  1253. // ' </td>\n' +
  1254. // ' <td style="vertical-align: middle !important;width: 200px;text-align: left;">\n' + data.drugname + manufactoryName +
  1255. // ' </td>\n' +
  1256. // ' <td style="vertical-align: middle !important;width: 60px;text-align: center;">\n' + data.drugQuan +
  1257. // ' </td>\n' +
  1258. // ' <td style="vertical-align: middle !important;width: 60px;text-align: center;">\n' + data.drugUnitName +
  1259. // ' </td>\n' +
  1260. // ' <td style="vertical-align: middle !important;width: 130px;text-align: left;">\n' + data.printName + psFlag +
  1261. // ' </td>\n' +
  1262. // ' <td style="vertical-align: middle !important;width: 60px;text-align: center;">\n' + data.frequency +
  1263. // ' </td>\n' +
  1264. // ' <td style="vertical-align: middle !important;width: 60px;text-align: center;">\n' + data.orderDays +
  1265. // ' </td>\n' +
  1266. // ' <td style="vertical-align: middle !important;width: 120px;text-align: left;">\n' + data.specification +
  1267. // ' </td>\n' +
  1268. // ' </tr>';
  1269. // }
  1270. // $('#zsd_yp').append(zsdYpHtm);
  1271. // var htm = '';
  1272. // for (let i = 0; i < 14; i++) {
  1273. // htm += '<tr class="zsd_two_tr">\n' +
  1274. // ' <td style="vertical-align: middle !important;width: 30px;text-align: center;">&nbsp;&nbsp;月&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;日</td>\n' +
  1275. // ' <td style="vertical-align: middle !important;width: 30px;text-align: right;"></td>\n' +
  1276. // ' <td style="vertical-align: middle !important;width: 30px;text-align: right;"></td>\n' +
  1277. // ' <td style="vertical-align: middle !important;width: 30px;text-align: right;"></td>\n' +
  1278. // ' <td style="vertical-align: middle !important;width: 30px;text-align: right;"></td>\n' +
  1279. // // ' <td style="vertical-align: middle !important;width: 30px;text-align: center;">&nbsp;&nbsp;月&nbsp;&nbsp;日</td>\n' +
  1280. // // ' <td style="vertical-align: middle !important;width: 30px;text-align: right;"></td>\n' +
  1281. // // ' <td style="vertical-align: middle !important;width: 30px;text-align: right;"></td>\n' +
  1282. // // ' <td style="vertical-align: middle !important;width: 30px;text-align: right;"></td>\n' +
  1283. // // ' <td style="vertical-align: middle !important;width: 30px;text-align: right;"></td>\n' +
  1284. // ' </tr>';
  1285. // }
  1286. // $('#zsd_two').append(htm);
  1287. // LODOP = getLodop();
  1288. // // LODOP.PRINT_INITA(6, 0, "210mm", "148mm", "铭和医院门、急诊注射单");
  1289. // // LODOP.SET_PRINT_STYLE("FontSize", 9); //字体大小
  1290. // LODOP.PRINT_INITA(6, 0, "140mm", "202mm", "铭和医院门、急诊注射单");
  1291. // LODOP.SET_PRINT_STYLE("FontSize", 9); //字体大小
  1292. // //设置默认打印机
  1293. // LODOP.SET_PRINTER_INDEX(zsdPrintIndex);
  1294. // // LODOP.SET_PRINT_PAGESIZE(1, '210mm', '148mm', "CreateCustomPage");
  1295. // // LODOP.SET_SHOW_MODE("BKIMG_WIDTH", "210mm");
  1296. // // LODOP.SET_SHOW_MODE("BKIMG_HEIGHT", "148mm");
  1297. // LODOP.SET_PRINT_PAGESIZE(1, '140mm', '202mm', "CreateCustomPage");
  1298. // LODOP.SET_PRINT_MODE('FULL_WIDTH_FOR_OVERFLOW', true) // 整宽不变形
  1299. // LODOP.SET_SHOW_MODE("BKIMG_WIDTH", "140mm");
  1300. // LODOP.SET_SHOW_MODE("BKIMG_HEIGHT", "202mm");
  1301. // LODOP.SET_PRINT_MODE("CREATE_CUSTOM_PAGE_NAME", "铭和医院门、急诊注射单");//对新建的纸张重命名
  1302. // // LODOP.ADD_PRINT_HTM("5mm", "3mm", "210mm", "148mm", $("div[id='print_view_zsd']").html());
  1303. // LODOP.ADD_PRINT_HTM("2mm", "4mm", "140mm", "202mm", $("div[id='print_view_zsd']").html());
  1304. // LODOP.PREVIEW();
  1305. // //LODOP.PREVIEW();
  1306. // }
  1307. if (drugs.length > 0) {
  1308. if (bqPrintIndex == null) {
  1309. return errorMesageSimaple('未设置标签打印机,请在发药参数设置中设置');
  1310. }
  1311. LODOP = null;
  1312. LODOP = getLodop();
  1313. LODOP.PRINT_INITA(6, 0, "80mm", "60mm", "患者药品标签");
  1314. LODOP.SET_PRINT_STYLE("FontSize", 9); //字体大小
  1315. //设置默认打印机
  1316. LODOP.SET_PRINTER_INDEX(bqPrintIndex);
  1317. LODOP.SET_PRINT_PAGESIZE(1, '80mm', '60mm', "CreateCustomPage");
  1318. LODOP.SET_SHOW_MODE("BKIMG_WIDTH", "80mm");
  1319. LODOP.SET_SHOW_MODE("BKIMG_HEIGHT", "60mm");
  1320. LODOP.SET_PRINT_MODE("CREATE_CUSTOM_PAGE_NAME", "患者药品标签");//对新建的纸张重命名
  1321. for (let j = 0; j < drugs.length; j++) {
  1322. for (var key in drugs[j]) {
  1323. $("#ypbq_" + key + "").attr("value", drugs[j][key]);
  1324. $("#ypbq_quantity").attr("value", parseInt(drugs[j]['quantity']));
  1325. }
  1326. $("#dataTime").attr("value", format(new Date(), "yyyy-MM-dd HH:mm"));
  1327. $("#ypbq_sex").attr("value", getSex(drugs[0].sex));
  1328. $("#ypbq_age").attr("value", age);
  1329. $("#NO").attr("value", j + 1 + "/" + drugs.length);
  1330. //用法
  1331. let yf = drugs[j].printName + ',';
  1332. if (drugs[j].drugUnitName == '粒' || drugs[j].drugUnitName == '片' || drugs[j].drugUnitName == '支' || drugs[j].drugUnitName == '袋' || drugs[j].drugUnitName == '包' || drugs[j].drugUnitName == '丸') {
  1333. $("#ypbq_comm").attr("value", yf + drugs[j].comm + ',每次' + (drugs[j].drugQuan == 0.5 ? '半' : drugs[j].drugQuan) + drugs[j].drugUnitName);
  1334. } else if ((drugs[j].weight == null && drugs[j].volum == null) || (drugs[j].weight != null && drugs[j].volum != null)) {
  1335. $("#ypbq_comm").attr("value", yf + drugs[j].comm + ',每次' + drugs[j].drugQuan + drugs[j].drugUnitName);
  1336. } else {
  1337. let weight = (drugs[j].weight == '' || drugs[j].weight == null) ? drugs[j].volum : drugs[j].weight;
  1338. var drugQuan = (drugs[j].drugQuan / weight).toFixed(2);
  1339. if (drugQuan == 0.5) {
  1340. $("#ypbq_comm").attr("value", yf + drugs[j].comm + ',每次半' + drugs[j].miniUnitName);
  1341. } else if (drugQuan < 1) {
  1342. $("#ypbq_comm").attr("value", yf + drugs[j].comm + ',每次' + drugs[j].drugQuan + drugs[j].drugUnitName);
  1343. } else {
  1344. drugQuan = Math.round(drugQuan * 100) / 100;
  1345. $("#ypbq_comm").attr("value", yf + drugs[j].comm + ',每次' + drugQuan + drugs[j].miniUnitName);
  1346. }
  1347. }
  1348. LODOP.ADD_PRINT_HTM("5mm", "2mm", "80mm", "60mm", $("div[id='print_view_bq']").html());
  1349. LODOP.NewPage();//下一页
  1350. }
  1351. LODOP.PREVIEW();
  1352. // LODOP.PRINT();
  1353. }
  1354. }
  1355. /**
  1356. * 打印放射科发药药品统计
  1357. */
  1358. function printRadSendMedicineStat(sendDate, startDate, endDate) {
  1359. $.ajax({
  1360. type: "GET",
  1361. url: "/thmz/getPrintRadSendStat?confirmTime=" + sendDate, //请求后台的URL(*)
  1362. contentType: "application/json;charset=UTF-8",
  1363. dataType: "json",
  1364. headers: {'Accept': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("token")},
  1365. data: {},
  1366. success: function (res) {
  1367. if (res == '401' || res == 401) {
  1368. window.location.href = '/thmz/login/view'
  1369. return;
  1370. }
  1371. if (res.code == 0) {
  1372. var list = res.data;
  1373. if (list.length == 0) {
  1374. return errorMesageSimaple('当前记录无发药药品统计数据');
  1375. }
  1376. if (fskPrintIndex == null) {
  1377. return errorMesageSimaple('未设置放射科发药清单打印机,请在发药参数设置中设置');
  1378. }
  1379. $(".fsk_tr").remove();
  1380. var htm = '';
  1381. for (let i = 0; i < list.length; i++) {
  1382. var data = list[i];
  1383. htm += '<tr class="fsk_tr">' +
  1384. ' <td style="vertical-align: middle !important;width: 30px;text-align: center;">' + (data.location == null ? '-' : data.location) +
  1385. ' </td>' +
  1386. ' <td style="vertical-align: middle !important;width: 30px;text-align: center;">' + data.name +
  1387. ' </td>' +
  1388. ' <td style="vertical-align: middle !important;width: 30px;text-align: center;">' + data.manuName +
  1389. ' </td>' +
  1390. ' <td style="vertical-align: middle !important;width: 30px;text-align: center;">' + data.specification +
  1391. ' </td>' +
  1392. ' <td style="vertical-align: middle !important;width: 30px;text-align: center;">' + data.quantity +
  1393. ' </td>' +
  1394. ' </tr>';
  1395. }
  1396. $('#fsk_tbody').append(htm);
  1397. $('#startDate').html(format(startDate, "yyyy-MM-dd"));
  1398. $('#endDate').html(format(endDate, "yyyy-MM-dd"));
  1399. //setPrint();
  1400. LODOP = getLodop();
  1401. LODOP.PRINT_INITA(6, 0, "241mm", "93.3mm", "放射科发药记录单");
  1402. LODOP.SET_PRINT_STYLE("FontSize", 9); //字体大小
  1403. //设置默认打印机
  1404. LODOP.SET_PRINTER_INDEX(fskPrintIndex);
  1405. LODOP.SET_PRINT_PAGESIZE(1, '241mm', '93.3mm', "CreateCustomPage");
  1406. LODOP.SET_SHOW_MODE("BKIMG_WIDTH", "241mm");
  1407. LODOP.SET_SHOW_MODE("BKIMG_HEIGHT", "93.3mm");
  1408. LODOP.SET_PRINT_MODE("CREATE_CUSTOM_PAGE_NAME", "放射科发药记录单");//对新建的纸张重命名
  1409. LODOP.ADD_PRINT_HTM("5mm", "20%", "60%", "93.3mm", $("div[id='print_view_fsk']").html());
  1410. LODOP.PREVIEW();
  1411. //LODOP.PREVIEW();
  1412. successMesage(res);
  1413. } else {
  1414. errorMesage(res);
  1415. }
  1416. }
  1417. });
  1418. }
  1419. /**
  1420. * 已发药和未发药记录构建列表查询参数
  1421. * @param params
  1422. */
  1423. function queryParams(params) {
  1424. var rePortRangeArr = getRePortRangeArr();
  1425. let warnDept;
  1426. if ($("#unitCode").val() == null) {
  1427. warnDept = null;
  1428. } else {
  1429. warnDept = $("#unitCode").val()[0]
  1430. }
  1431. var temp = {
  1432. pageSize: params.limit, //页面大小
  1433. pageIndex: params.offset / params.limit, //页码
  1434. beginDate: rePortRangeArr[0],
  1435. endDate: rePortRangeArr[1],
  1436. name: $("#nameSearch").val() == "" ? null : $("#nameSearch").val(),
  1437. patientId: $("#patientId").val() == "" ? null : $("#patientId").val(),
  1438. confirmFlag: $("#confirmFlagSearch").val(),
  1439. realNo: $("#realNoSearch").val() == "" ? null : $("#realNoSearch").val(),
  1440. warnDept: warnDept,
  1441. groupNoOut: groupNo,
  1442. winNo: winNo,
  1443. isSendAndMatch: 1,
  1444. sortType: $("#sortType option:selected").val()
  1445. };
  1446. return temp;
  1447. };
  1448. /**
  1449. * 放射科发药记录构建列表查询参数
  1450. * @param params
  1451. */
  1452. function radSendRecordQueryParams(params) {
  1453. var temp = {
  1454. pageSize: params.limit, //页面大小
  1455. pageIndex: params.offset / params.limit //页码
  1456. };
  1457. return temp;
  1458. };
  1459. /**
  1460. * 获取时间选择器的时间数组
  1461. * @returns {string[]}
  1462. */
  1463. function getRePortRangeArr() {
  1464. var rePortRange = $('#reportrange span').html();
  1465. var rePortRangeArr = rePortRange.split(" - ");
  1466. rePortRangeArr[0] = rePortRangeArr[0] + " 00:00:00"
  1467. rePortRangeArr[1] = rePortRangeArr[1] + " 23:59:59"
  1468. return rePortRangeArr;
  1469. }
  1470. /**
  1471. * 清空查询条件
  1472. */
  1473. function cleanParams() {
  1474. $('#reportrange span').html(moment().format('YYYY-MM-DD') + ' - ' + moment().format('YYYY-MM-DD'));
  1475. $("#nameSearch").val('');
  1476. $("#patientId_or_cardNo").val('');
  1477. $("#patientId").val('');
  1478. $("#realNoSearch").val('');
  1479. $("#unitCode").html('');
  1480. $("#unitCode").selectpicker('refresh');
  1481. var sendRefundGroup = getIndex("send_refund_group");
  1482. sendRefundGroup == 0 ? $("#confirmFlagSearch").selectpicker('val', 0) : $("#confirmFlagSearch").selectpicker('val', 2);
  1483. $("#confirmFlagSearch").selectpicker('refresh');
  1484. $("#patientId_or_cardNo").focus();
  1485. }
  1486. /**
  1487. * 查询病人处方明细
  1488. */
  1489. var $table;
  1490. function prescriptionDetail(realNo, orderNo, receiptNo, times, patientId, confirmFlag, pharPracCertNo) {
  1491. // 设置全局变量,供发药按钮使用
  1492. window.currentPharPracCertNo = pharPracCertNo || '';
  1493. let isXy = yf.xyFlag === '1';
  1494. if (confirmFlag == 5 || confirmFlag == 0) {
  1495. $("#sendDispose").show();//显示
  1496. } else {
  1497. $("#sendDispose").hide();//隐藏
  1498. }
  1499. var temp = {
  1500. groupNo: groupNo,
  1501. realNo: realNo,
  1502. orderNo: orderNo,
  1503. receiptNo: receiptNo,
  1504. times: times,
  1505. patientId: patientId
  1506. };
  1507. $('#tb_table_right').bootstrapTable("destroy");
  1508. $('#tb_table_allergen').bootstrapTable("destroy");
  1509. $table = $('#tb_table_right').bootstrapTable({
  1510. url: '/thmz/getFyclPrescriptionDetail', //请求后台的URL(*)
  1511. method: 'POST', //请求方式(*)
  1512. striped: true, //是否显示行间隔色
  1513. cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
  1514. pagination: true, //是否显示分页(*)
  1515. sortable: true, //是否启用排序
  1516. sortOrder: "asc", //排序方式
  1517. queryParams: JSON.stringify(temp), //传递参数(*)
  1518. sidePagination: "client", //分页方式:client客户端分页,server服务端分页(*)
  1519. pageNumber: 1, //初始化加载第一页,默认第一页
  1520. pageSize: 10, //每页的记录行数(*)
  1521. pageList: [10, 25, 50, 100], //可供选择的每页的行数(*)
  1522. search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
  1523. strictSearch: true,
  1524. showColumns: false, //是否显示所有的列
  1525. showRefresh: false, //是否显示刷新按钮
  1526. minimumCountColumns: 2, //最少允许的列数
  1527. clickToSelect: true, //是否启用点击选中行
  1528. uniqueId: "ID", //每一行的唯一标识,一般为主键列
  1529. showToggle: false, //是否显示详细视图和列表视图的切换按钮
  1530. cardView: false, //是否显示详细视图
  1531. detailView: false,
  1532. //rowStyle:rowStyle,//通过自定义函数设置行样式
  1533. ajaxOptions: {
  1534. headers: {
  1535. 'Accept': 'application/json',
  1536. 'Authorization': 'Bearer ' + localStorage.getItem("token")
  1537. }
  1538. },
  1539. columns: [
  1540. {
  1541. field: 'manuNo',
  1542. title: '批号',
  1543. align: "center",
  1544. valign: 'middle'
  1545. },{
  1546. field: 'location',
  1547. title: '货位号',
  1548. align: "center",
  1549. valign: 'middle'
  1550. }, {
  1551. field: 'drugname',
  1552. title: '品名',
  1553. align: "center",
  1554. valign: 'middle',
  1555. }, {
  1556. field: 'specification',
  1557. title: '规格',
  1558. align: "center",
  1559. valign: 'middle',
  1560. }, {
  1561. field: 'quantity',
  1562. title: '<span style="color: green">数量</span>',
  1563. align: "center",
  1564. valign: 'middle',
  1565. formatter: function (value, row, index) {
  1566. return '<span style="color: green">' + value + '</span>'
  1567. }
  1568. }, {
  1569. field: 'ypUnitName',
  1570. title: '单位',
  1571. align: "center",
  1572. valign: 'middle',
  1573. }, {
  1574. field: 'mdtrtSetlType',
  1575. title: '结算类型',
  1576. align: "center",
  1577. valign: 'middle',
  1578. width: 80,
  1579. formatter: function (value, row, index) {
  1580. // 根据处方类型判断:普通处方(1)、特门处方(3)、GCP实验(4)为自费,门诊统筹(2)为医保
  1581. if (value == 1) {
  1582. return '<span style="color: #007bff; font-weight: bold;">医保</span>';
  1583. } else {
  1584. return '<span style="color: #28a745; font-weight: bold;">自费</span>';
  1585. }
  1586. }
  1587. }, {
  1588. field: 'serial',
  1589. title: '拆零状态',
  1590. align: "center",
  1591. valign: 'middle',
  1592. width: 80,
  1593. formatter: function (value, row, index) {
  1594. if (value === '01') {
  1595. return '<span style="color: #dc3545; font-weight: bold;">拆零</span>';
  1596. } else if (value === '99') {
  1597. return '<span style="color: #6c757d;">不拆零</span>';
  1598. } else {
  1599. return '<span style="color: #6c757d;">-</span>';
  1600. }
  1601. }
  1602. }, {
  1603. field: 'drugTracCodg',
  1604. title: '药品追溯码',
  1605. width: '270',
  1606. align: "left",
  1607. valign: 'middle',
  1608. formatter: function (value, row, index) {
  1609. return isEmpty(value)?'':value
  1610. }
  1611. }, {
  1612. field: 'abbrName',
  1613. title: '生产厂家',
  1614. align: "center",
  1615. valign: 'middle',
  1616. visible: isXy
  1617. }, {
  1618. field: 'drugQuan',
  1619. title: '一次剂量',
  1620. align: "center",
  1621. valign: 'middle',
  1622. }, {
  1623. field: 'drugUnitName',
  1624. title: '单位',
  1625. align: "center",
  1626. valign: 'middle',
  1627. }, {
  1628. field: 'frequency',
  1629. title: '频率',
  1630. align: "center",
  1631. valign: 'middle',
  1632. visible: isXy
  1633. }, {
  1634. field: 'decAmount',
  1635. title: '<span style="color: red">退药量</span>',
  1636. align: "center",
  1637. valign: 'middle',
  1638. formatter: function (value, row, index) {
  1639. return value == null ? '<span style="color: red">-</span>' : '<span style="color: red">' + value + '</span>'
  1640. }
  1641. }, {
  1642. field: 'printName',
  1643. title: '给药方式',
  1644. align: "center",
  1645. valign: 'middle',
  1646. visible: isXy
  1647. }, {
  1648. field: 'unitPrice',
  1649. title: '单价',
  1650. align: "center",
  1651. valign: 'middle',
  1652. }
  1653. , {
  1654. field: 'drugFlag',//毒麻标志:1:毒;2:麻;3:精神1;4:精神2
  1655. title: '<span style="color: red">毒麻</span>',
  1656. align: "center",
  1657. valign: 'middle',
  1658. formatter: function (value, row, index) {
  1659. if (value == 1) {
  1660. return '<span style="color: red">毒</span>'
  1661. } else if (value == 2) {
  1662. return '<span style="color: red">麻</span>'
  1663. } else if (value == 3) {
  1664. return '<span style="color: red">精神1</span>'
  1665. } else if (value == 4) {
  1666. return '<span style="color: red">精神2</span>'
  1667. } else {
  1668. return '<span style="color: red">-</span>'
  1669. }
  1670. }
  1671. }
  1672. , {
  1673. field: 'stockAmount',
  1674. title: '当前库存',
  1675. align: "center",
  1676. valign: 'middle',
  1677. }
  1678. , {
  1679. field: 'drugWin',
  1680. title: '副数',
  1681. align: "center",
  1682. valign: 'middle',
  1683. visible: !isXy
  1684. }
  1685. , {
  1686. field: 'nationalCode',
  1687. title: '医保编码',
  1688. align: ";left",
  1689. valign: 'middle',
  1690. formatter: function (value, row, index) {
  1691. return value == null ? "-" : value;
  1692. }
  1693. }
  1694. , {
  1695. field: 'employeeName',
  1696. title: '医生姓名',
  1697. visible: false // 隐藏列,仅用于数据传递
  1698. }, {
  1699. field: 'drugKind',
  1700. title: '药品类别',
  1701. align: "center",
  1702. valign: 'middle',
  1703. visible: false, // 隐藏列,不显示给用户
  1704. formatter: function (value, row, index) {
  1705. return value || '-';
  1706. }
  1707. }
  1708. ],
  1709. /**
  1710. * @param {点击列的 field 名称} field
  1711. * @param {点击列的 value 值} value
  1712. * @param {点击列的整行数据} row
  1713. * @param {td 元素} $element
  1714. */
  1715. // onClickCell: function (field, value, row, $element) {
  1716. // if (field === 'drugTracCodg') {
  1717. // $element.attr('contenteditable', true);
  1718. // $element.focus();
  1719. // $element.blur(function () {
  1720. // let index = $element.parent().data('index');
  1721. // let tdValue = $element.html();
  1722. // saveCellData($('#tb_table_right'), index, field, tdValue);
  1723. // })
  1724. // }
  1725. // },
  1726. onClickCell: function (field, value, row, $element) {
  1727. if (field === 'drugTracCodg') {
  1728. $element.attr('contenteditable', true);
  1729. $element.focus();
  1730. // 添加扫码输入监听(带防抖)
  1731. let inputTimer = null;
  1732. let lastInputValue = '';
  1733. $element.off('input.scan').on('input.scan', function(e) {
  1734. // 使用innerHTML获取包含<br>的完整内容
  1735. let inputValue = e.target.innerHTML;
  1736. console.log('扫码输入事件触发,输入值:', inputValue);
  1737. console.log('输入值长度:', inputValue ? inputValue.length : 0);
  1738. console.log('输入值是否包含<br>:', inputValue ? inputValue.includes('<br>') : false);
  1739. // 清除之前的定时器
  1740. if (inputTimer) {
  1741. clearTimeout(inputTimer);
  1742. }
  1743. // 设置防抖定时器,0.5秒后触发验证
  1744. inputTimer = setTimeout(function() {
  1745. if (inputValue && inputValue.length > 0) {
  1746. // 直接按<br>分割,获取所有追溯码
  1747. let codes = inputValue.split('<br>').filter(code => code.length > 0);
  1748. console.log('分割后的追溯码列表:', codes);
  1749. // 检查最后一个追溯码是否为20位或以上
  1750. if (codes.length > 0) {
  1751. let lastCode = codes[codes.length - 1];
  1752. console.log('最后一个追溯码:', lastCode);
  1753. console.log('最后一个追溯码长度:', lastCode.length);
  1754. if (lastCode.length >= 20) {
  1755. console.log('防抖触发,准备验证追溯码:', lastCode);
  1756. // 验证最后一个完整的追溯码
  1757. validateAndAddTracCodg(lastCode, row, $element);
  1758. } else {
  1759. console.log('最后一个追溯码长度不正确,不进行验证:', lastCode.length);
  1760. // 添加报错提示
  1761. errorMesageSimaple('追溯码长度不正确,应为20位或以上,当前为' + lastCode.length + '位');
  1762. // 去掉长度不正确的追溯码
  1763. codes.pop();
  1764. // 重新设置单元格内容
  1765. let newContent = codes.join('<br>');
  1766. if (newContent) {
  1767. newContent += '<br>';
  1768. }
  1769. $element.html(newContent);
  1770. // 保持焦点在单元格末尾,让用户可以继续扫码
  1771. $element.focus();
  1772. // 将光标移动到内容末尾
  1773. let range = document.createRange();
  1774. let selection = window.getSelection();
  1775. range.selectNodeContents($element[0]);
  1776. range.collapse(false); // false表示移动到末尾
  1777. selection.removeAllRanges();
  1778. selection.addRange(range);
  1779. }
  1780. } else {
  1781. console.log('没有找到有效的追溯码');
  1782. }
  1783. }
  1784. }, 500);
  1785. });
  1786. // 保持原有的失去焦点保存逻辑
  1787. $element.off('blur.save').on('blur.save', function () {
  1788. let index = $element.parent().data('index');
  1789. let tdValue = $element.html();
  1790. saveCellData($('#tb_table_right'), index, field, tdValue);
  1791. });
  1792. }
  1793. },
  1794. responseHandler: function (res) {
  1795. if (res == '401' || res == 401) {
  1796. window.location.href = '/thmz/login/view'
  1797. return;
  1798. }
  1799. var ress = eval(res);
  1800. if (ress.data.length > 0) {
  1801. $("#employeeNameLabel").val(ress.data[0].employeeName);
  1802. $("#warnDeptNameLabel").val(ress.data[0].warnDeptName);
  1803. $("#chargeDateLabel").val(format(ress.data[0].chargeDate, "yyyy-MM-dd HH:mm:ss"));
  1804. $("#icdTextLabel").val(ress.data[0].icdText);
  1805. $("#orderNoLabel").val(ress.data[0].orderNo);
  1806. $("#receiptNoLabel").val(ress.data[0].receiptNo);
  1807. $("#timesLabel").val(ress.data[0].times);
  1808. $("#nameLabel").val(ress.data[0].name);
  1809. $("#patientIdLabel").val(ress.data[0].patientId);
  1810. $("#realNoLabel").val(ress.data[0].realNo);
  1811. }
  1812. if(ress.patientAllergenInfoList){
  1813. callAllergenInfo(ress.patientAllergenInfoList)
  1814. }
  1815. if (ress.code == -1) {
  1816. if (ress.message != null && ress.message != '') {
  1817. new PNotify({
  1818. title: '错误提示',
  1819. text: ress.message,
  1820. type: 'error',
  1821. hide: true,
  1822. styling: 'bootstrap3'
  1823. });
  1824. }
  1825. return {
  1826. "total": 0,//总页数
  1827. "rows": {} //数据
  1828. };
  1829. }
  1830. return {
  1831. "total": ress.data.length,//总页数
  1832. "rows": ress.data //数据
  1833. };
  1834. },
  1835. onLoadSuccess: function (res) { //加载成功时执行
  1836. var sendTotalAmount = 0;
  1837. for (var i = 0; i < res.rows.length; i++) {
  1838. sendTotalAmount += parseFloat(res.rows[i].quantity * res.rows[i].unitPrice * res.rows[i].drugWin);
  1839. }
  1840. $('#sendTotalAmount').html(sendTotalAmount.toFixed(2));//toFixed(2),保留2位小数,避免js中小数相加小数点后面多出很多位
  1841. },
  1842. });
  1843. $("#cfxxModal").modal();
  1844. }
  1845. /**
  1846. * 查询病人处方药品明细
  1847. */
  1848. function fitfymx(patientId, times, receiptNo, orderNo, groupNoOut) {
  1849. var temp = {
  1850. patientId: patientId,
  1851. times: times,
  1852. receiptNo: receiptNo,
  1853. orderNo: orderNo,
  1854. groupNoOut: groupNoOut,
  1855. confirmFlag: $("#confirmFlagSearch").val()
  1856. };
  1857. $('#tb_table_right_ty').bootstrapTable("destroy");
  1858. $table = $('#tb_table_right_ty').bootstrapTable({
  1859. url: '/thmz/getRefundYpMx', //请求后台的URL(*)
  1860. method: 'post', //请求方式(*)
  1861. striped: true, //是否显示行间隔色
  1862. cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
  1863. pagination: true, //是否显示分页(*)
  1864. sortable: true, //是否启用排序
  1865. sortOrder: "asc", //排序方式
  1866. queryParams: temp, //传递参数(*)
  1867. sidePagination: "client", //分页方式:client客户端分页,server服务端分页(*)
  1868. pageNumber: 1, //初始化加载第一页,默认第一页
  1869. pageSize: 10, //每页的记录行数(*)
  1870. pageList: [10, 25, 50, 100], //可供选择的每页的行数(*)
  1871. search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
  1872. strictSearch: true,
  1873. showColumns: false, //是否显示所有的列
  1874. showRefresh: false, //是否显示刷新按钮
  1875. minimumCountColumns: 2, //最少允许的列数
  1876. clickToSelect: true, //是否启用点击选中行
  1877. uniqueId: "ID", //每一行的唯一标识,一般为主键列
  1878. showToggle: false, //是否显示详细视图和列表视图的切换按钮
  1879. cardView: false, //是否显示详细视图
  1880. detailView: false,
  1881. paginationDetailHAlign: ' hidden',//隐藏左侧分页信息
  1882. //rowStyle:rowStyle,//通过自定义函数设置行样式
  1883. ajaxOptions: {
  1884. headers: {
  1885. 'Accept': 'application/json',
  1886. 'Authorization': 'Bearer ' + localStorage.getItem("token")
  1887. }
  1888. },
  1889. columns: [
  1890. {
  1891. field: 'charge_item_code',
  1892. title: '编码',
  1893. align: "center",
  1894. valign: 'middle'
  1895. },{
  1896. field: 'drugname',
  1897. title: '品名',
  1898. align: "center",
  1899. valign: 'middle',
  1900. formatter: function (value, row, index) {
  1901. if (value != null && value != "") {
  1902. return value.replace("()", "");
  1903. }
  1904. return "";
  1905. }
  1906. }, {
  1907. field: 'specification',
  1908. title: '规格',
  1909. align: "center",
  1910. valign: 'middle',
  1911. }, {
  1912. field: 'quantity',
  1913. title: '数量',
  1914. align: "center",
  1915. valign: 'middle',
  1916. }, {
  1917. field: 'unit_price',
  1918. title: '单价',
  1919. align: "center",
  1920. valign: 'middle',
  1921. }, {
  1922. field: 'dec_amount',
  1923. title: '<span style="color: red">退药量</span>',
  1924. align: "center",
  1925. valign: 'middle',
  1926. formatter: function (value, row, index) {
  1927. return '<span style="color: red">' + value + '</span>'
  1928. }
  1929. }, {
  1930. field: 'refund_medicine_remark',
  1931. title: '退药原因',
  1932. align: "center",
  1933. valign: 'middle',
  1934. formatter: function (value, row, index) {
  1935. if(row.dec_amount > 0){
  1936. return value;
  1937. } else {
  1938. return ''
  1939. }
  1940. }
  1941. }
  1942. ],
  1943. responseHandler: function (res) {
  1944. if (res == '401' || res == 401) {
  1945. window.location.href = '/thmz/login/view'
  1946. return;
  1947. }
  1948. var ress = eval(res);
  1949. if (ress.code == -1) {
  1950. if (ress.message != null && ress.message != '') {
  1951. new PNotify({
  1952. title: '错误提示',
  1953. text: ress.message,
  1954. type: 'error',
  1955. hide: true,
  1956. styling: 'bootstrap3'
  1957. });
  1958. }
  1959. return {
  1960. "total": 0,//总页数
  1961. "rows": {} //数据
  1962. };
  1963. }
  1964. return {
  1965. "total": ress.data.length,//总页数
  1966. "rows": ress.data //数据
  1967. };
  1968. },
  1969. onLoadSuccess: function (res) { //加载成功时执行
  1970. var returnTotalAmount = 0;
  1971. var returnAmount = 0;
  1972. for (var i = 0; i < res.rows.length; i++) {
  1973. returnTotalAmount += parseFloat(res.rows[i].quantity * res.rows[i].unit_price);
  1974. returnAmount += parseFloat(res.rows[i].dec_amount * res.rows[i].unit_price);
  1975. }
  1976. $('#returnTotalAmount').html(returnTotalAmount.toFixed(2));//toFixed(2),保留2位小数,避免js中小数相加小数点后面多出很多位
  1977. $('#returnAmount').html(returnAmount.toFixed(2));//toFixed(2),保留2位小数,避免js中小数相加小数点后面多出很多位
  1978. },
  1979. });
  1980. }
  1981. /**
  1982. * 退药处理
  1983. */
  1984. function saveRefundMedicine() {
  1985. let zt = $("#confirmFlagSearch").val()
  1986. // ================= 新增:详细调试信息 =================
  1987. console.log('=== saveRefundMedicine 函数开始 ===');
  1988. console.log('zt (confirmFlagSearch):', zt);
  1989. console.log('isTyOk 当前状态:', isTyOk);
  1990. console.log('scannedCodesMap 当前状态:', scannedCodesMap);
  1991. console.log('refundQuantityMap 当前状态:', refundQuantityMap);
  1992. console.log('window.currentRefundData 当前状态:', window.currentRefundData);
  1993. // 检查是否需要进行追溯码匹配
  1994. if (zt === '2') {
  1995. // 新增:按本次退药数据计算是否存在需要匹配的药品(非中药 且 不拆零 且 本次退药>0)。若无,则自动视为匹配完成
  1996. try {
  1997. let refundDataForMatch = window.currentRefundData || $table.bootstrapTable('getData');
  1998. let needMatchItemsNow = [];
  1999. if (refundDataForMatch && refundDataForMatch.length > 0) {
  2000. for (let i = 0; i < refundDataForMatch.length; i++) {
  2001. let r = refundDataForMatch[i];
  2002. let isTcm = (r.drugKind === '09' || r.drugKind === '10');
  2003. let isNonSplit = (r.serial === '99');
  2004. if (!isTcm && isNonSplit && r.dec_amount > 0) {
  2005. needMatchItemsNow.push(r);
  2006. }
  2007. }
  2008. }
  2009. if (needMatchItemsNow.length === 0) {
  2010. if (!isTyOk) {
  2011. isTyOk = true;
  2012. }
  2013. }
  2014. } catch (e) {
  2015. console.warn('计算是否需要匹配时出现异常,按默认流程继续:', e);
  2016. }
  2017. console.log('=== 进入追溯码匹配检查逻辑 ===');
  2018. // 检查是否已经完成匹配
  2019. if (!isTyOk) {
  2020. console.error('=== 错误:isTyOk 为 false,匹配未完成 ===');
  2021. console.log('isTyOk 详细值:', isTyOk);
  2022. console.log('isTyOk 类型:', typeof isTyOk);
  2023. return errorMesageSimaple('请先匹配退药药品追溯码!');
  2024. }
  2025. console.log('=== isTyOk 检查通过,继续后续逻辑 ===');
  2026. // 获取退药表格数据,检查是否所有需要退药的药品都已匹配
  2027. let tyTable = $('#ty_table_detail').bootstrapTable("getData");
  2028. let refundData = window.currentRefundData || $table.bootstrapTable('getData');
  2029. console.log('=== 获取表格数据 ===');
  2030. console.log('tyTable 总数量:', tyTable.length);
  2031. console.log('tyTable 样本数据:', tyTable.length > 0 ? tyTable[0] : '空数组');
  2032. console.log('refundData 总数量:', refundData.length);
  2033. console.log('refundData 样本数据:', refundData.length > 0 ? refundData[0] : '空数组');
  2034. console.log('$table.bootstrapTable("getData") 总数量:', $table.bootstrapTable('getData').length);
  2035. let needRefundItems = [];
  2036. console.log('=== 构建需要退药的药品列表 ===');
  2037. // 找出需要退药且需要匹配的药品(非中药 且 不拆零 且 本次退药>0)
  2038. refundData.forEach(function (item, index, arr) {
  2039. console.log(`检查第${index + 1}个药品:`, {
  2040. charge_item_code: item.charge_item_code,
  2041. dec_amount: item.dec_amount,
  2042. serial: item.serial,
  2043. drugKind: item.drugKind,
  2044. item_no: item.item_no
  2045. });
  2046. let isTcm = (item.drugKind === '09' || item.drugKind === '10');
  2047. let isNonSplit = (item.serial === '99');
  2048. if (!isTcm && isNonSplit && item.dec_amount > 0) {
  2049. needRefundItems.push({
  2050. chargeItemCode: item.charge_item_code,
  2051. serial: item.serial,
  2052. itemNo: item.item_no,
  2053. decAmount: item.dec_amount // 添加退药数量字段,用于后续校验
  2054. });
  2055. console.log(`第${index + 1}个药品需要退药且需要匹配,已添加到列表`);
  2056. } else {
  2057. console.log(`第${index + 1}个药品不需要匹配(中药或拆零或退药量<=0),跳过`);
  2058. }
  2059. });
  2060. console.log('=== needRefundItems 最终结果 ===');
  2061. console.log('needRefundItems 总数量:', needRefundItems.length);
  2062. console.log('needRefundItems 详细内容:', needRefundItems);
  2063. if (needRefundItems.length > 0) {
  2064. console.log('第一个需要退药的药品字段信息:');
  2065. console.log('- chargeItemCode:', needRefundItems[0].chargeItemCode);
  2066. console.log('- serial:', needRefundItems[0].serial);
  2067. console.log('- itemNo:', needRefundItems[0].itemNo);
  2068. console.log('- decAmount:', needRefundItems[0].decAmount);
  2069. }
  2070. // ================= 新增:智能追溯码匹配校验逻辑 =================
  2071. // 目的:检查是否扫描了足够数量的追溯码,而不是检查是否所有追溯码都已匹配
  2072. // 修改时间:2025年
  2073. // 修改原因:提高退药效率,只要求扫描退药数量对应的追溯码
  2074. console.log('=== 开始检查追溯码匹配状态 ===');
  2075. // 检查每个需要退药的药品是否都已匹配足够数量
  2076. let allMatched = true;
  2077. let unmatchedItems = [];
  2078. for (let i = 0; i < tyTable.length; i++) {
  2079. let item = tyTable[i];
  2080. console.log(`检查第${i + 1}个追溯码项目:`, {
  2081. chargeItemCode: item.chargeItemCode,
  2082. serial: item.serial,
  2083. itemNo: item.itemNo,
  2084. drugName: item.drugName,
  2085. drugTracCodg: item.drugTracCodg
  2086. });
  2087. // 检查这个药品是否需要退药
  2088. let needRefund = needRefundItems.find(function(refundItem) {
  2089. let matchResult = refundItem.chargeItemCode === item.chargeItemCode &&
  2090. refundItem.serial === item.serial &&
  2091. refundItem.itemNo === item.itemNo;
  2092. console.log(`匹配检查结果:`, {
  2093. refundItem: refundItem,
  2094. item: {
  2095. chargeItemCode: item.chargeItemCode,
  2096. serial: item.serial,
  2097. itemNo: item.itemNo
  2098. },
  2099. matchResult: matchResult
  2100. });
  2101. return matchResult;
  2102. });
  2103. if (needRefund) {
  2104. console.log(`第${i + 1}个追溯码项目需要退药,开始检查扫描状态`);
  2105. let drugCode = item.chargeItemCode;
  2106. let requiredCount = needRefund.decAmount;
  2107. let scannedCount = scannedCodesMap[drugCode] ? scannedCodesMap[drugCode].length : 0;
  2108. console.log(`药品 ${item.drugName} 匹配检查:`, {
  2109. drugCode: drugCode,
  2110. requiredCount: requiredCount,
  2111. scannedCount: scannedCount,
  2112. scannedCodes: scannedCodesMap[drugCode] || []
  2113. });
  2114. // 检查是否扫描了足够的追溯码
  2115. if (scannedCount < requiredCount) {
  2116. allMatched = false;
  2117. unmatchedItems.push(`${item.drugName} (需要${requiredCount}个,已扫描${scannedCount}个)`);
  2118. console.error(`药品 ${item.drugName} 扫描数量不足!`);
  2119. } else {
  2120. console.log(`药品 ${item.drugName} 扫描数量满足要求!`);
  2121. }
  2122. } else {
  2123. console.log(`第${i + 1}个追溯码项目不需要退药,跳过检查`);
  2124. }
  2125. }
  2126. console.log('=== 追溯码匹配检查结果 ===');
  2127. console.log('allMatched:', allMatched);
  2128. console.log('unmatchedItems:', unmatchedItems);
  2129. if (!allMatched) {
  2130. console.error('=== 追溯码匹配检查失败 ===');
  2131. return errorMesageSimaple('还有药品未完成追溯码匹配:' + unmatchedItems.join('、') + ',请完成匹配后再退药!');
  2132. }
  2133. console.log('=== 追溯码匹配检查通过,继续退药处理 ===');
  2134. // ================= 原逻辑(已屏蔽,如需恢复请取消注释) =================
  2135. /*
  2136. // 原逻辑:检查是否所有追溯码都已匹配
  2137. // 屏蔽原因:效率低下,要求扫描所有追溯码而不是退药数量对应的追溯码
  2138. // 屏蔽时间:2025年
  2139. // 检查每个需要退药的药品是否都已匹配
  2140. let allMatched = true;
  2141. let unmatchedItems = [];
  2142. for (let i = 0; i < tyTable.length; i++) {
  2143. let item = tyTable[i];
  2144. // 检查这个药品是否需要退药
  2145. let needRefund = needRefundItems.some(function(refundItem) {
  2146. return refundItem.chargeItemCode === item.chargeItemCode &&
  2147. refundItem.serial === item.serial &&
  2148. refundItem.itemNo === item.itemNo;
  2149. });
  2150. if (needRefund) {
  2151. // 检查是否已匹配
  2152. if (isEmpty(item.matchOk) || item.matchOk.indexOf('已匹配') === -1) {
  2153. allMatched = false;
  2154. unmatchedItems.push(item.drugName || '未知药品');
  2155. }
  2156. }
  2157. }
  2158. if (!allMatched) {
  2159. return errorMesageSimaple('还有药品未匹配追溯码:' + unmatchedItems.join('、') + ',请完成匹配后再退药!');
  2160. }
  2161. */
  2162. // ================= 原逻辑结束 =================
  2163. }
  2164. var row = $("#tb_table").bootstrapTable('getSelections');
  2165. if (row.length != 1) {
  2166. return errorMesageSimaple('请选择一条处方数据');
  2167. }
  2168. if (row[0].confirmFlag == 3) {
  2169. return errorMesageSimaple('请勿重复退药');
  2170. }
  2171. var data = $table.bootstrapTable('getData');
  2172. var datas = [];
  2173. var i = 0;
  2174. data.forEach(function (item, index, arr) {
  2175. if (item.dec_amount != 0) {
  2176. // 调试日志
  2177. console.log('=== 退药参数调试 ===');
  2178. console.log('item.patient_id:', item.patient_id);
  2179. console.log('item.times:', item.times);
  2180. console.log('item.receipt_no:', item.receipt_no);
  2181. console.log('item.order_no:', item.order_no);
  2182. console.log('item.real_no:', item.real_no);
  2183. console.log('item.dec_amount:', item.dec_amount);
  2184. console.log('item.unit_price:', item.unit_price);
  2185. console.log('item.charge_item_code:', item.charge_item_code);
  2186. console.log('item.serial:', item.serial);
  2187. console.log('item.group_no:', item.group_no);
  2188. console.log('item.item_no:', item.item_no);
  2189. console.log('item.serial_no:', item.serial_no);
  2190. var tem = {
  2191. "patientId": item.patient_id,
  2192. "times": item.times,
  2193. "receiptNo": item.receipt_no,
  2194. "orderNo": item.order_no,
  2195. "realNo": item.real_no,
  2196. "decAmount": item.dec_amount,
  2197. "unitPrice": item.unit_price,
  2198. "chargeCode": item.charge_item_code,
  2199. "serial": item.serial,
  2200. "groupNo": item.group_no,
  2201. "itemNo": item.item_no,
  2202. "serialNo": item.serial_no
  2203. }
  2204. datas[i] = tem;
  2205. i++;
  2206. }
  2207. })
  2208. if (datas.length == 0) {
  2209. return errorMesageSimaple('退药处方可退药药品为空');
  2210. }
  2211. if (!confirm("确定要对当前处方的药品进行退药处理吗?")) {
  2212. return;
  2213. }
  2214. $("#btn_ty").attr("disabled", true);
  2215. $.ajax({
  2216. type: "POST",
  2217. url: '/thmz/refundMedicineProcessing',
  2218. contentType: "application/json;charset=UTF-8",
  2219. dataType: "json",
  2220. headers: {'Accept': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("token")},
  2221. data: JSON.stringify(datas),
  2222. success: function (res) {
  2223. // ========== 调试日志:AJAX成功响应 ==========
  2224. console.log('=== AJAX成功响应 ===');
  2225. console.log('响应状态: 成功');
  2226. console.log('响应数据:', res);
  2227. $("#btn_ty").attr("disabled", false);
  2228. if (res == '401' || res == 401) {
  2229. console.error('认证失败,跳转到登录页面');
  2230. window.location.href = '/thmz/login/view'
  2231. return;
  2232. }
  2233. if (res.code == 0) {
  2234. console.log('退药处理成功');
  2235. successMesage(res);
  2236. // ========== 调用退药医保接口 ==========
  2237. console.log('=== 开始调用退药医保接口 ===');
  2238. // 获取退药记录的基本信息
  2239. let refundData = $table.bootstrapTable('getData');
  2240. if (refundData && refundData.length > 0) {
  2241. let firstItem = refundData[0];
  2242. let patientId = firstItem.patient_id;
  2243. let times = firstItem.times;
  2244. let receiptNo = firstItem.receipt_no;
  2245. let orderNo = firstItem.order_no;
  2246. let realNo = Math.abs(firstItem.real_no); // 保证 realNo 为正数
  2247. let name = firstItem.name;
  2248. console.log('退药医保接口参数:', {
  2249. patientId: patientId,
  2250. times: times,
  2251. receiptNo: receiptNo,
  2252. orderNo: orderNo,
  2253. realNo: realNo,
  2254. name: name
  2255. });
  2256. // 调用退药医保接口
  2257. callYbReturnGoodsItem(realNo, orderNo, receiptNo, times, patientId, name);
  2258. } else {
  2259. console.warn('没有退药数据,跳过医保接口调用');
  2260. }
  2261. // 退药成功后重置匹配状态和全局数据
  2262. // ================= 新增:使用统一的重置函数 =================
  2263. // 目的:统一管理追溯码匹配状态的重置
  2264. // 修改时间:2025年
  2265. // 修改原因:确保状态重置的完整性和一致性
  2266. console.log('=== 退药成功,完全重置追溯码状态 ===');
  2267. resetTraceabilityState(false, false); // 退药成功后完全重置
  2268. initTbTable();
  2269. } else {
  2270. console.error('退药处理失败:', res.message);
  2271. errorMesage(res);
  2272. }
  2273. },
  2274. error: function () {
  2275. $("#btn_ty").attr("disabled", false);
  2276. }
  2277. });
  2278. }
  2279. /**
  2280. * 撤销退药处理
  2281. */
  2282. function saveCancelRefundMedicine() {
  2283. var row = $("#tb_table").bootstrapTable('getSelections');
  2284. console.log("row11111111111111111111111111111111",row)
  2285. if (row.length != 1) {
  2286. return errorMesageSimaple('请选择一条处方数据');
  2287. }
  2288. if (row[0].confirmFlag != 3) {
  2289. return errorMesageSimaple('请选择已退药记录');
  2290. }
  2291. if (!confirm("确定要撤销当前处方的退药吗?")) {
  2292. return;
  2293. }
  2294. // ================= 新增:撤销退药按钮已隐藏,禁用逻辑也注释 =================
  2295. // 目的:确保撤销退药按钮完全不可用
  2296. // 修改时间:2025年
  2297. // 修改原因:业务需求,不允许撤销退药操作
  2298. // $("#btn_cancel_ty").attr("disabled", true);
  2299. request({
  2300. url: '/cancelRefundMedicineProcessing',
  2301. method: 'GET',
  2302. data: {
  2303. realNo: row[0].realNo,
  2304. groupNo: groupNo,
  2305. receiptNo: row[0].receiptNo,
  2306. orderNo: row[0].orderNo,
  2307. patientId: row[0].patientId,
  2308. times: row[0].times
  2309. }
  2310. }).then((res) => {
  2311. // ================= 新增:撤销退药按钮已隐藏,启用逻辑也注释 =================
  2312. // 目的:确保撤销退药按钮完全不可用
  2313. // 修改时间:2025年
  2314. // 修改原因:业务需求,不允许撤销退药操作
  2315. // $("#btn_cancel_ty").attr("disabled", false);
  2316. successMesage(res);
  2317. // ========== 调用撤销退药医保接口 ==========
  2318. console.log('=== 开始调用撤销退药医保接口 ===');
  2319. // 获取撤销退药记录的基本信息
  2320. let patientId = row[0].patientId;
  2321. let times = row[0].times;
  2322. let receiptNo = row[0].receiptNo;
  2323. let orderNo = row[0].orderNo;
  2324. let realNo = row[0].realNo;
  2325. let name = row[0].name;
  2326. let doctorName = row[0].doctorName;
  2327. console.log('撤销退药医保接口参数:', {
  2328. patientId: patientId,
  2329. times: times,
  2330. receiptNo: receiptNo,
  2331. orderNo: orderNo,
  2332. realNo: realNo,
  2333. name: name
  2334. });
  2335. // 调用撤销退药医保接口
  2336. callYbSaleGoodsItemForCancelRefund(realNo, orderNo, receiptNo, times, patientId, name, doctorName);
  2337. initTbTable();
  2338. },err =>{
  2339. // ================= 新增:撤销退药按钮已隐藏,错误处理中的启用逻辑也注释 =================
  2340. // 目的:确保撤销退药按钮完全不可用
  2341. // 修改时间:2025年
  2342. // 修改原因:业务需求,不允许撤销退药操作
  2343. // $("#btn_cancel_ty").attr("disabled",false);
  2344. })
  2345. }
  2346. /**
  2347. * 叫号
  2348. * @param patientId
  2349. * @param name
  2350. */
  2351. function callNumber(patientId, name) {
  2352. $.ajax({
  2353. type: "GET",
  2354. url: '/thmz/callNumber?patientId=' + patientId + "&winNo=" + winNo,
  2355. contentType: "application/json;charset=UTF-8",
  2356. dataType: "json",
  2357. headers: {'Accept': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("token")},
  2358. success: function (res) {
  2359. if (res == '401' || res == 401) {
  2360. window.location.href = '/thmz/login/view'
  2361. return;
  2362. }
  2363. if (res.code == 0) {
  2364. //jhRecord.push(patientId);
  2365. pastList[pastList.length] = {name: name, patient_id: patientId};
  2366. window.localStorage["pastList"] = JSON.stringify(pastList);
  2367. successMesage(res);
  2368. } else {
  2369. errorMesage(res);
  2370. }
  2371. }
  2372. });
  2373. }
  2374. // 添加门诊过敏史
  2375. var $tableAllergen;
  2376. function callAllergenInfo(allergenList){
  2377. $tableAllergen = $('#tb_table_allergen').bootstrapTable({
  2378. data:allergenList,
  2379. striped: true, //是否显示行间隔色
  2380. cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
  2381. pagination: false, //是否显示分页(*)
  2382. sortable: false, //是否启用排序
  2383. sortOrder: "asc", //排序方式
  2384. sidePagination: "client", //分页方式:client客户端分页,server服务端分页(*)
  2385. pageNumber: 1, //初始化加载第一页,默认第一页
  2386. pageSize: 10, //每页的记录行数(*)
  2387. pageList: [10, 25, 50, 100], //可供选择的每页的行数(*)
  2388. search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
  2389. strictSearch: true,
  2390. showColumns: false, //是否显示所有的列
  2391. showRefresh: false, //是否显示刷新按钮
  2392. minimumCountColumns: 2, //最少允许的列数
  2393. clickToSelect: true, //是否启用点击选中行
  2394. uniqueId: "ID", //每一行的唯一标识,一般为主键列
  2395. showToggle: false, //是否显示详细视图和列表视图的切换按钮
  2396. cardView: false, //是否显示详细视图
  2397. detailView: false,
  2398. //rowStyle:rowStyle,//通过自定义函数设置行样式
  2399. ajaxOptions: {
  2400. headers: {
  2401. 'Accept': 'application/json',
  2402. 'Authorization': 'Bearer ' + localStorage.getItem("token")
  2403. }
  2404. },
  2405. columns: [
  2406. {
  2407. field: 'patNo',
  2408. title: '门诊号',
  2409. align: "center",
  2410. valign: 'middle'
  2411. },{
  2412. field: 'allergenCode',
  2413. title: '过敏源编码',
  2414. align: "center",
  2415. valign: 'middle'
  2416. }, {
  2417. field: 'allergenName',
  2418. title: '过敏源',
  2419. align: "center",
  2420. valign: 'middle',
  2421. }
  2422. ],
  2423. responseHandler: function (res) {
  2424. if (res == '401' || res == 401) {
  2425. window.location.href = '/thmz/login/view'
  2426. return;
  2427. }
  2428. if (ress.code == -1) {
  2429. if (ress.message != null && ress.message != '') {
  2430. new PNotify({
  2431. title: '错误提示',
  2432. text: ress.message,
  2433. type: 'error',
  2434. hide: true,
  2435. styling: 'bootstrap3'
  2436. });
  2437. }
  2438. return {
  2439. "total": 0,//总页数
  2440. "rows": {} //数据
  2441. };
  2442. }
  2443. return {
  2444. "total": ress.data.length,//总页数
  2445. "rows": ress.data //数据
  2446. };
  2447. }
  2448. });
  2449. }
  2450. function callHistoryDetail() {
  2451. if(coreId){
  2452. prescriptionHistoryDetail(coreId, '1');
  2453. }
  2454. }
  2455. // 查看历史处方
  2456. let $historyTable
  2457. function prescriptionHistoryDetail(patientId, type){
  2458. coreId = patientId
  2459. if(type === '0'){
  2460. daterangepickerNew('reportRangeList', 'center');
  2461. initSelectHistory();
  2462. }
  2463. $('#tb_table_history').bootstrapTable("destroy");
  2464. $historyTable = $('#tb_table_history').bootstrapTable({
  2465. url: '/thmz/getMzBlRecordList', //请求后台的URL(*)
  2466. method: 'post', //请求方式(*)
  2467. toolbar: '#toolbar', //工具按钮用哪个容器
  2468. striped: true, //是否显示行间隔色
  2469. cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
  2470. pagination: true, //是否显示分页(*)
  2471. sortable: true, //是否启用排序
  2472. sortOrder: "desc", //排序方式
  2473. queryParams: queryDataS, //传递参数(*)
  2474. sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
  2475. pageNumber: 1, //初始化加载第一页,默认第一页
  2476. pageSize: 5, //每页的记录行数(*)
  2477. pageList: [5, 10, 15, 25, 30], //可供选择的每页的行数(*)
  2478. search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
  2479. strictSearch: true,
  2480. showColumns: false, //是否显示所有的列
  2481. showRefresh: false, //是否显示刷新按钮
  2482. minimumCountColumns: 2, //最少允许的列数
  2483. clickToSelect: true, //是否启用点击选中行
  2484. uniqueId: "ID", //每一行的唯一标识,一般为主键列
  2485. showToggle: false, //是否显示详细视图和列表视图的切换按钮
  2486. cardView: false, //是否显示详细视图
  2487. detailView: false,
  2488. //rowStyle:rowStyle,//通过自定义函数设置行样式
  2489. ajaxOptions: {
  2490. headers: {
  2491. 'Accept': 'application/json',
  2492. 'Authorization': 'Bearer ' + localStorage.getItem("token")
  2493. }
  2494. },
  2495. columns: [
  2496. {
  2497. title: '操作',
  2498. field: 'op',
  2499. align: "center",
  2500. valign: 'middle',
  2501. formatter: function (value, row, index) {
  2502. var str = '<button type="button" class="btn btn-primary btn-sm" onclick="showMzBlRecordModal(\'' + row.patientId + '\',' + row.times + ',3)">查看</button>';
  2503. return [str].join('');
  2504. }
  2505. },
  2506. {
  2507. field: 'patientId',
  2508. title: '门诊ID',
  2509. align: "center",
  2510. valign: 'middle'
  2511. }, {
  2512. field: 'patientName',
  2513. title: '患者姓名',
  2514. align: "center",
  2515. valign: 'middle'
  2516. }, {
  2517. field: 'deptCode',
  2518. title: '就诊科室',
  2519. align: "center",
  2520. valign: 'middle'
  2521. }, {
  2522. field: 'doctorCode',
  2523. title: '接诊医师',
  2524. align: "center",
  2525. valign: 'middle'
  2526. }, {
  2527. field: 'firstOrNot',
  2528. title: '初/复诊',
  2529. align: "center",
  2530. valign: 'middle',
  2531. formatter: function (value, row, index) {
  2532. if (value == '1') {
  2533. return "复诊";
  2534. }
  2535. return "初诊";
  2536. }
  2537. }
  2538. , {
  2539. field: 'visitDate',
  2540. title: '就诊时间',
  2541. align: "center",
  2542. valign: 'middle',
  2543. formatter: function (value, row, index) {
  2544. if (value == null || value == "") {
  2545. return "";
  2546. }
  2547. return format(value, "yyyy-MM-dd HH:mm:ss");
  2548. }
  2549. }
  2550. ],
  2551. responseHandler: function (res) {
  2552. if (res == '401' || res == 401) {
  2553. window.location.href = '/thmz/login/view'
  2554. return;
  2555. }
  2556. var ress = eval(res);
  2557. if (ress.code == -1) {
  2558. if (ress.message != null && ress.message != '') {
  2559. errorMesage(ress);
  2560. }
  2561. return {
  2562. "total": 0,//总页数
  2563. "rows": {} //数据
  2564. };
  2565. }
  2566. return {
  2567. "total": ress.total,//总页数
  2568. "rows": ress.data //数据
  2569. };
  2570. },
  2571. });
  2572. $("#historyModal").modal();
  2573. }
  2574. function showMzBlRecordModal(patientId, times, type) {
  2575. $.ajax({
  2576. type: "GET",
  2577. url: '/thmz/getMzBlrecord?patientId=' + patientId + '&times=' + times,
  2578. contentType: "application/json;charset=UTF-8",
  2579. dataType: "json",
  2580. headers: {'Accept': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("token")},
  2581. success: function (res) {
  2582. if (res == '401' || res == 401) {
  2583. window.location.href = '/thmz/login/view'
  2584. return;
  2585. }
  2586. if (res.code == 0) {
  2587. var mzPatientMi = res.mzPatientMi;
  2588. $("#editPatientId").text(mzPatientMi.patientId);
  2589. $("#editPatientName").text(mzPatientMi.name);
  2590. $("#editPatientGender").text(mzPatientMi.gender);
  2591. $("#editPatientAge").text(mzPatientMi.ageString);
  2592. var mzBlRecord = res.mzBlRecord;
  2593. $("#editEmrChiefComplaint").val(mzBlRecord.emrChiefComplaint == null ? "" : mzBlRecord.emrChiefComplaint);
  2594. $("#editEmrHpi").val(mzBlRecord.emrHpi == null ? "" : mzBlRecord.emrHpi);
  2595. $("#editEmrPs").val(mzBlRecord.emrPs == null ? "" : mzBlRecord.emrPs);
  2596. $("#editPersonalHistory").val(mzBlRecord.personalHistory == null ? "" : mzBlRecord.personalHistory);
  2597. $("#editFzZl").val(mzBlRecord.fzZl == null ? "" : mzBlRecord.fzZl);
  2598. $("#editCrbHistory").val(mzBlRecord.crbHistory == null ? "" : mzBlRecord.crbHistory);
  2599. $("#editFamilyHistory").val(mzBlRecord.familyHistory == null ? "" : mzBlRecord.familyHistory);
  2600. $("#editObstericalHistory").val(mzBlRecord.obstericalHistory == null ? "" : mzBlRecord.obstericalHistory);
  2601. $("#editQtjc").val(mzBlRecord.emrPe == null ? "" : mzBlRecord.emrPe);
  2602. setSelectedAttr("editZd", mzBlRecord.icdCode, mzBlRecord.icdText);
  2603. var patientAllergenInfoList = res.patientAllergenInfoList;
  2604. if (patientAllergenInfoList != null && patientAllergenInfoList.length > 0) {
  2605. var zdAllergen = [];
  2606. var ypDitList = [];
  2607. var zdAllergenHtml = '';
  2608. var ypDitListHtml = '';
  2609. var zdAllergeCodes = null;
  2610. var zdAllergeTexts = null;
  2611. var ypDitListodes = null;
  2612. var ypDitListTexts = null;
  2613. for (var i = 0; i < patientAllergenInfoList.length; i++) {
  2614. var patientAllergenInfo = patientAllergenInfoList[i];
  2615. if (patientAllergenInfo.type == 0 || patientAllergenInfo.type == '0') {
  2616. zdAllergen[zdAllergen.length] = patientAllergenInfo.allergenCode;
  2617. zdAllergenHtml += '<option value="' + patientAllergenInfo.allergenCode + '">' + patientAllergenInfo.allergenName + '</option>';
  2618. if (zdAllergeCodes == null) {
  2619. zdAllergeCodes = patientAllergenInfo.allergenCode;
  2620. zdAllergeTexts = patientAllergenInfo.allergenName;
  2621. } else {
  2622. zdAllergeCodes += "," + patientAllergenInfo.allergenCode;
  2623. zdAllergeTexts += "," + patientAllergenInfo.allergenName;
  2624. }
  2625. } else if (patientAllergenInfo.type == 1 || patientAllergenInfo.type == '1') {
  2626. ypDitList[ypDitList.length] = patientAllergenInfo.allergenCode;
  2627. ypDitListHtml += '<option value="' + patientAllergenInfo.allergenCode + '">' + patientAllergenInfo.allergenName + '</option>';
  2628. if (zdAllergeCodes == null) {
  2629. ypDitListodes = patientAllergenInfo.allergenCode;
  2630. ypDitListTexts = patientAllergenInfo.allergenName;
  2631. } else {
  2632. ypDitListodes += "," + patientAllergenInfo.allergenCode;
  2633. ypDitListTexts += "," + patientAllergenInfo.allergenName;
  2634. }
  2635. }
  2636. }
  2637. $("#editZdAllergen").empty();
  2638. $('#editZdAllergen').append(zdAllergenHtml);
  2639. $('#editZdAllergen').selectpicker('refresh');
  2640. $("#editYpDitList").empty();
  2641. $('#editYpDitList').append(ypDitListHtml);
  2642. $('#editYpDitList').selectpicker('refresh');
  2643. $("#editZdAllergen").selectpicker('val', zdAllergen);
  2644. $("#editZdAllergen").selectpicker('refresh');
  2645. $("#editYpDitList").selectpicker('val', ypDitList);
  2646. $("#editYpDitList").selectpicker('refresh');
  2647. $("#editZdAllergen").attr("selectedCodes", zdAllergeCodes);
  2648. $("#editZdAllergen").attr("selectedTexts", zdAllergeTexts);
  2649. $("#editYpDitList").attr("selectedCodes", ypDitListodes);
  2650. $("#editYpDitList").attr("selectedTexts", ypDitListTexts);
  2651. }
  2652. var tentativeDiagnosis = mzBlRecord.tentativeDiagnosis == null ? "" : mzBlRecord.tentativeDiagnosis;
  2653. if ((mzBlRecord.icdCode == null || mzBlRecord.icdCode == "") && mzBlRecord.icdText != null && mzBlRecord.icdText != "") {
  2654. if (tentativeDiagnosis == null || tentativeDiagnosis == "") {
  2655. tentativeDiagnosis = mzBlRecord.icdText;
  2656. } else {
  2657. tentativeDiagnosis = mzBlRecord.icdText + " " + tentativeDiagnosis;
  2658. }
  2659. }
  2660. $("#edittentativeDiagnosis").val(tentativeDiagnosis);
  2661. $("#editEmrJkjy").val(mzBlRecord.emrJkjy == null ? "" : mzBlRecord.emrJkjy);
  2662. $("#bl_weight").val(mzBlRecord.weight == 0 ? null : mzBlRecord.weight);
  2663. $("#bl_temperature").val(mzBlRecord.temperature == 0 ? null : mzBlRecord.temperature);
  2664. $("#bl_sphygmus").val(mzBlRecord.sphygmus == 0 ? null : mzBlRecord.sphygmus);
  2665. $("#bl_breathe").val(mzBlRecord.breathe == 0 ? null : mzBlRecord.breathe);
  2666. $("#bl_pressure_high").val(mzBlRecord.pressureHigh == 0 ? null : mzBlRecord.pressureHigh);
  2667. $("#bl_pressure_floor").val(mzBlRecord.pressureFloor == 0 ? null : mzBlRecord.pressureFloor);
  2668. $("#bl_pressure_high_left").val(mzBlRecord.pressureHighLeft == 0 ? null : mzBlRecord.pressureHighLeft);
  2669. $("#bl_pressure_floor_left").val(mzBlRecord.pressureFloorLeft == 0 ? null : mzBlRecord.pressureFloorLeft);
  2670. if (mzBlRecord.emrProcess != null && mzBlRecord.emrProcess != "") {
  2671. var reg = new RegExp("</br>", "g");//g,表示全部替换。
  2672. var editEmrProcess = mzBlRecord.emrProcess.replace(reg, "\n");
  2673. reg = new RegExp("&nbsp;", "g");//g,表示全部替换。
  2674. editEmrProcess = editEmrProcess.replace(reg, "");
  2675. $("#editEmrProcess").val(editEmrProcess);
  2676. } else {
  2677. $("#editEmrProcess").val("");
  2678. }
  2679. if (type == 1) {
  2680. $("#mzBlRecorTitle").html("门诊病历【编辑】");
  2681. $("#setOtherEmrProcess").removeClass("in").addClass("hide");
  2682. $("#openBlRecordModel").removeClass("hide").addClass("in");
  2683. $("#setEmrProcess").removeClass("hide").addClass("in");
  2684. $("#visitingDetailModal").modal("hide");
  2685. } else if (type == 2 || type == 3) {
  2686. $("#mzBlRecorTitle").html("门诊病历【查询】");
  2687. if(type==2){
  2688. $("#setOtherEmrProcess").removeClass("hide").addClass("in");
  2689. }else {
  2690. $("#setOtherEmrProcess").removeClass("in").addClass("hide");
  2691. }
  2692. $("#openBlRecordModel").removeClass("in").addClass("hide");
  2693. $("#setEmrProcess").removeClass("in").addClass("hide");
  2694. //因为预览的时候,关闭预览框没有清空数据,且 此时基础数据的病历次数被清空
  2695. if ($("#mzBlTimes").val() != null && $("#mzBlTimes").val() != "" && ($("#baseMzBlTimes").val() == null || $("#baseMzBlTimes").val() == "")) {
  2696. $("#baseMzBlTimes").val($("#mzBlTimes").val());
  2697. }
  2698. $("#otherBlRecordModal").modal("hide");
  2699. }
  2700. $("#mzBlTimes").val(mzBlRecord.times);
  2701. $("#editMzBlRecordModal").modal();
  2702. } else {
  2703. errorMesage(res);
  2704. }
  2705. }
  2706. });
  2707. }
  2708. function queryDataS(params) {
  2709. var rePortRangeArr = getRePortRangeArr1();
  2710. var temp = { //这里的键的名字和控制器的变量名必须一直,这边改动,控制器也需要改成一样的
  2711. patientId: coreId,
  2712. times: '-1', // 这里需要根据patientId精确查找病人的病历,而不是模糊查询
  2713. beginTime: rePortRangeArr[0],
  2714. endTime: rePortRangeArr[1],
  2715. pageSize: params.limit, //页面大小
  2716. pageIndex: params.offset / params.limit, //页码
  2717. };
  2718. return temp;
  2719. }
  2720. function getRePortRangeArr1() {
  2721. var rePortRange = $('#reportRangeList span').html();
  2722. var rePortRangeArr = rePortRange.split(" - ");
  2723. rePortRangeArr[0] = rePortRangeArr[0] + " 00:00:00"
  2724. rePortRangeArr[1] = rePortRangeArr[1] + " 23:59:59"
  2725. return rePortRangeArr;
  2726. }
  2727. /**
  2728. * 清空区域
  2729. */
  2730. function clearInput() {
  2731. $("#editPatientId").text(null);
  2732. $("#editPatientName").text(null);
  2733. $("#editPatientGender").text(null);
  2734. $("#editPatientAge").text(null);
  2735. $("#editEmrChiefComplaint").val(null);
  2736. $("#editEmrHpi").val(null);
  2737. $("#editEmrPs").val(null);
  2738. $("#editPersonalHistory").val(null);
  2739. $("#editFzZl").val(null);
  2740. $("#editCrbHistory").val(null);
  2741. $("#editFamilyHistory").val(null);
  2742. $("#editObstericalHistory").val(null);
  2743. $("#bl_weight").val(null);
  2744. $("#bl_sphygmus").val(null);
  2745. $("#bl_breathe").val(null);
  2746. $("#bl_pressure_high").val(null);
  2747. $("#bl_pressure_floor").val(null);
  2748. $("#bl_pressure_high_left").val(null);
  2749. $("#bl_pressure_floor_left").val(null);
  2750. $("#editQtjc").val(null);
  2751. $("#editZd").selectpicker('val', null);
  2752. $("#editZd").selectpicker('refresh');
  2753. $("#edittentativeDiagnosis").val(null);
  2754. $("#editEmrProcess").val(null);
  2755. $("#editEmrJkjy").val(null);
  2756. $("#mzBlTimes").val(null);
  2757. }
  2758. function initSelectHistory() {
  2759. $('#reportRangeList span').html(moment().subtract(mzHistoryDays, 'days').format('YYYY-MM-DD') + ' - ' + moment().format('YYYY-MM-DD'));
  2760. //select 从后台加载数据,并保留之前选择的内容
  2761. dynamicSelectWithOri("editZd", '/thmz/getAllZdIcdCommonParams?commonParams=',false);
  2762. //过敏源
  2763. dynamicSelectWithOri("editZdAllergen", '/thmz/getZdAllergenListByCode?code=', false);
  2764. //药品列表
  2765. dynamicSelectWithOri("editYpDitList", '/thmz/getYpZdDictListByCode?code=', false);
  2766. }
  2767. // 退药药品追溯码匹配
  2768. function matchingDrugCodg(patientId, times, receiptNo, orderNo, realNo){
  2769. if(yf.xyFlag !== '1'){
  2770. errorMesage("暂时仅门诊西药房发药才进行配药处理!");
  2771. }
  2772. let isXy = yf.xyFlag === '1';
  2773. let tem = {
  2774. patientId: patientId,
  2775. times: times,
  2776. receiptNo: receiptNo,
  2777. orderNo: orderNo,
  2778. realNo: realNo,
  2779. groupNo: groupNo,
  2780. };
  2781. // 保存当前退药数据到全局变量,供匹配检查使用
  2782. window.currentRefundData = $table.bootstrapTable('getData');
  2783. // 新增:若本次退药全部为中药或拆零药,提示无需匹配并直接跳过
  2784. try {
  2785. let refundDataForMatch = window.currentRefundData || [];
  2786. let needMatchExists = false;
  2787. if (refundDataForMatch && refundDataForMatch.length > 0) {
  2788. for (let i = 0; i < refundDataForMatch.length; i++) {
  2789. let r = refundDataForMatch[i];
  2790. let isTcm = (r.drugKind === '09' || r.drugKind === '10');
  2791. let isNonSplit = (r.serial === '99');
  2792. if (!isTcm && isNonSplit && r.dec_amount > 0) {
  2793. needMatchExists = true;
  2794. break;
  2795. }
  2796. }
  2797. }
  2798. if (!needMatchExists) {
  2799. if (!isTyOk) { isTyOk = true; }
  2800. warningMesageSimaple('本次退药全部为中药或拆零药,无需匹配,请直接点击“退药处理”。');
  2801. return; // 不再打开匹配弹窗
  2802. }
  2803. } catch (e) {
  2804. console.warn('判断是否需要匹配时异常,按默认流程继续:', e);
  2805. }
  2806. // ================= 新增:追溯码匹配状态初始化 =================
  2807. // 目的:初始化扫描状态和退药数量信息,为智能匹配做准备
  2808. // 修改时间:2025年
  2809. // 修改原因:支持智能追溯码匹配功能
  2810. // 初始化扫描状态
  2811. scannedCodesMap = {};
  2812. refundQuantityMap = {};
  2813. // 预加载退药数量信息
  2814. let refundData = $table.bootstrapTable('getData');
  2815. refundData.forEach(function (item, index, arr) {
  2816. if (item.dec_amount > 0) {
  2817. refundQuantityMap[item.charge_item_code] = item.dec_amount;
  2818. }
  2819. });
  2820. $('#ty_table_detail').bootstrapTable("destroy");
  2821. $('#ty_table_detail').bootstrapTable({
  2822. url: '/thmz/getMzDrugTracCodgData', //请求后台的URL(*)
  2823. method: 'POST', //请求方式(*)
  2824. striped: true, //是否显示行间隔色
  2825. cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
  2826. pagination: true, //是否显示分页(*)
  2827. sortable: true, //是否启用排序
  2828. sortOrder: "asc", //排序方式
  2829. queryParams: JSON.stringify(tem), //传递参数(*)
  2830. sidePagination: "client", //分页方式:client客户端分页,server服务端分页(*)
  2831. pageNumber: 1, //初始化加载第一页,默认第一页
  2832. pageSize: 50, //每页的记录行数(*)
  2833. pageList: [10, 25, 50, 100], //可供选择的每页的行数(*)
  2834. search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
  2835. strictSearch: true,
  2836. showColumns: false, //是否显示所有的列
  2837. showRefresh: false, //是否显示刷新按钮
  2838. minimumCountColumns: 2, //最少允许的列数
  2839. clickToSelect: true, //是否启用点击选中行
  2840. uniqueId: "ID", //每一行的唯一标识,一般为主键列
  2841. showToggle: false, //是否显示详细视图和列表视图的切换按钮
  2842. cardView: false, //是否显示详细视图
  2843. detailView: false,
  2844. // rowStyle:rowStyleCharge,//通过自定义函数设置行样式
  2845. ajaxOptions: {
  2846. headers: {
  2847. 'Accept': 'application/json',
  2848. 'Authorization': 'Bearer ' + localStorage.getItem("token")
  2849. }
  2850. },
  2851. columns: [
  2852. {
  2853. field: 'drugName',
  2854. title: '品名',
  2855. align: "center",
  2856. valign: 'middle',
  2857. }, {
  2858. field: 'specification',
  2859. title: '规格',
  2860. align: "center",
  2861. valign: 'middle',
  2862. }, {
  2863. field: 'abbrName',
  2864. title: '生产厂家',
  2865. align: "center",
  2866. valign: 'middle',
  2867. visible: isXy
  2868. }, {
  2869. field: 'unitPrice',
  2870. title: '单价',
  2871. align: "center",
  2872. valign: 'middle',
  2873. }, {
  2874. field: 'drugTracCodg',
  2875. title: '药品追溯码',
  2876. width: '270',
  2877. align: "left",
  2878. valign: 'middle',
  2879. formatter: function (value, row, index) {
  2880. return isEmpty(value)?'':value
  2881. }
  2882. }, {
  2883. field: 'matchOk',
  2884. title: '匹配结果',
  2885. align: "center",
  2886. valign: 'middle',
  2887. }
  2888. ],
  2889. responseHandler: function (res) {
  2890. if (res === '401' || res === 401) {
  2891. window.location.href = '/thmz/login/view'
  2892. return;
  2893. }
  2894. let re = eval(res);
  2895. if (re.data.length > 0) {
  2896. $("#patientIdTy").val(re.data[0].patientId);
  2897. $("#timesTy").val(re.data[0].times);
  2898. $("#nameTy").val(re.data[0].name);
  2899. $("#employeeNameLabelTy").val(re.data[0].employeeName);
  2900. $("#warnDeptNameLabelPy").val(re.data[0].warnDeptName);
  2901. $("#smMatchTy").val("");
  2902. // ================= 新增:初始化追溯码表格的进度显示 =================
  2903. // 目的:在追溯码表格加载完成后显示初始进度状态
  2904. // 修改时间:2025年
  2905. // 修改原因:提供更好的用户体验,显示每个药品的扫描进度
  2906. setTimeout(function() {
  2907. updateTraceabilityProgressDisplay();
  2908. }, 100);
  2909. }
  2910. if (re.code === -1) {
  2911. if (re.message != null && re.message !== '') {
  2912. new PNotify({
  2913. title: '错误提示',
  2914. text: re.message,
  2915. type: 'error',
  2916. hide: true,
  2917. styling: 'bootstrap3'
  2918. });
  2919. }
  2920. return {
  2921. "total": 0,//总页数
  2922. "rows": [] //数据
  2923. };
  2924. }
  2925. // 仅展示需要匹配的药品(非中药 且 不拆零 且 本次退药>0)
  2926. try {
  2927. let refundData = window.currentRefundData || $table.bootstrapTable('getData');
  2928. let needMatchKeySet = new Set();
  2929. if (refundData && refundData.length > 0) {
  2930. for (let i = 0; i < refundData.length; i++) {
  2931. let r = refundData[i];
  2932. let isTcm = (r.drugKind === '09' || r.drugKind === '10');
  2933. let isNonSplit = (r.serial === '99');
  2934. if (!isTcm && isNonSplit && r.dec_amount > 0) {
  2935. needMatchKeySet.add(r.charge_item_code + '||' + r.serial + '||' + r.item_no);
  2936. }
  2937. }
  2938. }
  2939. let filtered = (re.data || []).filter(function(row){
  2940. let key = row.chargeItemCode + '||' + row.serial + '||' + row.itemNo;
  2941. return needMatchKeySet.has(key);
  2942. });
  2943. return {
  2944. "total": filtered.length,
  2945. "rows": filtered
  2946. };
  2947. } catch (e) {
  2948. console.warn('过滤匹配列表异常,回退为原始数据:', e);
  2949. return {
  2950. "total": re.data.length,//总页数
  2951. "rows": re.data //数据
  2952. };
  2953. }
  2954. },
  2955. onLoadSuccess: function () {
  2956. // 如果没有需要匹配的药品,自动关闭弹窗并视为匹配完成
  2957. try {
  2958. let rows = $('#ty_table_detail').bootstrapTable('getData') || [];
  2959. if (rows.length === 0) {
  2960. if (!isTyOk) { isTyOk = true; }
  2961. $('#tyModal').modal('hide');
  2962. }
  2963. } catch (e) {
  2964. console.warn('匹配表加载后自动关闭判断异常:', e);
  2965. }
  2966. },
  2967. });
  2968. $("#tyModal").modal();
  2969. // 弹窗打开后自动聚焦到扫码输入框
  2970. $("#tyModal").on('shown.bs.modal', function () {
  2971. setTimeout(function() {
  2972. $("#smMatchTy").focus();
  2973. }, 100);
  2974. });
  2975. // ================= 新增:弹窗关闭时重置追溯码状态 =================
  2976. // 目的:确保弹窗关闭时清理所有状态,避免状态残留
  2977. // 修改时间:2025年
  2978. // 修改原因:防止状态污染,确保下次打开弹窗时状态正确
  2979. // 注意:如果匹配成功,不要重置 isTyOk 状态和扫描数据
  2980. $("#tyModal").off('hidden.bs.modal').on('hidden.bs.modal', function () {
  2981. console.log('=== 弹窗关闭事件触发 ===');
  2982. console.log('关闭前 isTyOk 状态:', isTyOk);
  2983. // 如果匹配成功,保留 isTyOk 状态和扫描数据,只重置其他状态
  2984. if (isTyOk) {
  2985. console.log('匹配已成功,保留 isTyOk 状态和扫描数据,只重置其他状态');
  2986. resetTraceabilityState(true, true); // 保留 isTyOk 状态和扫描数据
  2987. } else {
  2988. console.log('匹配未成功,重置所有状态');
  2989. resetTraceabilityState(false, false); // 完全重置
  2990. }
  2991. });
  2992. // 防抖定时器
  2993. let matchDebounceTimer = null;
  2994. // 支持回车键触发匹配
  2995. $("#smMatchTy").on('keypress', function(e) {
  2996. if (e.which === 13) { // 回车键
  2997. e.preventDefault();
  2998. // 清除防抖定时器
  2999. if (matchDebounceTimer) {
  3000. clearTimeout(matchDebounceTimer);
  3001. }
  3002. matchDrugCodg();
  3003. }
  3004. });
  3005. // 输入防抖处理
  3006. $("#smMatchTy").on('input', function() {
  3007. let code = $(this).val().trim();
  3008. // 清除之前的定时器
  3009. if (matchDebounceTimer) {
  3010. clearTimeout(matchDebounceTimer);
  3011. }
  3012. // 如果输入框有值,设置0.5秒防抖
  3013. if (code && code !== '') {
  3014. matchDebounceTimer = setTimeout(function() {
  3015. matchDrugCodg();
  3016. }, 500);
  3017. }
  3018. });
  3019. // 防止onchange和防抖冲突
  3020. $("#smMatchTy").on('change', function() {
  3021. // 清除防抖定时器,避免重复执行
  3022. if (matchDebounceTimer) {
  3023. clearTimeout(matchDebounceTimer);
  3024. matchDebounceTimer = null;
  3025. }
  3026. });
  3027. // 扫码输入框获得焦点时全选文本
  3028. $("#smMatchTy").on('focus', function() {
  3029. $(this).select();
  3030. });
  3031. }
  3032. // 匹配扫码
  3033. function matchDrugCodg(){
  3034. if(isTyOk){
  3035. isTyOk = false;
  3036. }
  3037. let code = $("#smMatchTy").val().trim().replace(/[\r\n]/g,"");
  3038. // 检查输入是否为空
  3039. if (!code) {
  3040. errorMesageSimaple("请输入或扫描药品追溯码!");
  3041. $("#smMatchTy").focus();
  3042. return false;
  3043. }
  3044. let tyTable = $('#ty_table_detail').bootstrapTable("getData");
  3045. let matched = false;
  3046. for (let i = 0; i < tyTable.length; i++) {
  3047. if(tyTable[i].drugTracCodg === code){
  3048. // ================= 新增:智能追溯码匹配逻辑 =================
  3049. // 目的:只要求扫描退药数量对应的追溯码,而不是所有追溯码
  3050. // 修改时间:2025年
  3051. // 修改原因:解决退药时需要扫描所有追溯码的问题,提高工作效率
  3052. let currentDrugCode = tyTable[i].chargeItemCode;
  3053. // 获取该药品的退药数量
  3054. if (!refundQuantityMap[currentDrugCode]) {
  3055. refundQuantityMap[currentDrugCode] = getRefundQuantityForDrug(currentDrugCode);
  3056. }
  3057. let maxAllowedCount = refundQuantityMap[currentDrugCode];
  3058. // 获取已扫描数量
  3059. if (!scannedCodesMap[currentDrugCode]) {
  3060. scannedCodesMap[currentDrugCode] = [];
  3061. }
  3062. let currentScannedCount = scannedCodesMap[currentDrugCode].length;
  3063. // 检查是否超过退药数量
  3064. if (currentScannedCount >= maxAllowedCount) {
  3065. warningMesageSimaple(`该药品已扫描${currentScannedCount}个追溯码,退药数量为${maxAllowedCount}个,无需继续扫描!`);
  3066. $("#smMatchTy").val("").focus();
  3067. return false;
  3068. }
  3069. // 检查是否已扫描过此追溯码
  3070. if (scannedCodesMap[currentDrugCode].includes(code)) {
  3071. warningMesageSimaple("该追溯码已扫描过,请勿重复扫描!");
  3072. $("#smMatchTy").val("").focus();
  3073. return false;
  3074. }
  3075. // 记录扫描的追溯码
  3076. scannedCodesMap[currentDrugCode].push(code);
  3077. // 更新匹配结果显示(带进度显示)
  3078. let newScannedCount = scannedCodesMap[currentDrugCode].length;
  3079. let progressText = `${newScannedCount}/${maxAllowedCount}`;
  3080. let color = newScannedCount >= maxAllowedCount ? 'green' : 'orange';
  3081. $('#ty_table_detail').bootstrapTable('updateCell', {
  3082. index: i,
  3083. field: "drugTracCodg",
  3084. value: '<span style="color: green">' + tyTable[i].drugTracCodg + '</span>'
  3085. });
  3086. $('#ty_table_detail').bootstrapTable('updateCell', {
  3087. index: i,
  3088. field: "matchOk",
  3089. value: `<span style="color: ${color}">已匹配 (${progressText})</span>`
  3090. });
  3091. successMesageSimaple("药品追溯码匹配成功!");
  3092. matched = true;
  3093. // 匹配成功后清空输入框,准备扫描下一个
  3094. $("#smMatchTy").val("").focus();
  3095. break;
  3096. // ================= 原逻辑(已屏蔽,如需恢复请取消注释) =================
  3097. /*
  3098. // 原逻辑:要求扫描所有追溯码
  3099. // 屏蔽原因:效率低下,需要扫描所有追溯码而不是退药数量对应的追溯码
  3100. // 屏蔽时间:2025年
  3101. if(!isEmpty(tyTable[i].matchOk)){
  3102. warningMesageSimaple("已匹配,请勿重复扫码!");
  3103. // 重复匹配时清空输入框,准备扫描下一个
  3104. $("#smMatchTy").val("").focus();
  3105. return false;
  3106. }
  3107. $('#ty_table_detail').bootstrapTable('updateCell', {
  3108. index: i,
  3109. field: "drugTracCodg",
  3110. value: '<span style="color: green">' + tyTable[i].drugTracCodg + '</span>'
  3111. });
  3112. $('#ty_table_detail').bootstrapTable('updateCell', {
  3113. index: i,
  3114. field: "matchOk",
  3115. value: '<span style="color: green">已匹配</span>'
  3116. });
  3117. successMesageSimaple("药品追溯码匹配成功!");
  3118. matched = true;
  3119. // 匹配成功后清空输入框,准备扫描下一个
  3120. $("#smMatchTy").val("").focus();
  3121. break;
  3122. */
  3123. // ================= 原逻辑结束 =================
  3124. }
  3125. }
  3126. if (!matched) {
  3127. errorMesageSimaple("在退药列表未找到条码对应的药品,请核对!");
  3128. // 匹配失败时清空输入框
  3129. $("#smMatchTy").val("").focus();
  3130. }
  3131. }
  3132. // 确认匹配之后可以退药了
  3133. function matchTp(){
  3134. // 获取退药表格数据
  3135. let tyTable = $('#ty_table_detail').bootstrapTable("getData");
  3136. let refundData = window.currentRefundData || $table.bootstrapTable('getData');
  3137. // ========== 调试日志开始 ==========
  3138. console.log('=== matchTp 调试信息 ===');
  3139. console.log('refundData 样本:', refundData.length > 0 ? refundData[0] : '空数组');
  3140. console.log('tyTable 样本:', tyTable.length > 0 ? tyTable[0] : '空数组');
  3141. // ========== 调试日志结束 ==========
  3142. let needRefundItems = [];
  3143. // 找出需要退药且需要匹配的药品(非中药 且 不拆零 且 本次退药>0)
  3144. refundData.forEach(function (item, index, arr) {
  3145. let isTcm = (item.drugKind === '09' || item.drugKind === '10');
  3146. let isNonSplit = (item.serial === '99');
  3147. if (!isTcm && isNonSplit && item.dec_amount > 0) {
  3148. needRefundItems.push({
  3149. chargeItemCode: item.charge_item_code,
  3150. serial: item.serial,
  3151. itemNo: item.item_no,
  3152. decAmount: item.dec_amount
  3153. });
  3154. }
  3155. });
  3156. // ================= 新增:智能数量校验逻辑 =================
  3157. // 目的:检查是否扫描了足够数量的追溯码,而不是检查是否所有追溯码都已匹配
  3158. // 修改时间:2025年
  3159. // 修改原因:提高退药效率,只要求扫描退药数量对应的追溯码
  3160. // 检查每个需要退药的药品是否都已匹配足够数量
  3161. let allMatched = true;
  3162. let unmatchedItems = [];
  3163. for (let i = 0; i < tyTable.length; i++) {
  3164. let item = tyTable[i];
  3165. // 检查这个药品是否需要退药
  3166. let needRefund = needRefundItems.find(function(refundItem) {
  3167. return refundItem.chargeItemCode === item.chargeItemCode &&
  3168. refundItem.serial === item.serial &&
  3169. refundItem.itemNo === item.itemNo;
  3170. });
  3171. if (needRefund) {
  3172. let drugCode = item.chargeItemCode;
  3173. let requiredCount = needRefund.decAmount;
  3174. let scannedCount = scannedCodesMap[drugCode] ? scannedCodesMap[drugCode].length : 0;
  3175. // 检查是否扫描了足够的追溯码
  3176. if (scannedCount < requiredCount) {
  3177. allMatched = false;
  3178. unmatchedItems.push(`${item.drugName} (需要${requiredCount}个,已扫描${scannedCount}个)`);
  3179. }
  3180. }
  3181. }
  3182. if (!allMatched) {
  3183. return errorMesageSimaple('还有药品未完成追溯码匹配:' + unmatchedItems.join('、') + ',请完成匹配后再确认!');
  3184. }
  3185. // ================= 原逻辑(已屏蔽,如需恢复请取消注释) =================
  3186. /*
  3187. // 原逻辑:检查是否所有追溯码都已匹配
  3188. // 屏蔽原因:效率低下,要求扫描所有追溯码而不是退药数量对应的追溯码
  3189. // 屏蔽时间:2025年
  3190. // 检查每个需要退药的药品是否都已匹配
  3191. let allMatched = true;
  3192. let unmatchedItems = [];
  3193. for (let i = 0; i < tyTable.length; i++) {
  3194. let item = tyTable[i];
  3195. // 检查这个药品是否需要退药
  3196. let needRefund = needRefundItems.some(function(refundItem) {
  3197. let matchResult = refundItem.chargeItemCode === item.chargeItemCode &&
  3198. refundItem.serial === item.serial &&
  3199. refundItem.itemNo === item.itemNo;
  3200. // ========== 调试日志开始 ==========
  3201. if (i === 0) { // 只打印第一个匹配的调试信息
  3202. console.log('=== 匹配检查调试 ===');
  3203. console.log('tyTable item 字段信息:');
  3204. console.log('- item.chargeItemCode:', item.chargeItemCode);
  3205. console.log('- item.serial:', item.serial);
  3206. console.log('- item.itemNo:', item.itemNo);
  3207. console.log('- item.drugName:', item.drugName);
  3208. console.log('- item.matchOk:', item.matchOk);
  3209. console.log('refundItem 字段信息:');
  3210. console.log('- refundItem.chargeItemCode:', refundItem.chargeItemCode);
  3211. console.log('- refundItem.serial:', refundItem.serial);
  3212. console.log('- refundItem.itemNo:', refundItem.itemNo);
  3213. console.log('匹配结果:', matchResult);
  3214. }
  3215. // ========== 调试日志结束 ==========
  3216. return matchResult;
  3217. });
  3218. if (needRefund) {
  3219. // 检查是否已匹配
  3220. if (isEmpty(item.matchOk) || item.matchOk.indexOf('已匹配') === -1) {
  3221. allMatched = false;
  3222. unmatchedItems.push(item.drugName || '未知药品');
  3223. }
  3224. }
  3225. }
  3226. if (!allMatched) {
  3227. return errorMesageSimaple('还有药品未匹配追溯码:' + unmatchedItems.join('、') + ',请完成所有匹配后再确认!');
  3228. }
  3229. */
  3230. // ================= 原逻辑结束 =================
  3231. console.log('=== 确认匹配对话框 ===');
  3232. if (!confirm("确定对当前处方所有退药的药品匹配成功?")) {
  3233. console.log('用户取消了确认匹配');
  3234. return;
  3235. }
  3236. console.log('=== 设置匹配完成状态 ===');
  3237. console.log('设置前 isTyOk:', isTyOk);
  3238. if(!isTyOk){
  3239. isTyOk = true;
  3240. console.log('isTyOk 已设置为 true');
  3241. } else {
  3242. console.log('isTyOk 已经是 true,无需重复设置');
  3243. }
  3244. console.log('设置后 isTyOk:', isTyOk);
  3245. console.log('=== 关闭追溯码匹配弹窗 ===');
  3246. $("#tyModal").modal('hide');
  3247. }
  3248. // ================= 新增:获取指定药品的退药数量 =================
  3249. // 目的:根据药品编码获取该药品的退药数量,用于智能追溯码匹配
  3250. // 修改时间:2025年
  3251. // 修改原因:支持智能追溯码匹配功能,只要求扫描退药数量对应的追溯码
  3252. // 参数:drugCode - 药品编码
  3253. // 返回值:退药数量,如果没有退药则返回0
  3254. function getRefundQuantityForDrug(drugCode) {
  3255. let refundData = window.currentRefundData || $table.bootstrapTable('getData');
  3256. for (let item of refundData) {
  3257. if (item.charge_item_code === drugCode && item.dec_amount > 0) {
  3258. return item.dec_amount;
  3259. }
  3260. }
  3261. return 0;
  3262. }
  3263. // ================= 新增:更新追溯码表格的进度显示 =================
  3264. // 目的:实时更新追溯码表格中每个药品的扫描进度显示
  3265. // 修改时间:2025年
  3266. // 修改原因:提供更好的用户体验,让用户清楚了解每个药品的扫描状态
  3267. // 功能:显示格式为"已匹配 (2/4)"或"未匹配 (0/4)",绿色表示完成,橙色表示进行中
  3268. function updateTraceabilityProgressDisplay() {
  3269. let tyTable = $('#ty_table_detail').bootstrapTable("getData");
  3270. tyTable.forEach(function(item, index) {
  3271. let drugCode = item.chargeItemCode;
  3272. let scannedCount = scannedCodesMap[drugCode] ? scannedCodesMap[drugCode].length : 0;
  3273. let requiredCount = refundQuantityMap[drugCode] || 0;
  3274. if (requiredCount > 0) {
  3275. let progressText = `${scannedCount}/${requiredCount}`;
  3276. let color = scannedCount >= requiredCount ? 'green' : 'orange';
  3277. let statusText = scannedCount > 0 ? '已匹配' : '未匹配';
  3278. $('#ty_table_detail').bootstrapTable('updateCell', {
  3279. index: index,
  3280. field: "matchOk",
  3281. value: `<span style="color: ${color}">${statusText} (${progressText})</span>`
  3282. });
  3283. }
  3284. });
  3285. }
  3286. // ================= 新增:重置追溯码扫描状态 =================
  3287. // 目的:统一重置所有追溯码匹配相关的状态变量
  3288. // 修改时间:2025年
  3289. // 修改原因:确保状态管理的一致性,防止状态残留导致的问题
  3290. // 重置内容:
  3291. // - scannedCodesMap: 清空已扫描的追溯码记录(可选)
  3292. // - refundQuantityMap: 清空退药数量记录(可选)
  3293. // - isTyOk: 重置匹配完成标志(可选)
  3294. // - window.currentRefundData: 清空当前退药数据(可选)
  3295. // 参数:keepIsTyOk - 是否保留 isTyOk 状态,默认为 false
  3296. // 参数:keepScannedData - 是否保留扫描数据,默认为 false
  3297. function resetTraceabilityState(keepIsTyOk = false, keepScannedData = false) {
  3298. console.log('=== 重置追溯码状态 ===');
  3299. console.log('重置前状态:', {
  3300. scannedCodesMap: scannedCodesMap,
  3301. refundQuantityMap: refundQuantityMap,
  3302. isTyOk: isTyOk,
  3303. currentRefundData: window.currentRefundData
  3304. });
  3305. console.log('keepIsTyOk 参数:', keepIsTyOk);
  3306. console.log('keepScannedData 参数:', keepScannedData);
  3307. let currentIsTyOk = isTyOk; // 保存当前状态
  3308. let currentScannedCodesMap = scannedCodesMap; // 保存当前扫描数据
  3309. let currentRefundQuantityMap = refundQuantityMap; // 保存当前退药数量数据
  3310. // 根据参数决定是否清空扫描数据
  3311. if (!keepScannedData) {
  3312. scannedCodesMap = {};
  3313. refundQuantityMap = {};
  3314. console.log('清空扫描数据和退药数量数据');
  3315. } else {
  3316. console.log('保留扫描数据和退药数量数据');
  3317. }
  3318. // 根据参数决定是否清空当前退药数据
  3319. if (!keepScannedData) {
  3320. window.currentRefundData = null;
  3321. console.log('清空当前退药数据');
  3322. } else {
  3323. console.log('保留当前退药数据');
  3324. }
  3325. // 根据参数决定是否重置 isTyOk
  3326. if (!keepIsTyOk) {
  3327. isTyOk = false;
  3328. console.log('重置 isTyOk 为 false');
  3329. } else {
  3330. isTyOk = currentIsTyOk;
  3331. console.log('保留 isTyOk 状态:', isTyOk);
  3332. }
  3333. console.log('重置后状态:', {
  3334. scannedCodesMap: scannedCodesMap,
  3335. refundQuantityMap: refundQuantityMap,
  3336. isTyOk: isTyOk,
  3337. currentRefundData: window.currentRefundData
  3338. });
  3339. console.log('=== 追溯码状态重置完成 ===');
  3340. }
  3341. function printPrescription(patientId, times, orderNo) {
  3342. if (mzCfPrintIndex == null || ekCfPrintIndex == null || jzCfPrintIndex == null) {
  3343. return errorMesageSimaple('打印机参数未设置,请在发药参数设置中设置');
  3344. }
  3345. var tem = {
  3346. patientId: patientId,
  3347. times: times,
  3348. orderNo: orderNo,
  3349. groupNo: groupNo
  3350. };
  3351. $.ajax({
  3352. type: "POST",
  3353. url: '/thmz/getPrintPrescriptionData',
  3354. contentType: "application/json;charset=UTF-8",
  3355. dataType: "json",
  3356. headers: {'Accept': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("token")},
  3357. data: JSON.stringify(tem),
  3358. success: function (res) {
  3359. if (res == '401' || res == 401) {
  3360. window.location.href = '/thmz/login/view'
  3361. return;
  3362. }
  3363. if (res.code == 0) {
  3364. //setPrint();//初始化默认打印机
  3365. printView(res.data);
  3366. successMesage(res);
  3367. } else {
  3368. errorMesage(res);
  3369. }
  3370. }
  3371. });
  3372. }
  3373. function groupByGroupProperty(array) {
  3374. return array.reduce((acc, current) => {
  3375. const group = current.groupOrder;
  3376. acc[group] = acc[group] || [];
  3377. acc[group].push(current);
  3378. return acc;
  3379. }, {});
  3380. }
  3381. function printView(data) {
  3382. $('.sjh').remove();
  3383. $('#print_view input').attr("value", "");
  3384. var age = 0;
  3385. if (null != data) {
  3386. for (var key in data) {
  3387. $("#" + key + "").attr("value", data[key]);
  3388. }
  3389. age = getBirthSlot(data['birthDay'], data.list[0].priceTime);
  3390. $("#age").attr("value", age);
  3391. }
  3392. var list = data.list;
  3393. // console.log('list',list);
  3394. if(list.length > 0) {
  3395. let gruop = groupByGroupProperty(list);
  3396. for (const key in gruop) {
  3397. let current = gruop[key]
  3398. // console.log('current',current);
  3399. if (current) {
  3400. if(current.length == 1){
  3401. current[0].groupSign = '⊐'
  3402. } else {
  3403. current.forEach((item,index) => {
  3404. if(index == 0) {
  3405. item.groupSign = '⌝'
  3406. } else if(index == current.length - 1) {
  3407. item.groupSign = '⌟'
  3408. } else {
  3409. item.groupSign = ''
  3410. }
  3411. })
  3412. }
  3413. }
  3414. }
  3415. // console.log('gruop',gruop);
  3416. }
  3417. if (age.substring(0, age.indexOf('岁')) < 18 && yf.xyFlag === '1') {
  3418. $('#drugFlag').attr("value", "儿科");
  3419. printIndex = ekCfPrintIndex;
  3420. } else if (data.warnDeptName.indexOf("急诊") != -1 && yf.xyFlag === '1') {
  3421. $('#drugFlag').attr("value", "急诊");
  3422. printIndex = jzCfPrintIndex;
  3423. } else {
  3424. $('#drugFlag').attr("value", "普通");
  3425. printIndex = mzCfPrintIndex;
  3426. }
  3427. if (list[0].drugFlag == 2 || list[0].drugFlag == 3) {
  3428. $('#drugFlag').attr("value", "麻、精一");
  3429. } else if (list[0].drugFlag == 4) {
  3430. $('#drugFlag').attr("value", "精二");
  3431. } else if(list[0].drugFlag == 1){
  3432. $('#drugFlag').attr("value", "毒");
  3433. }
  3434. JsBarcode("#cfBarcode", data.patientId+'|'+data.times+'|'+data.orderNo, {
  3435. lineColor: '#000000', //线条颜色
  3436. width: 1, //线宽
  3437. height: 26, //条码高度
  3438. displayValue: false, //是否显示文字信息
  3439. });
  3440. $('#priceTime').attr("value", format(list[0].priceTime, "yyyy-MM-dd HH:mm"));
  3441. // 获取医生签名
  3442. getAjaxRequest("/thmz/getDoctorSignatureImage",{doctorCode:data.employeeCode},false,function (postRes) {
  3443. if(postRes.code == 0){
  3444. $("#employeeName").html("<img src='" + postRes.data + "' style='width:80px;'/>")
  3445. }else {
  3446. $('#employeeName').html(data.employeeName);
  3447. }
  3448. })
  3449. $('#sex').attr("value", getSex(data.sex));
  3450. $('#nameCf').attr("value", data.name);
  3451. $('#patientIdCf').attr("value", data.patientId);
  3452. $('#totalPrice').html(data.totalPrice + '元');
  3453. if (data.ybCardNo == null || data.ybCardNo == '') {
  3454. $('#ybCardNo').attr("value", data.icCardNo);
  3455. }
  3456. $('#tbody_yp').html(yf.xyFlag === '1' ? getXyPrintHtml(list) : getZyPrintHtml(list));
  3457. $("#patientId").val('');
  3458. // LODOP = getLodop();
  3459. // LODOP.PRINT_INITA(6, 0, "140mm", "202mm", "铭和医院处方笺");
  3460. // LODOP.SET_PRINT_STYLE("FontSize", 28); //字体大小
  3461. // //设置默认打印机
  3462. // //设置默认打印机
  3463. // LODOP.SET_PRINTER_INDEX(printIndex);
  3464. // LODOP.SET_PRINT_PAGESIZE(1, '140mm', '202mm', "CreateCustomPage");
  3465. // LODOP.SET_PRINT_MODE('FULL_WIDTH_FOR_OVERFLOW', true) // 整宽不变形
  3466. // LODOP.SET_SHOW_MODE("BKIMG_WIDTH", "140mm");
  3467. // LODOP.SET_SHOW_MODE("BKIMG_HEIGHT", "202mm");
  3468. // LODOP.SET_PRINT_MODE("CREATE_CUSTOM_PAGE_NAME", "铭和医院处方笺");//对新建的纸张重命名
  3469. // let strStyle='';
  3470. // let font = 'font-size: 12px;padding: 2px 2px;';
  3471. // if(yf.xyFlag !== '1'){
  3472. // strStyle = "<style>table,td,th {border-bottom: 1px dashed black;margin-bottom: 2px;";
  3473. // strStyle = "<style>table,td,th {border-bottom: 1px dashed black;margin-bottom: 2px;";
  3474. // strStyle += font;
  3475. // strStyle += font;
  3476. // strStyle += "}";
  3477. // strStyle += "}";
  3478. // strStyle += "</style>";
  3479. // }
  3480. // LODOP.ADD_PRINT_HTM("2mm", "4mm", "140mm", "202mm", strStyle + $("div[id='print_view']").html());
  3481. // LODOP.PREVIEW();
  3482. // LODOP.NewPageA();//下一页
  3483. LODOP = getLodop();
  3484. // 初始化打印区域,参数:top, left, width, height(横向打印时宽高可保持原比例)
  3485. LODOP.PRINT_INITA(6, 0, "202mm", "202mm", "铭和医院处方笺"); // 横向建议交换宽高值适配布局
  3486. // 设置字体大小
  3487. LODOP.SET_PRINT_STYLE("FontSize", 28);
  3488. // 设置默认打印机
  3489. LODOP.SET_PRINTER_INDEX(printIndex);
  3490. // 关键:设置打印方向为横向(1=横向),并保持自定义纸张尺寸
  3491. // 横向打印时,宽高参数建议按 "实际高度, 实际宽度" 传递更符合视觉习惯
  3492. LODOP.SET_PRINT_PAGESIZE(2, 0, 0, "square202");
  3493. // LODOP.SET_PRINT_PAGESIZE(2, 0, 0, "A4");
  3494. // // 整宽不变形模式(横向适配关键)
  3495. // LODOP.SET_PRINT_MODE('FULL_WIDTH_FOR_OVERFLOW', true);
  3496. //
  3497. // // 背景图尺寸适配横向纸张
  3498. // LODOP.SET_SHOW_MODE("BKIMG_WIDTH", "202mm");
  3499. // LODOP.SET_SHOW_MODE("BKIMG_HEIGHT", "140mm");
  3500. // 核心配置:同时宽度和高度自适应铺满
  3501. LODOP.SET_PRINT_MODE('FULL_WIDTH_FOR_OVERFLOWFLOW', true); // 宽度铺满
  3502. // LODOP.SET_PRINT_MODE('FULL_HEIGHT_FOR_OVERFLOWFLOW', true); // 高度铺满
  3503. LODOP.SET_PRINT_MODE('AUTO_SCALE', true); // 自动缩放适配
  3504. // 自定义纸张重命名
  3505. LODOP.SET_PRINT_MODE("CREATE_CUSTOM_PAGE_NAME", "铭和医院处方笺");
  3506. let strStyle = '';
  3507. let font = 'font-size: 12px;padding: 2px 2px;';
  3508. if (yf.xyFlag !== '1') {
  3509. strStyle = "<style>";
  3510. strStyle += "table,td,th {border-bottom: 1px dashed black;margin-bottom: 2px;";
  3511. strStyle += font;
  3512. strStyle += "}";
  3513. strStyle += "</style>";
  3514. }
  3515. // 添加HTML内容,参数:top, left, width, height(使用横向纸张的宽高)
  3516. // 宽度设为"100%"可自动适配横向纸张宽度
  3517. let printContent = document.getElementById('print_view').innerHTML
  3518. // LODOP.ADD_PRINT_HTM("2mm", "4mm", "100%", "100%", strStyle + $("div[id='print_view']").html());
  3519. LODOP.ADD_PRINT_HTM("2mm", "4mm", "100%", "100%", strStyle + printContent);
  3520. LODOP.SET_PRINT_MODE("RESELECT_ORIENT",true);
  3521. LODOP.SET_PRINT_MODE("RESELECT_PAGESIZE", true);
  3522. // 预览打印(横向效果)
  3523. // LODOP.PREVIEW();
  3524. // LODOP.NewPageA();//下一页
  3525. // 如需多页,建议在添加内容前调用NewPageA(),此处预览后无需调用
  3526. LODOP.NewPageA();
  3527. LODOP.PREVIEW();
  3528. }
  3529. function getXyPrintHtml(list) {
  3530. let tr = '';
  3531. for (let i = 0; i < list.length; i++) {
  3532. let printName = list[i].printName == null ? "" : list[i].printName;
  3533. let tryResult = '';
  3534. let tryFlag = '';
  3535. if(list[i].paySelf == 1 || list[i].ybZfFlag == 1){
  3536. continue
  3537. }
  3538. if (list[i].tryResult !== null && list[i].tryResult.trim() === '0') {
  3539. tryResult = '(阴性)';
  3540. } else if (list[i].psFlag === '1' && list[i].tryFlag === '0') {//药品需要皮试,处方未点需要皮试
  3541. tryResult = '<span style="color: red">(免试)</span>';
  3542. }
  3543. if (list[i].tryFlag === '1') {
  3544. tryFlag = '<span style="color: red">(需皮试)</span>';
  3545. }
  3546. var number = i + 1;
  3547. let manufactoryName = list[i].manufactoryName == null || list[i].manufactoryName === '' ? '' : '(' + list[i].manufactoryName + ')';
  3548. tr += '<tr>' +
  3549. ' <td style="margin-bottom: 5px;width: 12px;font-size: 18px;" align="left" valign="top">' + number + "." +
  3550. ' </td>' +
  3551. ' <td style="margin-bottom: 5px;vertical-align: middle !important;width: 400px;font-size: 13px;">' + tryResult + list[i].drugName +
  3552. ' </td>' +
  3553. ' <td colspan="3" style="margin-bottom: 5px;vertical-align: middle !important;width: 280px;text-align: right;font-size: 13px;">' + list[i].specification + '×' + list[i].quantity + list[i].ypUnitName +
  3554. ' </td>' +
  3555. ' <td>' +
  3556. ' </td>' +
  3557. // ' <td style="margin-bottom: 5px;vertical-align: middle !important;width: 5px;text-align: left;font-size: 13px;"></td>' +
  3558. ' <td style="margin-bottom: 5px;vertical-align: middle !important;width: 5px;text-align: left;font-size: 13px;">' +
  3559. ' </td>' +
  3560. // ' <td style="margin-bottom: 5px;vertical-align: middle !important;width: 20px;text-align: left;font-size: 13px;">' +
  3561. // ' </td>' +
  3562. ' <td style="vertical-align: middle !important;width: 60px;text-align: left;font-size:25px;font-weight: bold">' + list[i].groupSign +
  3563. ' </td>' +
  3564. ' <td>' +
  3565. ' </td>' +
  3566. '</tr>' +
  3567. '<tr>' +
  3568. ' <td style="margin-bottom: 5px;width: 10px;font-size: 13px;" align="left" valign="top">' +
  3569. ' </td>' +
  3570. ' <td colspan="2" style="padding-left:0;margin-bottom: 5px;width:220px;vertical-align: middle !important;text-align: left;font-size: 13px;">用法:' + list[i].drugQuan + "&nbsp;" + list[i].drugUnitName + '/次&nbsp;&nbsp;' + list[i].frequencyName + '&nbsp;&nbsp;' + printName +
  3571. ' </td>' +
  3572. ' <td style="margin-bottom: 5px;vertical-align: middle !important;width: 180px;font-size: 13px;">' + tryFlag +
  3573. ' </td>' +
  3574. ' <td style="margin-bottom: 5px;vertical-align: middle !important;width: 220px;font-size: 13px;">' + (list[i].instructionText == null ? '' : list[i].instructionText) +
  3575. ' </td>' +
  3576. ' <td style="margin-bottom: 5px;vertical-align: middle !important;font-size: 13px;">' +
  3577. ' </td>' +
  3578. ' <td style="margin-bottom: 5px;vertical-align: middle !important;font-size: 13px;">' +
  3579. ' </td>' +
  3580. ' <td>' +
  3581. ' </td>' +
  3582. '</tr>' +
  3583. '<tr>' +
  3584. ' <td style="margin-bottom: 5px;width: 10px;font-size: 13px;" align="left" valign="top">' +
  3585. ' </td>' +
  3586. '</tr>' +
  3587. '<tr>' +
  3588. ' <td style="margin-bottom: 5px;width: 10px;font-size: 13px;" align="left" valign="top">' +
  3589. // ' <td colspan="5" style="margin-bottom: 5px;vertical-align: middle !important;width: 245px;font-size: 13px;">' + '货位号:' + list[i].location +
  3590. // ' </td>' +
  3591. // ' <td style="margin-bottom: 5px;vertical-align: middle !important;width: 245px;font-size: 13px;">货位号:' + list[i].location +
  3592. // ' </td>' +
  3593. // ' <td colspan="4" style="padding-left:0;margin-bottom: 5px;width:220px;vertical-align: middle !important;text-align: left;font-size: 13px;">零售价:' + list[i].packRetprice + '&nbsp;元/' + list[i].ypUnitName +
  3594. // ' </td>' +
  3595. '</tr><tr style="height: 5px;"><td><img src="about:blank" width="5" height="5" /></td></tr>';
  3596. }
  3597. $('#yxwk').remove();
  3598. if (list.length < 5) {
  3599. $('#div_yp_cf').append('<span id="yxwk" style="margin-bottom: 5px;font-size: 13px;">以下为空</span>');
  3600. }
  3601. return tr;
  3602. }
  3603. function getZyPrintHtml(list) {
  3604. let tr = '';
  3605. for (let i = 0; i < list.length;) {
  3606. tr += '<tr class="sjh">' +
  3607. '<td style="width: 160px; font-size: 14px;">' + list[i].drugName + (list[i].instructionText == null || list[i].instructionText === '' ? '' : '【' + list[i].instructionText + '】') +
  3608. '</td>' +
  3609. '<td style="width: 40px;text-align: right; font-size: 14px;">' + list[i].specification +
  3610. '</td>' +
  3611. '<td style="width: 25px;text-align: right;border-right: 1px solid black; font-size: 14px;">' + list[i].quantity + list[i].ypUnitName +
  3612. '</td>';
  3613. if (i + 1 < list.length) {
  3614. tr += '<td style="width: 160px; font-size: 14px;">' + list[i + 1].drugName + (list[i + 1].instructionText == null || list[i + 1].instructionText === '' ? '' : '【' + list[i + 1].instructionText + '】') +
  3615. '</td>' +
  3616. '<td style="width: 40px;text-align: right; font-size: 14px;">' + list[i + 1].specification +
  3617. '</td>' +
  3618. '<td style="width: 25px;text-align: right; font-size: 14px;">' + list[i + 1].quantity + list[i + 1].ypUnitName +
  3619. '</td>' +
  3620. '</tr>';
  3621. }
  3622. i = i + 2;
  3623. }
  3624. let cydj = isEmpty(list[0].cyDj)?'':list[0].cyDj;
  3625. tr += '<tr class="sjh">' +
  3626. '<td colspan="6" style="border: 0 !important;text-align: right;padding: 0;">×&nbsp;' + list[0].drugWin +
  3627. '&nbsp;副&nbsp;&nbsp;'+cydj+'</td>' +
  3628. '</tr>';
  3629. let yf = '';
  3630. yf += isEmpty(list[0].cyMtjs)?'':'每天'+list[0].cyMtjs+'剂,';
  3631. yf += isEmpty(list[0].cyJsl)?'':list[0].cyJssm+list[0].cyJsl+'ml,';
  3632. yf += isEmpty(list[0].cyZql)?'':'煮取量'+list[0].cyZql+'ml,';
  3633. yf += isEmpty(list[0].cyFj)?'':'复煎'+list[0].cyFj+'次。';
  3634. yf += isEmpty(list[0].cyFfcs)?'':'分'+list[0].cyFfcs+'次,';
  3635. yf += isEmpty(list[0].cyFysm)?'':list[0].cyFysm;
  3636. tr += '<tr class="sjh">' +
  3637. '<td colspan="6" style="border: 0 !important;text-align: left;padding: 0; font-size: 14px;">'+yf+'</td>' +
  3638. '</tr>';
  3639. return tr;
  3640. }
  3641. function getAjaxRequest (url, data,async, callBack) {
  3642. requestAs(url, "GET", data, async,"application/x-www-form-urlencoded;charset=UTF-8", function(res) {
  3643. return typeof callBack == "function" && callBack(res)
  3644. })
  3645. }
  3646. function requestAs (url, method, data = {},async, contentType, back){
  3647. $.ajax({
  3648. url: url,
  3649. type: method,
  3650. data: data,
  3651. async: async,
  3652. headers:{'Accept': 'application/json','Authorization':'Bearer '+ localStorage.getItem("token")},
  3653. contentType: contentType,
  3654. dataType: "json",
  3655. success: function(res){
  3656. return typeof back == "function" && back(res);
  3657. },
  3658. error: function(error) {
  3659. console.log(error)
  3660. return typeof back == "function" && back(null);
  3661. }
  3662. });
  3663. }
  3664. /**
  3665. * 新的requestAs函数,用于药品追溯码功能
  3666. * @param url 请求URL
  3667. * @param method 请求方法
  3668. * @param data 请求数据
  3669. * @param async 是否异步
  3670. * @param contentType 内容类型
  3671. * @param back 回调函数
  3672. */
  3673. function requestAsNew (url, method, data = {},async, contentType, back){
  3674. $.ajax({
  3675. type: method,
  3676. url: url,
  3677. contentType: contentType,
  3678. dataType: "json",
  3679. async: async,
  3680. headers: {'Accept': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("token")},
  3681. data: data,
  3682. success: function (res) {
  3683. back(res);
  3684. },
  3685. error: function () {
  3686. back(null);
  3687. }
  3688. });
  3689. }
  3690. /**
  3691. * 保存单元格数据
  3692. * @param table 表格对象
  3693. * @param index 行索引
  3694. * @param field 字段名
  3695. * @param value 新值
  3696. */
  3697. function saveCellData(table, index, field, value) {
  3698. table.bootstrapTable('updateCell', {
  3699. index: index,
  3700. field: field,
  3701. value: value
  3702. });
  3703. }
  3704. $(document).ready(function () {
  3705. // ================= 新增:使用统一的重置函数初始化全局变量 =================
  3706. // 目的:确保页面加载时追溯码匹配状态正确初始化
  3707. // 修改时间:2025年
  3708. // 修改原因:统一状态管理,避免状态不一致
  3709. console.log('=== 页面加载,初始化追溯码状态 ===');
  3710. resetTraceabilityState(false, false); // 页面加载时完全重置
  3711. initTbTable();
  3712. });
  3713. /**
  3714. * 验证并添加追溯码
  3715. * @param tracCodg 追溯码
  3716. * @param rowData 行数据
  3717. * @param $element 单元格元素
  3718. */
  3719. function validateAndAddTracCodg(tracCodg, rowData, $element) {
  3720. // 构建验证数据,只包含可以从rowData中获取的字段
  3721. let validateData = {
  3722. drugTracCodg: tracCodg, // 这是用户扫码输入的追溯码
  3723. patientId: rowData.patientId,
  3724. times: rowData.times,
  3725. receiptNo: rowData.receiptNo,
  3726. orderNo: rowData.orderNo,
  3727. itemNo: rowData.itemNo,
  3728. chargeItemCode: rowData.chargeItemCode,
  3729. drugName: rowData.drugname,
  3730. specification: rowData.specification
  3731. };
  3732. // 添加调试日志
  3733. console.log('验证追溯码参数:', validateData);
  3734. console.log('行数据:', rowData);
  3735. $.ajax({
  3736. type: "POST",
  3737. url: '/thmz/validateDrugTracCodgForDispensing',
  3738. contentType: "application/json;charset=UTF-8",
  3739. dataType: "json",
  3740. headers: {
  3741. 'Accept': 'application/json',
  3742. 'Authorization': 'Bearer ' + localStorage.getItem("token")
  3743. },
  3744. data: JSON.stringify(validateData),
  3745. success: function (res) {
  3746. console.log('验证响应:', res);
  3747. if (res.code == 0 && res.data && res.data.isValid) {
  3748. // 验证成功,添加到追溯码集合
  3749. addTracCodgToCell(tracCodg, $element);
  3750. successMesage(res);
  3751. // 验证成功后,保持单元格可编辑状态,用户可以继续扫码
  3752. $element.focus();
  3753. } else {
  3754. // 验证失败
  3755. errorMesage(res);
  3756. // 验证失败时,清理掉无效的追溯码
  3757. let currentContent = $element.html();
  3758. let codes = currentContent.split('<br>').filter(code => code.length > 0);
  3759. // 去掉最后一个追溯码(无效的追溯码)
  3760. if (codes.length > 0) {
  3761. codes.pop();
  3762. // 重新设置单元格内容
  3763. let newContent = codes.join('<br>');
  3764. if (newContent) {
  3765. newContent += '<br>';
  3766. }
  3767. $element.html(newContent);
  3768. // 保持焦点在单元格末尾
  3769. $element.focus();
  3770. let range = document.createRange();
  3771. let selection = window.getSelection();
  3772. range.selectNodeContents($element[0]);
  3773. range.collapse(false);
  3774. selection.removeAllRanges();
  3775. selection.addRange(range);
  3776. }
  3777. }
  3778. },
  3779. error: function (xhr, status, error) {
  3780. console.error('验证请求失败:', error);
  3781. errorMesageSimaple("验证请求失败");
  3782. // 错误时也清理掉无效的追溯码
  3783. let currentContent = $element.html();
  3784. let codes = currentContent.split('<br>').filter(code => code.length > 0);
  3785. // 去掉最后一个追溯码(无效的追溯码)
  3786. if (codes.length > 0) {
  3787. codes.pop();
  3788. // 重新设置单元格内容
  3789. let newContent = codes.join('<br>');
  3790. if (newContent) {
  3791. newContent += '<br>';
  3792. }
  3793. $element.html(newContent);
  3794. // 保持焦点在单元格末尾
  3795. $element.focus();
  3796. let range = document.createRange();
  3797. let selection = window.getSelection();
  3798. range.selectNodeContents($element[0]);
  3799. range.collapse(false);
  3800. selection.removeAllRanges();
  3801. selection.addRange(range);
  3802. }
  3803. }
  3804. });
  3805. }
  3806. /**
  3807. * 添加追溯码到单元格
  3808. * @param tracCodg 追溯码(单个追溯码,不包含分隔符)
  3809. * @param $element 单元格元素
  3810. */
  3811. function addTracCodgToCell(tracCodg, $element) {
  3812. let currentValue = $element.html();
  3813. console.log('addTracCodgToCell 开始');
  3814. console.log('传入的追溯码:', tracCodg);
  3815. console.log('当前单元格内容:', currentValue);
  3816. if (isEmpty(currentValue)) {
  3817. // 如果单元格为空,直接设置追溯码
  3818. console.log('单元格为空,直接设置追溯码');
  3819. $element.html(tracCodg);
  3820. } else {
  3821. // 检查是否已存在该追溯码
  3822. let existingCodes = currentValue.split('<br>');
  3823. console.log('已存在的追溯码列表:', existingCodes);
  3824. console.log('是否已存在:', existingCodes.includes(tracCodg));
  3825. if (!existingCodes.includes(tracCodg)) {
  3826. // 如果不存在,添加<br>分隔符后追加
  3827. let newValue = currentValue + '<br>' + tracCodg;
  3828. console.log('添加追溯码,新内容:', newValue);
  3829. $element.html(newValue);
  3830. } else {
  3831. // 追溯码已存在,显示提示
  3832. console.log('追溯码已存在,显示提示');
  3833. if (typeof PNotify !== 'undefined') {
  3834. new PNotify({
  3835. title: '提示',
  3836. text: '该追溯码已添加',
  3837. type: 'info',
  3838. delay: 2000
  3839. });
  3840. }
  3841. }
  3842. }
  3843. console.log('addTracCodgToCell 结束,最终单元格内容:', $element.html());
  3844. }
  3845. /**
  3846. * 调用医保商品销售接口
  3847. * @param realNo 流水号
  3848. * @param orderNo 处方号
  3849. * @param receiptNo 发票分票号
  3850. * @param times 次数
  3851. * @param patientId 病人ID
  3852. * @param name 病人姓名
  3853. */
  3854. function callYbSaleGoodsItem(realNo, orderNo, receiptNo, times, patientId, name, pharPracCertNo) {
  3855. // 获取处方明细数据
  3856. let tableData = $("#tb_table_right").bootstrapTable('getData');
  3857. console.log("callYbSaleGoodsItem11111111111111111111111",tableData)
  3858. if (!tableData || tableData.length === 0) {
  3859. console.log('没有处方明细数据,跳过医保接口调用');
  3860. return;
  3861. }
  3862. // 获取当前用户信息(药师信息)
  3863. let currentUserName = localStorage.getItem('userName') || '';
  3864. let currentUserId = localStorage.getItem('userID') || '';
  3865. // 获取当前时间
  3866. let currentTime = new Date();
  3867. let selRetnTime = currentTime.getFullYear() + '-' +
  3868. String(currentTime.getMonth() + 1).padStart(2, '0') + '-' +
  3869. String(currentTime.getDate()).padStart(2, '0') + ' ' +
  3870. String(currentTime.getHours()).padStart(2, '0') + ':' +
  3871. String(currentTime.getMinutes()).padStart(2, '0') + ':' +
  3872. String(currentTime.getSeconds()).padStart(2, '0');
  3873. // 为每个药品调用一次医保接口
  3874. for (let i = 0; i < tableData.length; i++) {
  3875. let item = tableData[i];
  3876. // 中药不调用医保销售接口(drug_kind 为 '09' 或 '10')
  3877. if (item.drugKind === '09' || item.drugKind === '10') {
  3878. console.log('中药免医保销售调用,跳过:', item.drugname, 'drugKind=', item.drugKind);
  3879. continue;
  3880. }
  3881. // 构建关联字段组合(用于关联发药记录)
  3882. let currentPatientId = item.patientId || patientId;
  3883. let currentTimes = item.times || times;
  3884. let currentReceiptNo = item.receiptNo || receiptNo;
  3885. let currentOrderNo = item.orderNo || orderNo;
  3886. let chargeItemCode = item.chargeItemCode;
  3887. let currentRealNo = item.realNo || realNo;
  3888. console.log('发药关联键:', {patientId: currentPatientId, times: currentTimes, receiptNo: currentReceiptNo, orderNo: currentOrderNo, chargeItemCode, realNo: currentRealNo});
  3889. // 参数验证
  3890. // 从处方明细数据中获取开方医师姓名
  3891. console.log('处方明细数据item:', item); // 调试日志
  3892. console.log('doctorName字段:', item.doctorName); // 调试日志
  3893. console.log('employeeName字段:', item.employeeName); // 调试日志
  3894. let doctorName = item.doctorName || item.employeeName || '';
  3895. if (!doctorName) {
  3896. console.warn('开方医师姓名为空,使用默认值,item数据:', item);
  3897. doctorName = '未知医师';
  3898. } else {
  3899. console.log('成功获取医生姓名:', doctorName);
  3900. }
  3901. if (!currentUserName) {
  3902. console.warn('药师姓名为空,使用默认值');
  3903. currentUserName = '未知药师';
  3904. }
  3905. // 构建医保接口参数
  3906. let ybData = {
  3907. // 关联字段 - 直接传递到医保接口
  3908. patientId: currentPatientId,
  3909. times: currentTimes,
  3910. receiptNo: currentReceiptNo,
  3911. orderNo: currentOrderNo,
  3912. chargeItemCode: chargeItemCode,
  3913. realNo: currentRealNo,
  3914. // 医疗目录编码(医保编码)
  3915. medListCodg: item.nationalCode,
  3916. // 开方医师姓名
  3917. prscDrName: doctorName,
  3918. // 药师姓名
  3919. pharName: currentUserName,
  3920. // 药师执业资格证号(取当前操作者的药师执业资格证号)
  3921. pharPracCertNo: localStorage.getItem('pharPracCertNo') || '',
  3922. // 销售/退货经办人姓名
  3923. selRetnOpterName: currentUserName,
  3924. // 就诊结算类型(1-医保结算 2-自费结算)
  3925. // 根据处方类型判断:普通处方(1)、特门处方(3)、GCP实验(4)为自费,门诊统筹(2)为医保
  3926. mdtrtSetlType: (item.mdtrtSetlType && item.mdtrtSetlType === 1) ? '1' : '2',
  3927. // 处方药标志
  3928. // rxFlag: item.rxFlag || '1',
  3929. rxFlag: "1",//医院默认都是处方药
  3930. // 拆零标志(0-否;1-是)
  3931. trdnFlag: (item.serial === '99') ? '0' : '1',
  3932. // 患者相关参数(医保接口需要)
  3933. // 人员证件类型
  3934. psnCertType: item.psnCertType || '01',
  3935. // 证件号码
  3936. certno: item.certno || '',
  3937. // 人员姓名
  3938. psnName: item.psnName || item.name || name || '',
  3939. // 销售|退货数量
  3940. selRetnCnt: parseInt(item.quantity) || 0,
  3941. };
  3942. // 追溯码信息
  3943. let drugtracinfo = []
  3944. // 处理追溯码
  3945. if (item.drugTracCodg && item.drugTracCodg !== '') {
  3946. let tracCodes = item.drugTracCodg.split('<br>').filter(code => code !== '');
  3947. for (let j = 0; j < tracCodes.length; j++) {
  3948. drugtracinfo.push({
  3949. drugTracCodg: tracCodes[j]
  3950. });
  3951. }
  3952. }
  3953. // 如果没有追溯码,添加空数组(保持数据结构一致)
  3954. if (drugtracinfo.length === 0) {
  3955. drugtracinfo = [];
  3956. }
  3957. console.log('调用医保接口,药品:', item.drugname, '参数:', ybData);
  3958. let param = {
  3959. selinfoSold: ybData,
  3960. drugtracinfo: drugtracinfo
  3961. }
  3962. // 调用医保接口
  3963. $.ajax({
  3964. type: "POST",
  3965. url: '/thmz/Yb/saleGoodsItem',
  3966. contentType: "application/json;charset=UTF-8",
  3967. dataType: "json",
  3968. headers: {
  3969. 'Accept': 'application/json',
  3970. 'Authorization': 'Bearer ' + localStorage.getItem("token")
  3971. },
  3972. data: JSON.stringify(param),
  3973. success: function (res) {
  3974. console.log('医保接口调用成功:', res);
  3975. if (res.code !== 0) {
  3976. console.error('医保接口调用失败:', res.message);
  3977. // 医保接口失败不影响发药流程,只记录日志
  3978. }
  3979. },
  3980. error: function (xhr, status, error) {
  3981. console.error('医保接口调用失败:', error);
  3982. // 医保接口失败不影响发药流程,只记录日志
  3983. }
  3984. });
  3985. }
  3986. }
  3987. /**
  3988. * 调用医保商品退货接口
  3989. * @param realNo 流水号
  3990. * @param orderNo 处方号
  3991. * @param receiptNo 发票分票号
  3992. * @param times 次数
  3993. * @param patientId 病人ID
  3994. * @param name 病人姓名
  3995. */
  3996. function callYbReturnGoodsItem(realNo, orderNo, receiptNo, times, patientId, name) {
  3997. // 获取退药明细数据 - 直接使用退药表格数据
  3998. let tableData = window.currentRefundData || $table.bootstrapTable('getData');
  3999. if (!tableData || tableData.length === 0) {
  4000. console.log('没有退药明细数据,跳过医保接口调用');
  4001. return;
  4002. }
  4003. // 获取当前用户信息(药师信息)
  4004. let currentUserName = localStorage.getItem('userName') || '';
  4005. let currentUserId = localStorage.getItem('userID') || '';
  4006. // 获取当前时间
  4007. let currentTime = new Date();
  4008. let selRetnTime = currentTime.getFullYear() + '-' +
  4009. String(currentTime.getMonth() + 1).padStart(2, '0') + '-' +
  4010. String(currentTime.getDate()).padStart(2, '0') + ' ' +
  4011. String(currentTime.getHours()).padStart(2, '0') + ':' +
  4012. String(currentTime.getMinutes()).padStart(2, '0') + ':' +
  4013. String(currentTime.getSeconds()).padStart(2, '0');
  4014. // 为每个退药药品调用一次医保接口
  4015. console.log('开始处理退药数据,总数:', tableData.length);
  4016. for (let i = 0; i < tableData.length; i++) {
  4017. let item = tableData[i];
  4018. console.log('处理第', i + 1, '条退药记录:', {
  4019. 'drugname': item.drugname,
  4020. 'dec_amount': item.dec_amount,
  4021. 'charge_item_code': item.charge_item_code,
  4022. 'serial': item.serial,
  4023. 'item_no': item.item_no
  4024. });
  4025. // 只处理有退药数量的药品
  4026. if (item.dec_amount == 0) {
  4027. console.log('跳过数量为0的药品:', item.drugname);
  4028. continue;
  4029. }
  4030. // 新增:中药不调用医保退药接口(drugKind 为 '09' 或 '10')
  4031. if (item.drugKind === '09' || item.drugKind === '10') {
  4032. console.log('中药免医保退药调用,跳过:', item.drugname, 'drugKind=', item.drugKind);
  4033. continue;
  4034. }
  4035. // 获取医生姓名
  4036. let doctorName = item.doctor_name || item.name || '';
  4037. if (!doctorName) {
  4038. doctorName = '未知医生';
  4039. }
  4040. // 构建医保接口参数
  4041. let ybData = {
  4042. // 关联字段 - 直接传递到医保接口
  4043. patientId: patientId,
  4044. times: times,
  4045. receiptNo: receiptNo,
  4046. orderNo: orderNo,
  4047. chargeItemCode: item.charge_item_code,
  4048. realNo: realNo,
  4049. // // 医疗目录编码(医保编码)
  4050. // medListCodg: item.nationalCode || 'NMLC999',
  4051. // 销售/退货经办人姓名(必填参数)
  4052. selRetnOpterName: currentUserName,
  4053. // // 销售/退货数量
  4054. // selRetnCnt: item.dec_amount,
  4055. // // 销售/退货时间
  4056. // selRetnTime: selRetnTime,
  4057. // // 最终成交单价
  4058. // finlTrnsPric: item.unit_price,
  4059. // // 处方药标志
  4060. // rxFlag: item.rxFlag || '1',
  4061. // rxFlag: '1',//医院默认都是处方药
  4062. // // 拆零标志(0-否;1-是)
  4063. // trdnFlag: item.clFlag || '0',
  4064. // 追溯码信息
  4065. drugtracinfo: []
  4066. };
  4067. // ================= 新增:根据拆零标志控制追溯码上传与否 =================
  4068. // 非中药且拆零(serial='01'):调用医保,但不上传追溯码(数组留空)
  4069. // 非中药且不拆零(serial='99'):上传本次已扫描匹配到的追溯码
  4070. if (item.serial === '99') {
  4071. let drugCode = item.charge_item_code;
  4072. let scannedCodes = scannedCodesMap[drugCode] || [];
  4073. // 安全起见,限制上传数量不超过退药数量
  4074. let needCount = parseInt(item.dec_amount) || scannedCodes.length;
  4075. let uploadCodes = scannedCodes.slice(0, needCount);
  4076. console.log('非拆零上传追溯码:', uploadCodes);
  4077. for (let k = 0; k < uploadCodes.length; k++) {
  4078. ybData.drugtracinfo.push({
  4079. drugTracCodg: uploadCodes[k]
  4080. });
  4081. }
  4082. } else {
  4083. console.log('拆零药品调用医保退药但不上传追溯码:', item.drugname);
  4084. // 新增:拆零药品需要上传退药数量(与发药数量字段一致语义)
  4085. try {
  4086. ybData.selRetnCnt = parseInt(item.dec_amount) || 0;
  4087. } catch(e) {
  4088. ybData.selRetnCnt = 0;
  4089. }
  4090. }
  4091. console.log('医保接口追溯码参数:', ybData.drugtracinfo);
  4092. // 直接调用医保接口,无需异步查询
  4093. callYbReturnGoodsItemWithData(ybData, item);
  4094. // ================= 原逻辑(已屏蔽,如需恢复请取消注释) =================
  4095. /*
  4096. // 原逻辑:从数据库查询所有追溯码
  4097. // 屏蔽原因:会返回所有追溯码而不是用户实际扫描的追溯码
  4098. // 屏蔽时间:2025年
  4099. // 主动获取追溯码信息(退药后从退药追溯码表查询)
  4100. let tracCodgParams = {
  4101. patientId: patientId,
  4102. times: times,
  4103. receiptNo: receiptNo,
  4104. orderNo: orderNo,
  4105. chargeItemCode: item.charge_item_code,
  4106. serial: item.serial,
  4107. itemNo: item.item_no,
  4108. groupNo: item.group_no || groupNo
  4109. };
  4110. console.log("调用退药医保接口tracCodgParams000000000000000000000",tracCodgParams)
  4111. // 调用追溯码查询接口(异步方式)
  4112. // 注意:退药处理后,追溯码已转移到 mz_drug_trac_codg_ty 表
  4113. $.ajax({
  4114. type: "POST",
  4115. url: '/thmz/getMzDrugTracCodgTyData',
  4116. contentType: "application/json;charset=UTF-8",
  4117. dataType: "json",
  4118. headers: {
  4119. 'Accept': 'application/json',
  4120. 'Authorization': 'Bearer ' + localStorage.getItem("token")
  4121. },
  4122. data: JSON.stringify(tracCodgParams),
  4123. success: function (tracRes) {
  4124. console.log('追溯码查询结果:', tracRes);
  4125. if (tracRes.code === 0 && tracRes.data && tracRes.data.length > 0) {
  4126. // 将追溯码添加到医保接口参数中
  4127. for (let k = 0; k < tracRes.data.length; k++) {
  4128. let tracItem = tracRes.data[k];
  4129. if (tracItem.drugTracCodg && tracItem.drugTracCodg !== '') {
  4130. ybData.drugtracinfo.push({
  4131. drugTracCodg: tracItem.drugTracCodg
  4132. });
  4133. }
  4134. }
  4135. console.log('成功获取追溯码:', ybData.drugtracinfo);
  4136. } else {
  4137. console.log('未找到追溯码信息');
  4138. }
  4139. // 追溯码查询完成后,调用医保接口
  4140. callYbReturnGoodsItemWithData(ybData, item);
  4141. },
  4142. error: function (xhr, status, error) {
  4143. console.error('追溯码查询失败:', error);
  4144. // 即使追溯码查询失败,也要调用医保接口
  4145. callYbReturnGoodsItemWithData(ybData, item);
  4146. }
  4147. });
  4148. */
  4149. // ================= 原逻辑结束 =================
  4150. }
  4151. }
  4152. /**
  4153. * 调用医保退药接口(带追溯码数据)
  4154. * @param ybData 医保接口参数
  4155. * @param item 退药药品信息
  4156. */
  4157. function callYbReturnGoodsItemWithData(ybData, item) {
  4158. // 如果没有追溯码,添加空数组(保持数据结构一致)
  4159. if (ybData.drugtracinfo.length === 0) {
  4160. ybData.drugtracinfo = [];
  4161. }
  4162. console.log('调用医保退药接口,药品:', item.drugname, '参数:', ybData);
  4163. // 调用医保接口
  4164. $.ajax({
  4165. type: "POST",
  4166. url: '/thmz/Yb/returnGoodsItem',
  4167. contentType: "application/json;charset=UTF-8",
  4168. dataType: "json",
  4169. headers: {
  4170. 'Accept': 'application/json',
  4171. 'Authorization': 'Bearer ' + localStorage.getItem("token")
  4172. },
  4173. data: JSON.stringify(ybData),
  4174. success: function (res) {
  4175. console.log('医保退药接口调用成功:', res);
  4176. if (res.code !== 0) {
  4177. console.error('医保退药接口调用失败:', res.message);
  4178. // 医保接口失败不影响退药流程,只记录日志
  4179. }
  4180. },
  4181. error: function (xhr, status, error) {
  4182. console.error('医保退药接口调用失败:', error);
  4183. // 医保接口失败不影响退药流程,只记录日志
  4184. }
  4185. });
  4186. }
  4187. /**
  4188. * 验证追溯码数量与处方数量的匹配情况
  4189. * @param realNo 流水号
  4190. * @param orderNo 处方号
  4191. * @param receiptNo 发票分票号
  4192. * @param times 次数
  4193. * @param patientId 病人ID
  4194. * @param name 病人姓名
  4195. * @param pharPracCertNo 药师执业资格证号
  4196. */
  4197. function validateTracCodgQuantity(realNo, orderNo, receiptNo, times, patientId, name, pharPracCertNo) {
  4198. // 获取处方明细表格数据
  4199. let tableData = $("#tb_table_right").bootstrapTable('getData');
  4200. let mismatchDetails = [];
  4201. let hasMismatch = false;
  4202. console.log('开始验证追溯码数量,表格数据:', tableData);
  4203. // 遍历每种药品,检查追溯码数量
  4204. for (let i = 0; i < tableData.length; i++) {
  4205. let drug = tableData[i];
  4206. let prescriptionQuantity = parseInt(drug.quantity) || 0; // 处方数量
  4207. let tracCodgCount = 0; // 追溯码数量
  4208. // 中药免校验:drug_kind 为 '09' 或 '10' 时,跳过追溯码数量检查
  4209. if (drug.drugKind === '09' || drug.drugKind === '10') {
  4210. continue;
  4211. }
  4212. // 计算该药品的追溯码数量
  4213. if (!isEmpty(drug.drugTracCodg)) {
  4214. // 按<br>分割追溯码,过滤空值
  4215. let tracCodgList = drug.drugTracCodg.split('<br>').filter(code => code.length > 0);
  4216. tracCodgCount = tracCodgList.length;
  4217. }
  4218. console.log('药品:', drug.drugname, '处方数量:', prescriptionQuantity, '追溯码数量:', tracCodgCount, '拆零状态:', drug.serial);
  4219. // ================= 修改:根据药品类型区分验证逻辑 =================
  4220. // 目的:拆零药品必须上传一个追溯码,不拆零药品维持原样
  4221. // 判断逻辑:serial="01"为拆零药品,serial="99"为不拆零药品
  4222. let isSplitDrug = (drug.serial === '01'); // 拆零药品
  4223. let isNonSplitDrug = (drug.serial === '99'); // 不拆零药品
  4224. // 拆零药品必须上传至少一个追溯码
  4225. if (isSplitDrug && tracCodgCount === 0) {
  4226. hasMismatch = true;
  4227. let mismatchInfo = {
  4228. drugName: drug.drugname,
  4229. prescriptionQuantity: prescriptionQuantity,
  4230. tracCodgCount: tracCodgCount,
  4231. difference: -prescriptionQuantity, // 缺少所有数量
  4232. isSplitDrug: isSplitDrug
  4233. };
  4234. mismatchDetails.push(mismatchInfo);
  4235. console.log('拆零药品【' + drug.drugname + '】必须上传至少一个追溯码');
  4236. }
  4237. // 不拆零药品检查追溯码数量是否匹配
  4238. if (isNonSplitDrug && tracCodgCount !== prescriptionQuantity) {
  4239. hasMismatch = true;
  4240. let mismatchInfo = {
  4241. drugName: drug.drugname,
  4242. prescriptionQuantity: prescriptionQuantity,
  4243. tracCodgCount: tracCodgCount,
  4244. difference: tracCodgCount - prescriptionQuantity,
  4245. isSplitDrug: isSplitDrug
  4246. };
  4247. mismatchDetails.push(mismatchInfo);
  4248. }
  4249. // ================= 修改结束 =================
  4250. }
  4251. // 如果有不匹配的情况,显示确认弹框
  4252. if (hasMismatch) {
  4253. // 存储发药参数,供确认后使用
  4254. window.pendingSendParams = {
  4255. realNo: realNo,
  4256. orderNo: orderNo,
  4257. receiptNo: receiptNo,
  4258. times: times,
  4259. patientId: patientId,
  4260. name: name,
  4261. pharPracCertNo: pharPracCertNo
  4262. };
  4263. // 构建不匹配详情HTML
  4264. let detailsHtml = '<div class="table-responsive"><table class="table table-bordered table-striped">';
  4265. detailsHtml += '<thead><tr><th>药品名称</th><th>处方数量</th><th>追溯码数量</th><th>差异</th></tr></thead><tbody>';
  4266. for (let i = 0; i < mismatchDetails.length; i++) {
  4267. let detail = mismatchDetails[i];
  4268. let differenceText = '';
  4269. let rowClass = '';
  4270. if (detail.difference > 0) {
  4271. differenceText = '<span style="color: orange;">多输入 ' + detail.difference + ' 个</span>';
  4272. rowClass = 'warning';
  4273. } else if (detail.difference < 0) {
  4274. differenceText = '<span style="color: red;">缺少 ' + Math.abs(detail.difference) + ' 个</span>';
  4275. rowClass = 'danger';
  4276. }
  4277. detailsHtml += '<tr class="' + rowClass + '">';
  4278. detailsHtml += '<td>' + detail.drugName + '</td>';
  4279. detailsHtml += '<td>' + detail.prescriptionQuantity + '</td>';
  4280. detailsHtml += '<td>' + detail.tracCodgCount + '</td>';
  4281. detailsHtml += '<td>' + differenceText + '</td>';
  4282. detailsHtml += '</tr>';
  4283. }
  4284. detailsHtml += '</tbody></table></div>';
  4285. // 显示确认弹框
  4286. $('#tracCodgMismatchDetails').html(detailsHtml);
  4287. $('#tracCodgConfirmModal').modal('show');
  4288. console.log('追溯码数量不匹配,显示确认弹框:', mismatchDetails);
  4289. } else {
  4290. // 数量匹配,直接发药
  4291. console.log('追溯码数量匹配,直接发药');
  4292. sendMedicineProcessing(realNo, orderNo, receiptNo, times, patientId, name, pharPracCertNo);
  4293. }
  4294. }
  4295. /**
  4296. * 调用撤销退药医保接口(销售接口)
  4297. * @param realNo 流水号
  4298. * @param orderNo 处方号
  4299. * @param receiptNo 发票分票号
  4300. * @param times 次数
  4301. * @param patientId 病人ID
  4302. * @param name 病人姓名
  4303. */
  4304. function callYbSaleGoodsItemForCancelRefund(realNo, orderNo, receiptNo, times, patientId, name, doctorName) {
  4305. console.log('=== 开始调用撤销退药医保接口 ===');
  4306. // 获取当前用户信息(药师信息)
  4307. let currentUserName = localStorage.getItem('userName') || '';
  4308. let pharPracCertNo = localStorage.getItem('pharPracCertNo') || '';
  4309. // 构建调用新接口的参数
  4310. let params = {
  4311. patientId: patientId,
  4312. times: times,
  4313. receiptNo: receiptNo,
  4314. orderNo: orderNo,
  4315. groupNoOut: groupNo,
  4316. // 添加医生姓名、药师姓名和药师执业资格证号
  4317. doctorName: doctorName, // 医生姓名,从处方明细中获取
  4318. pharName: currentUserName, // 药师姓名
  4319. pharPracCertNo: pharPracCertNo // 药师执业资格证号
  4320. };
  4321. console.log('撤销退药医保接口参数:', params);
  4322. // 调用新的撤销退药医保接口
  4323. $.ajax({
  4324. type: "POST",
  4325. url: '/thmz/cancelRefundWithYb',
  4326. contentType: "application/json;charset=UTF-8",
  4327. dataType: "json",
  4328. headers: {
  4329. 'Accept': 'application/json',
  4330. 'Authorization': 'Bearer ' + localStorage.getItem("token")
  4331. },
  4332. data: JSON.stringify(params),
  4333. success: function (res) {
  4334. console.log('撤销退药医保接口调用结果:', res);
  4335. if (res.code === 0) {
  4336. successMesage(res);
  4337. console.log('撤销退药医保接口调用成功');
  4338. } else {
  4339. errorMesage(res);
  4340. console.error('撤销退药医保接口调用失败:', res.message);
  4341. }
  4342. },
  4343. error: function (xhr, status, error) {
  4344. console.error('撤销退药医保接口调用异常:', error);
  4345. errorMesage({message: '撤销退药医保接口调用异常:' + error});
  4346. }
  4347. });
  4348. }