1871 84 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874
  1. Import SQLUSER
  2. /// Creator: 系统
  3. /// CreatDate: 2026-09-17
  4. /// Description: 报表服务类(承载各类报表,与 src.DRG.Profit 同级)
  5. ///
  6. /// 接口Code规范: 020106xx
  7. /// 02010601 可比就诊检索(已完成首页分组的就诊列表,供勾选加入比对)
  8. /// 02010602 病组费用比对(2~5 例并列:结算清单汇总列 / HIS明细项目 / 结算类别聚合
  9. /// + 诊断 / 手术 / DRG支付标准 + 中文文字分析报告)
  10. /// 02010603 重复收费汇总统计(按收费项目类型/收费项目,双比重 + 全局KPI)
  11. /// 02010604 重复收费明细查询(按重复组分页,同组同色号)
  12. /// 02010605 单次就诊费用信息(明细 + 双维度汇总 + 重复分组统计,只读不触发HIS同步)
  13. ///
  14. /// 数据来源:
  15. /// BS_DRGMedInsuMedicalRecord (MR) 医保结算明细(28 项费用列 + MedfeeSumamt、DRG/DRGDesc、HISAdmID、
  16. /// MedcasNo、MdtrtId、PsnNo、AdmDate、DscgDate、ImageURL、FixmedinsCode、ValiFlag)
  17. /// BS_HISPatAdm (PA) 住院就诊(科室 InLocCode/InLocDesc、医生 AdmDocCode/AdmDocDesc、
  18. /// 险种 InsuType;关联键 PA.AdmID = MR.HISAdmID)
  19. /// BS_HISFeeDetail (FD) HIS费用明细流水(MedinsListCodg/Desc、EcCode/EcDesc、Cnt、DetItemFeeSumamt;
  20. /// 关联键 FD.AdmID = MR.HISAdmID;有效口径 Deleted=0 且 ValidFlag 非 'N')
  21. /// BS_HISDiseInfo 诊断(AdmID 关联;DiagCode/DiagName/MainFlag/DiagSn;无 Deleted 字段)
  22. /// BS_HISOprnInfo 手术(AdmID 关联;OprnCode/OprnName/MainFlag/OprnSn;无 Deleted 字段)
  23. /// BS_DRGGroupRecord (GR) DRG分组(BenchmarkCost 支付标准、Weight 权重、DRG/DRGDesc、ActiveFlag)
  24. /// CB_DRGDictTable 险种字典(父记录 Code='INSU_TYPE',子记录 Code/Name)
  25. ///
  26. /// 已完成首页分组口径(02010601 固定附加,四条同时满足):MR.ValiFlag 非 '0';
  27. /// MR.ImageURL 非空;MR.DRG 非空(IS NOT NULL 且 <> '',主表 DRG 必须有值);
  28. /// EXISTS(BS_DRGGroupRecord g: g.AdmID = MR.HISAdmID AND g.ActiveFlag='1' AND g.DRG<>'')
  29. /// SQL 约束:本环境不支持 WITH(CTE)、ORDER BY 聚合表达式与列序号;聚合排序一律在 ObjectScript 侧完成
  30. Class src.DRG.Report Extends (%RegisteredObject, %XML.Adaptor) [ Not ProcedureBlock ]
  31. {
  32. /// Description: 通用成功结果封装
  33. ClassMethod SetSuccessResult(code As %String, message As %String) As %Library.DynamicObject
  34. {
  35. new resultObj
  36. set resultObj = {}
  37. set resultObj.errorCode = code
  38. set resultObj.errorMessage = message
  39. set resultObj.result = {}
  40. quit resultObj
  41. }
  42. /// Description: 通用错误结果封装
  43. ClassMethod SetErrorResult(errorCode As %String, errorMsg As %String) As %Library.DynamicObject
  44. {
  45. new resultObj
  46. set resultObj = {}
  47. set resultObj.errorCode = errorCode
  48. set resultObj.errorMessage = errorMsg
  49. set resultObj.result = {}
  50. quit resultObj
  51. }
  52. /// Description: 解析分页参数(pagination[0].pageSize / currentPage,缺省 20 / 1)
  53. ClassMethod %GetPage(jsonObj As %Library.DynamicObject) As %Library.DynamicObject
  54. {
  55. new pg, pagination
  56. set pg = {}
  57. set pg.pageSize = 20
  58. set pg.currentPage = 1
  59. if (jsonObj.%IsDefined("pagination") '= 0) {
  60. set pagination = jsonObj.pagination.%Get(0)
  61. if (pagination.pageSize '= "") set pg.pageSize = pagination.pageSize
  62. if (pagination.currentPage '= "") set pg.currentPage = pagination.currentPage
  63. }
  64. quit pg
  65. }
  66. /// Description: 内存分页:对结果数组做切片,返回 {rows, total}
  67. ClassMethod %Paginate(all As %Library.DynamicArray, pg As %Library.DynamicObject) As %Library.DynamicObject
  68. {
  69. new out, total, startIdx, rows, i
  70. set out = {}
  71. set total = all.%Size()
  72. set startIdx = (pg.currentPage - 1) * pg.pageSize
  73. if (startIdx < 0) set startIdx = 0
  74. set rows = []
  75. for i = startIdx:1:(startIdx + pg.pageSize - 1) {
  76. if (i >= total) quit
  77. do rows.%Push(all.%Get(i))
  78. }
  79. set out.rows = rows
  80. set out.total = total
  81. quit out
  82. }
  83. /// Description: 统一异常处理:记录错误日志并返回中文错误结果
  84. ClassMethod %HandleError(methodName As %String, code As %String, jsonObj As %Library.DynamicObject, status As %Status) As %Library.DynamicObject
  85. {
  86. new errorMsg, errorInfo, errorLogID, resultObj
  87. set errorMsg = $replace(##class(%SYSTEM.Status).GetErrorText(status, "cn"), "^", " ")
  88. set errorInfo = methodName _ "异常:类=" _ $ClassName() _ ",入参=" _ jsonObj.%ToJSON() _ ",错误:" _ errorMsg
  89. set errorLogID = ##class(src.Interface.Message).InsErrRecord(code, errorInfo, errorMsg)
  90. set resultObj = {}
  91. set resultObj.errorCode = code
  92. set resultObj.errorMessage = methodName _ "异常(日志ID:" _ errorLogID _ "):" _ errorMsg
  93. set resultObj.result = {}
  94. quit resultObj
  95. }
  96. /// Description: 险种编码转中文名(查 CB_DRGDictTable 自关联);查不到回落为编码原值
  97. ClassMethod %GetInsuTypeName(code As %String) As %String
  98. {
  99. new sqlObj, sc, rs, name
  100. if (code = "") quit ""
  101. set sqlObj = ##class(%SQL.Statement).%New(1)
  102. set sc = sqlObj.%Prepare("SELECT b.Name AS Name FROM CB_DRGDictTable a INNER JOIN CB_DRGDictTable b ON a.ID = b.Parent_Dr WHERE a.Parent_Dr IS NULL AND a.Code = 'INSU_TYPE' AND a.Status = 'Y' AND b.Code = ?")
  103. if ('$$$ISOK(sc)) quit code
  104. set rs = sqlObj.%Execute(code)
  105. if (rs.%Next()) {
  106. set name = rs.%Get("Name")
  107. if (name '= "") quit name
  108. }
  109. quit code
  110. }
  111. /// Description: 将就诊号数组拼成 SQL IN 列表(每个元素做单引号转义防注入)
  112. ClassMethod %BuildIn(arr As %Library.DynamicArray) As %String
  113. {
  114. new inList, i, v
  115. set inList = ""
  116. for i = 0:1:(arr.%Size() - 1) {
  117. set v = arr.%Get(i)
  118. if (v = "") continue
  119. if (inList '= "") set inList = inList _ ","
  120. set inList = inList _ "'" _ $REPLACE(v, "'", "") _ "'"
  121. }
  122. quit inList
  123. }
  124. /// Description: 构建可比就诊检索的公共过滤条件
  125. /// 基础口径:MR 有效 + 病案首页已入库(ImageURL<>'') + 存在有效 DRG 分组记录
  126. /// 追加:普通区(机构/DRG编码/入院或出院日期区间)与高级区(患者/病案/就诊/流水号/个人编号/险种/主诊断/主手术)
  127. /// 注意:险种 InsuType 存于 BS_HISPatAdm(PA),主 SQL 必须 INNER JOIN PA
  128. ClassMethod %BuildVisitWhere(params As %Library.DynamicObject) As %String
  129. {
  130. new w, v, dateType, dateCol
  131. set w = " WHERE (MR.ValiFlag IS NULL OR MR.ValiFlag = '1')"
  132. _ " AND (MR.ImageURL IS NOT NULL AND MR.ImageURL <> '')"
  133. _ " AND (MR.DRG IS NOT NULL AND MR.DRG <> '')"
  134. _ " AND EXISTS (SELECT 1 FROM BS_DRGGroupRecord g WHERE g.AdmID = MR.HISAdmID AND g.ActiveFlag = '1' AND g.DRG <> '')"
  135. set v = params.fixmedinsCode
  136. if (v '= "") set w = w _ " AND MR.FixmedinsCode = '" _ $REPLACE(v, "'", "") _ "'"
  137. set v = params.drgCode
  138. if (v '= "") set w = w _ " AND MR.DRG = '" _ $REPLACE(v, "'", "") _ "'"
  139. set dateType = params.dateType
  140. set dateCol = $CASE(dateType, "discharge" : "MR.DscgDate", : "MR.AdmDate")
  141. set v = params.startDate
  142. if (v '= "") set w = w _ " AND " _ dateCol _ " >= '" _ $REPLACE(v, "'", "") _ "'"
  143. set v = params.endDate
  144. if (v '= "") set w = w _ " AND " _ dateCol _ " <= '" _ $REPLACE(v, "'", "") _ " 23:59:59'"
  145. set v = params.patName
  146. if (v '= "") set w = w _ " AND MR.PsnName LIKE '%" _ $REPLACE(v, "'", "") _ "%'"
  147. set v = params.medcasNo
  148. if (v '= "") set w = w _ " AND MR.MedcasNo = '" _ $REPLACE(v, "'", "") _ "'"
  149. set v = params.admID
  150. if (v '= "") set w = w _ " AND MR.HISAdmID = '" _ $REPLACE(v, "'", "") _ "'"
  151. set v = params.mdtrtId
  152. if (v '= "") set w = w _ " AND MR.MdtrtId = '" _ $REPLACE(v, "'", "") _ "'"
  153. set v = params.psnNo
  154. if (v '= "") set w = w _ " AND MR.PsnNo LIKE '%" _ $REPLACE(v, "'", "") _ "%'"
  155. set v = params.insuType
  156. if (v '= "") set w = w _ " AND PA.InsuType = '" _ $REPLACE(v, "'", "") _ "'"
  157. set v = params.mainDiagCode
  158. if (v '= "") set w = w _ " AND EXISTS (SELECT 1 FROM BS_HISDiseInfo d WHERE d.AdmID = MR.HISAdmID AND d.MainFlag = 1 AND d.DiagCode = '" _ $REPLACE(v, "'", "") _ "')"
  159. set v = params.mainDiagName
  160. if (v '= "") set w = w _ " AND EXISTS (SELECT 1 FROM BS_HISDiseInfo d WHERE d.AdmID = MR.HISAdmID AND d.MainFlag = 1 AND d.DiagName LIKE '%" _ $REPLACE(v, "'", "") _ "%')"
  161. set v = params.mainOprnCode
  162. if (v '= "") set w = w _ " AND EXISTS (SELECT 1 FROM BS_HISOprnInfo o WHERE o.AdmID = MR.HISAdmID AND o.MainFlag = 'Y' AND o.OprnCode = '" _ $REPLACE(v, "'", "") _ "')"
  163. set v = params.mainOprnName
  164. if (v '= "") set w = w _ " AND EXISTS (SELECT 1 FROM BS_HISOprnInfo o WHERE o.AdmID = MR.HISAdmID AND o.MainFlag = 'Y' AND o.OprnName LIKE '%" _ $REPLACE(v, "'", "") _ "%')"
  165. quit w
  166. }
  167. /// Description: 计算单个比对单元格的差异标记
  168. /// @param value 本例金额
  169. /// @param baseValue 基准金额(首条值 或 各例均值)
  170. /// @param exists 本例是否存在该行
  171. /// @param existsCount 全部病例中存在该行的例数
  172. /// @return $LB(diffFlag, diffAmount, diffRate)
  173. /// missing=本例无该项 / onlyIn=仅本例有 / diff=有差异 / same=一致(2 位小数容差)
  174. ClassMethod %CalcDiff(value As %Numeric, baseValue As %Numeric, exists As %Boolean, existsCount As %Integer) As %List
  175. {
  176. new diffAmount, diffRate
  177. if ('exists) quit $LB("missing", 0, 0)
  178. if (existsCount <= 1) quit $LB("onlyIn", +$FN(value, "", 2), 0)
  179. if ($FN(value, "", 2) = $FN(baseValue, "", 2)) quit $LB("same", 0, 0)
  180. set diffAmount = +$FN(value - baseValue, "", 2)
  181. set diffRate = 0
  182. if (baseValue '= 0) set diffRate = +$FN((diffAmount / baseValue) * 100, "", 2)
  183. quit $LB("diff", diffAmount, diffRate)
  184. }
  185. /// Creator: 系统
  186. /// CreatDate: 2026-09-17
  187. /// Description: 可比就诊检索(已完成首页分组的就诊列表,供勾选加入比对)
  188. /// Code: 02010601
  189. /// Input: {"params":[{"fixmedinsCode":"","dateType":"adm","startDate":"","endDate":"","drgCode":"",
  190. /// "patName":"","medcasNo":"","admID":"","mdtrtId":"","psnNo":"","insuType":"",
  191. /// "mainDiagCode":"","mainDiagName":"","mainOprnCode":"","mainOprnName":""}],
  192. /// "pagination":[{"pageSize":20,"currentPage":1}]}
  193. /// Output: {errorCode:"0", errorMessage:"", result:{rows:[{admID,medcasNo,patName,...,payStandard,insuType,insuTypeCode}], total:N}}
  194. ClassMethod QueryComparableVisits(jsonObj As %Library.DynamicObject) As %Library.DynamicObject
  195. {
  196. new (jsonObj)
  197. set resultObj = {"errorCode":"0","errorMessage":"","result":{}}
  198. try
  199. {
  200. if (jsonObj = "") || (jsonObj.params = "") {
  201. set resultObj = ..SetErrorResult("-1", "入参异常:缺少params参数或参数为空")
  202. quit
  203. }
  204. set pg = ..%GetPage(jsonObj)
  205. set params = jsonObj.params.%Get(0)
  206. set fixmedinsCode = params.fixmedinsCode
  207. set startDate = params.startDate
  208. set endDate = params.endDate
  209. set admID = params.admID
  210. set medcasNo = params.medcasNo
  211. set mdtrtId = params.mdtrtId
  212. if (fixmedinsCode = "") && (startDate = "") && (endDate = "") && (admID = "") && (medcasNo = "") && (mdtrtId = "") {
  213. set resultObj = ..SetErrorResult("-1", "查询条件不足:请至少提供机构代码、日期区间或就诊标识之一")
  214. quit
  215. }
  216. set w = ..%BuildVisitWhere(params)
  217. set baseFrom = " FROM BS_DRGMedInsuMedicalRecord MR INNER JOIN BS_HISPatAdm PA ON PA.AdmID = MR.HISAdmID " _ w
  218. set sqlObj = ##class(%SQL.Statement).%New(1)
  219. set sc = sqlObj.%Prepare("SELECT COUNT(*) AS total " _ baseFrom)
  220. if ('$$$ISOK(sc)) {
  221. set resultObj = ..%HandleError("查询可比就诊", "02010601", jsonObj, sc)
  222. quit
  223. }
  224. set rs = sqlObj.%Execute()
  225. set total = 0
  226. if (rs.%Next()) set total = +rs.%Get("total")
  227. if (total = 0) {
  228. set resultObj.result = {"rows":[], "total":0}
  229. quit
  230. }
  231. set sql = "SELECT MR.HISAdmID AS admID, MR.MedcasNo AS medcasNo, MR.PsnName AS patName, MR.Gend AS gend, MR.Age AS age,"
  232. _ " MR.AdmDate AS admDate, MR.DscgDate AS dscgDate, MR.IptDays AS iptDays, MR.DRG AS drgCode, MR.DRGDesc AS drgName,"
  233. _ " MR.MedfeeSumamt AS medfeeSumamt, MR.PsnNo AS psnNo, MR.MdtrtId AS mdtrtId, MR.FixmedinsCode AS fixmedinsCode,"
  234. _ " PA.InsuType AS insuTypeCode, PA.InLocCode AS deptCode, PA.InLocDesc AS deptName,"
  235. _ " PA.AdmDocCode AS doctorCode, PA.AdmDocDesc AS doctorName"
  236. _ baseFrom _ " ORDER BY MR.AdmDate DESC, MR.ID DESC"
  237. set sc = sqlObj.%Prepare(sql)
  238. if ('$$$ISOK(sc)) {
  239. set resultObj = ..%HandleError("查询可比就诊列表", "02010601", jsonObj, sc)
  240. quit
  241. }
  242. set rs = sqlObj.%Execute()
  243. set all = []
  244. while (rs.%Next()) {
  245. set r = {}
  246. set r.admID = rs.%Get("admID")
  247. set r.medcasNo = rs.%Get("medcasNo")
  248. set r.patName = rs.%Get("patName")
  249. set r.gend = rs.%Get("gend")
  250. set r.age = +rs.%Get("age")
  251. set r.admDate = rs.%Get("admDate")
  252. set r.dscgDate = rs.%Get("dscgDate")
  253. set r.iptDays = +rs.%Get("iptDays")
  254. set r.drgCode = rs.%Get("drgCode")
  255. set r.drgName = rs.%Get("drgName")
  256. set r.medfeeSumamt = +rs.%Get("medfeeSumamt")
  257. set r.psnNo = rs.%Get("psnNo")
  258. set r.mdtrtId = rs.%Get("mdtrtId")
  259. set r.fixmedinsCode = rs.%Get("fixmedinsCode")
  260. set r.insuTypeCode = rs.%Get("insuTypeCode")
  261. set r.deptCode = rs.%Get("deptCode")
  262. set r.deptName = rs.%Get("deptName")
  263. set r.doctorCode = rs.%Get("doctorCode")
  264. set r.doctorName = rs.%Get("doctorName")
  265. set r.payStandard = 0
  266. do all.%Push(r)
  267. }
  268. set paged = ..%Paginate(all, pg)
  269. set paged.total = total
  270. // 支付标准:独立按 AdmID 聚合回填(避免 JOIN 放大行数)
  271. set pageIds = []
  272. set rows = paged.rows
  273. for i = 0:1:(rows.%Size() - 1) {
  274. do pageIds.%Push(rows.%Get(i).admID)
  275. }
  276. if (pageIds.%Size() > 0) {
  277. kill payStd
  278. set sc = sqlObj.%Prepare("SELECT AdmID, MAX(BenchmarkCost) AS PayStd FROM BS_DRGGroupRecord WHERE ActiveFlag = '1' AND AdmID IN (" _ ..%BuildIn(pageIds) _ ") GROUP BY AdmID")
  279. if ('$$$ISOK(sc)) {
  280. set resultObj = ..%HandleError("查询可比就诊支付标准", "02010601", jsonObj, sc)
  281. quit
  282. }
  283. set rs = sqlObj.%Execute()
  284. while (rs.%Next()) {
  285. set payStd(rs.%Get("AdmID")) = +rs.%Get("PayStd")
  286. }
  287. for i = 0:1:(rows.%Size() - 1) {
  288. set r = rows.%Get(i)
  289. set r.payStandard = +$get(payStd(r.admID), 0)
  290. set r.insuType = ..%GetInsuTypeName(r.insuTypeCode)
  291. do rows.%Set(i, r)
  292. }
  293. }
  294. set resultObj.result = paged
  295. }
  296. catch(e)
  297. {
  298. set resultObj = ..%HandleError("查询可比就诊", "02010601", jsonObj, e.AsStatus())
  299. }
  300. quit resultObj
  301. }
  302. /// Creator: 系统
  303. /// CreatDate: 2026-09-17
  304. /// Description: 病组费用比对(三维度费用 + 诊断/手术/支付标准 + 中文文字分析报告)
  305. /// Code: 02010602
  306. ClassMethod CompareDRGFee(jsonObj As %Library.DynamicObject) As %Library.DynamicObject
  307. {
  308. new (jsonObj)
  309. set resultObj = {"errorCode":"0","errorMessage":"","result":{}}
  310. try
  311. {
  312. if (jsonObj = "") || (jsonObj.params = "") {
  313. set resultObj = ..SetErrorResult("-1", "入参异常:缺少params参数或参数为空")
  314. quit
  315. }
  316. set params = jsonObj.params.%Get(0)
  317. if ('$ISOBJECT(params.admIds)) {
  318. set resultObj = ..SetErrorResult("-1", "请至少选择 2 条就诊记录进行比对")
  319. quit
  320. }
  321. set admIds = []
  322. kill seenId
  323. for i = 0:1:(params.admIds.%Size() - 1) {
  324. set aid = params.admIds.%Get(i)
  325. if (aid = "") continue
  326. if ($get(seenId(aid)) = 1) continue
  327. set seenId(aid) = 1
  328. do admIds.%Push(aid)
  329. }
  330. if (admIds.%Size() < 2) {
  331. set resultObj = ..SetErrorResult("-1", "请至少选择 2 条就诊记录进行比对")
  332. quit
  333. }
  334. if (admIds.%Size() > 5) {
  335. set resultObj = ..SetErrorResult("-1", "单次最多支持 5 条就诊记录同时比对")
  336. quit
  337. }
  338. set diffBase = params.diffBase
  339. if ((diffBase '= "avg") && (diffBase '= "first")) set diffBase = "first"
  340. set n = admIds.%Size()
  341. set inList = ..%BuildIn(admIds)
  342. set sqlObj = ##class(%SQL.Statement).%New(1)
  343. // ---------- SQL-A 就诊基本信息 ----------
  344. set sql = "SELECT MR.HISAdmID AS admID, MR.MedcasNo AS medcasNo, MR.PsnName AS patName, MR.Gend AS gend, MR.Age AS age,"
  345. _ " MR.AdmDate AS admDate, MR.DscgDate AS dscgDate, MR.IptDays AS iptDays, MR.MedfeeSumamt AS medfeeSumamt,"
  346. _ " MR.DRG AS drgCode, MR.DRGDesc AS drgName, PA.InLocDesc AS deptName, PA.AdmDocDesc AS doctorName, PA.InsuType AS insuTypeCode"
  347. _ " FROM BS_DRGMedInsuMedicalRecord MR LEFT JOIN BS_HISPatAdm PA ON PA.AdmID = MR.HISAdmID AND PA.Deleted = 0"
  348. _ " WHERE MR.HISAdmID IN (" _ inList _ ")"
  349. set sc = sqlObj.%Prepare(sql)
  350. if ('$$$ISOK(sc)) {
  351. set resultObj = ..%HandleError("查询比对就诊信息", "02010602", jsonObj, sc)
  352. quit
  353. }
  354. set rs = sqlObj.%Execute()
  355. kill vIdx
  356. while (rs.%Next()) {
  357. set v = {}
  358. set v.admID = rs.%Get("admID")
  359. set v.medcasNo = rs.%Get("medcasNo")
  360. set v.patName = rs.%Get("patName")
  361. set v.gend = rs.%Get("gend")
  362. set v.age = +rs.%Get("age")
  363. set v.admDate = rs.%Get("admDate")
  364. set v.dscgDate = rs.%Get("dscgDate")
  365. set v.iptDays = +rs.%Get("iptDays")
  366. set v.medfeeSumamt = +rs.%Get("medfeeSumamt")
  367. set v.drgCode = rs.%Get("drgCode")
  368. set v.drgName = rs.%Get("drgName")
  369. set v.deptName = rs.%Get("deptName")
  370. set v.doctorName = rs.%Get("doctorName")
  371. set v.insuTypeCode = rs.%Get("insuTypeCode")
  372. set vIdx(v.admID) = v
  373. }
  374. set visits = []
  375. for i = 0:1:(n - 1) {
  376. set aid = admIds.%Get(i)
  377. if ($data(vIdx(aid)) = 0) {
  378. set v = {}
  379. set v.admID = aid
  380. set v.medcasNo = ""
  381. set v.patName = ""
  382. set v.gend = ""
  383. set v.age = 0
  384. set v.admDate = ""
  385. set v.dscgDate = ""
  386. set v.iptDays = 0
  387. set v.medfeeSumamt = 0
  388. set v.drgCode = ""
  389. set v.drgName = ""
  390. set v.deptName = ""
  391. set v.doctorName = ""
  392. set v.insuTypeCode = ""
  393. set v.insuType = ""
  394. } else {
  395. set v = vIdx(aid)
  396. set v.insuType = ..%GetInsuTypeName(v.insuTypeCode)
  397. }
  398. do visits.%Push(v)
  399. }
  400. // ---------- SQL-B DRG 支付标准 ----------
  401. kill grPay, grWt
  402. set sc = sqlObj.%Prepare("SELECT AdmID, MAX(BenchmarkCost) AS PayStd, MAX(Weight) AS Weight FROM BS_DRGGroupRecord WHERE ActiveFlag = '1' AND AdmID IN (" _ inList _ ") GROUP BY AdmID")
  403. if ('$$$ISOK(sc)) {
  404. set resultObj = ..%HandleError("查询比对支付标准", "02010602", jsonObj, sc)
  405. quit
  406. }
  407. set rs = sqlObj.%Execute()
  408. while (rs.%Next()) {
  409. set grPay(rs.%Get("AdmID")) = +rs.%Get("PayStd")
  410. set grWt(rs.%Get("AdmID")) = +rs.%Get("Weight")
  411. }
  412. set drgPayment = []
  413. for i = 0:1:(n - 1) {
  414. set aid = admIds.%Get(i)
  415. set v = visits.%Get(i)
  416. set p = {}
  417. set p.admID = aid
  418. set p.drgCode = v.drgCode
  419. set p.drgName = v.drgName
  420. set p.payStandard = +$get(grPay(aid), 0)
  421. set p.weight = +$get(grWt(aid), 0)
  422. set p.totalFee = v.medfeeSumamt
  423. set p.profitAmount = +$FN(p.payStandard - p.totalFee, "", 2)
  424. set p.profitRate = 0
  425. if (p.totalFee > 0) set p.profitRate = +$FN((p.profitAmount / p.totalFee) * 100, "", 2)
  426. do drgPayment.%Push(p)
  427. }
  428. // ---------- SQL-C 结算清单费用汇总列 ----------
  429. set feeList = $LB(
  430. $LB("MedfeeSumamt","医疗费用总额"), $LB("OrdnMedServfee","一般医疗服务费"), $LB("OrdnTrtOprtFee","一般治疗操作费"),
  431. $LB("NursFee","护理费"), $LB("ComMedServOthFee","综合医疗服务其他费"), $LB("PalgDiagFee","病理诊断费"),
  432. $LB("LabDiagFee","实验室诊断费"), $LB("RdhyDiagFee","影像学诊断费"), $LB("ClncDiseFee","临床诊断项目费"),
  433. $LB("NsrgtrtItemFee","非手术治疗项目费"), $LB("ClncPhysTrtFee","临床物理治疗费"), $LB("RgtrtTrtFee","手术治疗费"),
  434. $LB("AnstFee","麻醉费"), $LB("RgtrtFee","手术费"), $LB("RhabFee","康复费"), $LB("TcmTrtFee","中医治疗费"),
  435. $LB("WmFee","西药费"), $LB("AbtlMednFee","抗菌药费"), $LB("TcmpatFee","中成药费"), $LB("TcmherbFee","中药饮片费"),
  436. $LB("BloFee","血费"), $LB("AlbuFee","白蛋白类制品费"), $LB("GlonFee","球蛋白类制品费"), $LB("ClotfacFee","凝血因子类制品费"),
  437. $LB("CykiFee","细胞因子类制品费"), $LB("ExamDspoMatlFee","检查用卫生材料费"), $LB("TrtDspoMatlFee","治疗用卫生材料费"),
  438. $LB("OprnDspoMatlFee","手术用卫生材料费"), $LB("OthFee","其他费"))
  439. set feeCount = $LL(feeList)
  440. set sel = "MR.HISAdmID AS admID"
  441. for fi = 1:1:feeCount {
  442. set sel = sel _ ", MR." _ $LI($LI(feeList, fi), 1) _ " AS " _ $LI($LI(feeList, fi), 1)
  443. }
  444. set sc = sqlObj.%Prepare("SELECT " _ sel _ " FROM BS_DRGMedInsuMedicalRecord MR WHERE MR.HISAdmID IN (" _ inList _ ")")
  445. if ('$$$ISOK(sc)) {
  446. set resultObj = ..%HandleError("查询比对结算清单费用", "02010602", jsonObj, sc)
  447. quit
  448. }
  449. set rs = sqlObj.%Execute()
  450. kill settleVal, settleExists
  451. while (rs.%Next()) {
  452. set aid = rs.%Get("admID")
  453. set settleExists(aid) = 1
  454. for fi = 1:1:feeCount {
  455. set settleVal(aid, $LI($LI(feeList, fi), 1)) = +rs.%Get($LI($LI(feeList, fi), 1))
  456. }
  457. }
  458. set settleCaseCount = 0
  459. for i = 0:1:(n - 1) {
  460. if ($get(settleExists(admIds.%Get(i))) = 1) set settleCaseCount = settleCaseCount + 1
  461. }
  462. set settleSummary = []
  463. for fi = 1:1:feeCount {
  464. set f = $LI($LI(feeList, fi), 1)
  465. set fname = $LI($LI(feeList, fi), 2)
  466. set baseVal = 0
  467. if (diffBase = "first") {
  468. set baseVal = +$get(settleVal(admIds.%Get(0), f), 0)
  469. } else {
  470. set cnt = 0
  471. for i = 0:1:(n - 1) {
  472. set aid = admIds.%Get(i)
  473. if ($get(settleExists(aid)) = 1) {
  474. set baseVal = baseVal + +$get(settleVal(aid, f), 0)
  475. set cnt = cnt + 1
  476. }
  477. }
  478. if (cnt > 0) set baseVal = baseVal / cnt
  479. }
  480. set cells = []
  481. set maxA = ""
  482. set minA = ""
  483. for i = 0:1:(n - 1) {
  484. set aid = admIds.%Get(i)
  485. set ex = ($get(settleExists(aid)) = 1)
  486. set val = +$get(settleVal(aid, f), 0)
  487. set d = ..%CalcDiff(val, baseVal, ex, settleCaseCount)
  488. set c = {}
  489. set c.admID = aid
  490. set c.value = val
  491. set c.diffFlag = $LI(d, 1)
  492. set c.diffAmount = $LI(d, 2)
  493. set c.diffRate = $LI(d, 3)
  494. do cells.%Push(c)
  495. if (ex) {
  496. if (maxA = "") || (val > maxA) set maxA = val
  497. if (minA = "") || (val < minA) set minA = val
  498. }
  499. }
  500. if (maxA = "") set maxA = 0
  501. if (minA = "") set minA = 0
  502. set row = {}
  503. set row.field = f
  504. set row.fieldName = fname
  505. set row.cells = cells
  506. set row.maxAmount = +$FN(maxA, "", 2)
  507. set row.minAmount = +$FN(minA, "", 2)
  508. set row.rangeAmount = +$FN(maxA - minA, "", 2)
  509. do settleSummary.%Push(row)
  510. }
  511. // ---------- SQL-D HIS 费用明细按项目 ----------
  512. set sc = sqlObj.%Prepare("SELECT FD.AdmID AS admID, FD.MedinsListCodg AS itemCode, MAX(FD.MedinsListDesc) AS itemName, SUM(COALESCE(FD.Cnt,0)) AS qty, SUM(COALESCE(FD.DetItemFeeSumamt,0)) AS amount FROM BS_HISFeeDetail FD WHERE FD.AdmID IN (" _ inList _ ") AND FD.Deleted = 0 AND (FD.ValidFlag IS NULL OR FD.ValidFlag <> 'N') GROUP BY FD.AdmID, FD.MedinsListCodg")
  513. if ('$$$ISOK(sc)) {
  514. set resultObj = ..%HandleError("查询比对费用明细项目", "02010602", jsonObj, sc)
  515. quit
  516. }
  517. set rs = sqlObj.%Execute()
  518. kill itemNameOf, ex, vl, qt
  519. while (rs.%Next()) {
  520. set aid = rs.%Get("admID")
  521. set code = rs.%Get("itemCode")
  522. if (code = "") set code = "#NONE#"
  523. set nm = rs.%Get("itemName")
  524. if ('$data(itemNameOf(code))) set itemNameOf(code) = nm
  525. if (nm '= "") set itemNameOf(code) = nm
  526. set ex(code, aid) = 1
  527. set vl(code, aid) = +rs.%Get("amount")
  528. set qt(code, aid) = +rs.%Get("qty")
  529. }
  530. kill rowKey, rowName
  531. set rowCount = 0
  532. set code = ""
  533. for {
  534. set code = $ORDER(itemNameOf(code))
  535. quit:(code = "")
  536. set rowCount = rowCount + 1
  537. set rowKey(rowCount) = code
  538. set rowName(rowCount) = itemNameOf(code)
  539. }
  540. set feeItem = ..%BuildMatrix(.rowKey, .rowName, .ex, .vl, .qt, admIds, diffBase, 500, .itemTruncated)
  541. // ---------- SQL-E 结算类别聚合 ----------
  542. set sc = sqlObj.%Prepare("SELECT FD.AdmID AS admID, FD.EcCode AS catCode, MAX(FD.EcDesc) AS catName, SUM(COALESCE(FD.Cnt,0)) AS qty, SUM(COALESCE(FD.DetItemFeeSumamt,0)) AS amount FROM BS_HISFeeDetail FD WHERE FD.AdmID IN (" _ inList _ ") AND FD.Deleted = 0 AND (FD.ValidFlag IS NULL OR FD.ValidFlag <> 'N') GROUP BY FD.AdmID, FD.EcCode, FD.EcDesc")
  543. if ('$$$ISOK(sc)) {
  544. set resultObj = ..%HandleError("查询比对结算类别", "02010602", jsonObj, sc)
  545. quit
  546. }
  547. set rs = sqlObj.%Execute()
  548. kill itemNameOf, ex, vl, qt
  549. while (rs.%Next()) {
  550. set aid = rs.%Get("admID")
  551. set code = rs.%Get("catCode")
  552. set nm = rs.%Get("catName")
  553. if (code = "") { set code = "#NONE#" if (nm = "") set nm = "未分类" }
  554. if ('$data(itemNameOf(code))) set itemNameOf(code) = nm
  555. if (nm '= "") set itemNameOf(code) = nm
  556. set ex(code, aid) = 1
  557. set vl(code, aid) = +$get(vl(code, aid), 0) + +rs.%Get("amount")
  558. set qt(code, aid) = +$get(qt(code, aid), 0) + +rs.%Get("qty")
  559. }
  560. kill rowKey, rowName
  561. set rowCount = 0
  562. set code = ""
  563. for {
  564. set code = $ORDER(itemNameOf(code))
  565. quit:(code = "")
  566. set rowCount = rowCount + 1
  567. set rowKey(rowCount) = code
  568. set rowName(rowCount) = itemNameOf(code)
  569. }
  570. set catTruncated = 0
  571. set feeCategory = ..%BuildMatrix(.rowKey, .rowName, .ex, .vl, .qt, admIds, diffBase, 0, .catTruncated)
  572. // ---------- SQL-F 诊断比对(BS_HISDiseInfo 无 Deleted 字段,不做作废过滤) ----------
  573. kill diagNameOf, diagEx, diagMain
  574. set sc = sqlObj.%Prepare("SELECT AdmID, DiagCode, DiagName, MainFlag FROM BS_HISDiseInfo WHERE AdmID IN (" _ inList _ ")")
  575. if ('$$$ISOK(sc)) {
  576. set resultObj = ..%HandleError("查询比对诊断信息", "02010602", jsonObj, sc)
  577. quit
  578. }
  579. set rs = sqlObj.%Execute()
  580. while (rs.%Next()) {
  581. set aid = rs.%Get("AdmID")
  582. set dc = rs.%Get("DiagCode")
  583. if (dc = "") continue
  584. set nm = rs.%Get("DiagName")
  585. if ('$data(diagNameOf(dc))) set diagNameOf(dc) = nm
  586. if (nm '= "") set diagNameOf(dc) = nm
  587. set diagEx(dc, aid) = 1
  588. if (+rs.%Get("MainFlag") = 1) set diagMain(dc, aid) = 1
  589. }
  590. set diagnoses = []
  591. set dc = ""
  592. for {
  593. set dc = $ORDER(diagNameOf(dc))
  594. quit:(dc = "")
  595. set marks = []
  596. for i = 0:1:(n - 1) {
  597. set aid = admIds.%Get(i)
  598. set m = {}
  599. set m.admID = aid
  600. set m.exists = ($get(diagEx(dc, aid)) = 1)
  601. set m.isMain = ($get(diagMain(dc, aid)) = 1)
  602. do marks.%Push(m)
  603. }
  604. set dr = {}
  605. set dr.diagCode = dc
  606. set dr.diagName = diagNameOf(dc)
  607. set dr.marks = marks
  608. do diagnoses.%Push(dr)
  609. }
  610. // ---------- SQL-G 手术比对(BS_HISOprnInfo 无 Deleted 字段,不做作废过滤) ----------
  611. kill oprnNameOf, oprnEx, oprnMain
  612. set sc = sqlObj.%Prepare("SELECT AdmID, OprnCode, OprnName, MainFlag FROM BS_HISOprnInfo WHERE AdmID IN (" _ inList _ ")")
  613. if ('$$$ISOK(sc)) {
  614. set resultObj = ..%HandleError("查询比对手术信息", "02010602", jsonObj, sc)
  615. quit
  616. }
  617. set rs = sqlObj.%Execute()
  618. while (rs.%Next()) {
  619. set aid = rs.%Get("AdmID")
  620. set oc = rs.%Get("OprnCode")
  621. if (oc = "") continue
  622. set nm = rs.%Get("OprnName")
  623. if ('$data(oprnNameOf(oc))) set oprnNameOf(oc) = nm
  624. if (nm '= "") set oprnNameOf(oc) = nm
  625. set oprnEx(oc, aid) = 1
  626. if (rs.%Get("MainFlag") = "Y") set oprnMain(oc, aid) = 1
  627. }
  628. set operations = []
  629. set oc = ""
  630. for {
  631. set oc = $ORDER(oprnNameOf(oc))
  632. quit:(oc = "")
  633. set marks = []
  634. for i = 0:1:(n - 1) {
  635. set aid = admIds.%Get(i)
  636. set m = {}
  637. set m.admID = aid
  638. set m.exists = ($get(oprnEx(oc, aid)) = 1)
  639. set m.isMain = ($get(oprnMain(oc, aid)) = 1)
  640. do marks.%Push(m)
  641. }
  642. set orow = {}
  643. set orow.oprnCode = oc
  644. set orow.oprnName = oprnNameOf(oc)
  645. set orow.marks = marks
  646. do operations.%Push(orow)
  647. }
  648. // ---------- 文字比对分析报告 ----------
  649. set reportText = ..%BuildReportText(visits, drgPayment, settleSummary, feeItem, diagnoses, operations, itemTruncated)
  650. set analysis = {}
  651. set analysis.reportText = reportText
  652. set out = {}
  653. set out.visits = visits
  654. set out.drgPayment = drgPayment
  655. set out.settleSummary = settleSummary
  656. set out.feeItem = feeItem
  657. set out.feeCategory = feeCategory
  658. set out.diagnoses = diagnoses
  659. set out.operations = operations
  660. set out.analysis = analysis
  661. set resultObj.result = out
  662. }
  663. catch(e)
  664. {
  665. set resultObj = ..%HandleError("病组费用比对", "02010602", jsonObj, e.AsStatus())
  666. }
  667. quit resultObj
  668. }
  669. /// Description: 由并集行键构建比对矩阵(应用层降序排序 + TopN 截断)
  670. /// rowKey(k)=行键、rowName(k)=行名(k=1..rowCount)
  671. /// ex(key,admID)=1 表示该例存在该行;vl(key,admID)=金额;qt(key,admID)=数量
  672. /// topN>0 时仅保留各例金额最大值最高的 topN 行,并置 truncated=1
  673. /// 注:本环境不支持 ORDER BY 聚合表达式,排序一律在应用层用下标数组完成
  674. ClassMethod %BuildMatrix(ByRef rowKey, ByRef rowName, ByRef ex, ByRef vl, ByRef qt, admIds As %Library.DynamicArray, diffBase As %String, topN As %Integer, ByRef truncated) As %Library.DynamicArray
  675. {
  676. new out, rowCount, n, i, k, key, baseVal, cnt, aid, val, existsCount, cells, c, d, maxA, minA, row, maxV, t, sMax, skey, take, done, e
  677. set truncated = 0
  678. set out = []
  679. set n = admIds.%Size()
  680. set rowCount = 0
  681. set k = ""
  682. for {
  683. set k = $ORDER(rowKey(k))
  684. quit:(k = "")
  685. set rowCount = rowCount + 1
  686. }
  687. if (rowCount = 0) quit out
  688. kill sortIdx
  689. for k = 1:1:rowCount {
  690. set key = rowKey(k)
  691. set maxV = 0
  692. for i = 0:1:(n - 1) {
  693. set aid = admIds.%Get(i)
  694. if ($get(ex(key, aid)) = 1) {
  695. set t = +$get(vl(key, aid), 0)
  696. if (t > maxV) set maxV = t
  697. }
  698. }
  699. set sortIdx(maxV, k) = k
  700. }
  701. set take = 0
  702. set done = 0
  703. set sMax = ""
  704. for {
  705. quit:done
  706. set sMax = $ORDER(sortIdx(sMax), -1)
  707. quit:(sMax = "")
  708. set skey = ""
  709. for {
  710. quit:done
  711. set skey = $ORDER(sortIdx(sMax, skey), 1)
  712. quit:(skey = "")
  713. if ((topN > 0) && (take >= topN)) { set truncated = 1 set done = 1 quit }
  714. set k = sortIdx(sMax, skey)
  715. set key = rowKey(k)
  716. set existsCount = 0
  717. for i = 0:1:(n - 1) {
  718. set aid = admIds.%Get(i)
  719. if ($get(ex(key, aid)) = 1) set existsCount = existsCount + 1
  720. }
  721. set baseVal = 0
  722. if (diffBase = "first") {
  723. set baseVal = +$get(vl(key, admIds.%Get(0)), 0)
  724. } else {
  725. set cnt = 0
  726. for i = 0:1:(n - 1) {
  727. set aid = admIds.%Get(i)
  728. if ($get(ex(key, aid)) = 1) {
  729. set baseVal = baseVal + +$get(vl(key, aid), 0)
  730. set cnt = cnt + 1
  731. }
  732. }
  733. if (cnt > 0) set baseVal = baseVal / cnt
  734. }
  735. set cells = []
  736. set maxA = ""
  737. set minA = ""
  738. for i = 0:1:(n - 1) {
  739. set aid = admIds.%Get(i)
  740. set e = ($get(ex(key, aid)) = 1)
  741. set val = +$get(vl(key, aid), 0)
  742. set d = ..%CalcDiff(val, baseVal, e, existsCount)
  743. set c = {}
  744. set c.admID = aid
  745. set c.value = val
  746. set c.qty = +$get(qt(key, aid), 0)
  747. set c.diffFlag = $LI(d, 1)
  748. set c.diffAmount = $LI(d, 2)
  749. set c.diffRate = $LI(d, 3)
  750. do cells.%Push(c)
  751. if (e) {
  752. if (maxA = "") || (val > maxA) set maxA = val
  753. if (minA = "") || (val < minA) set minA = val
  754. }
  755. }
  756. if (maxA = "") set maxA = 0
  757. if (minA = "") set minA = 0
  758. set row = {}
  759. set row.key = key
  760. set row.name = $get(rowName(k), "")
  761. set row.cells = cells
  762. set row.maxAmount = +$FN(maxA, "", 2)
  763. set row.minAmount = +$FN(minA, "", 2)
  764. set row.rangeAmount = +$FN(maxA - minA, "", 2)
  765. do out.%Push(row)
  766. set take = take + 1
  767. }
  768. }
  769. quit out
  770. }
  771. /// Description: 拼装中文文字比对分析报告(段落数组)
  772. /// 段落顺序:结论摘要 / 费用总览 / 结构差异 Top5 / 诊断与手术差异 / 支付标准与盈亏
  773. /// / [跨病组比对提示] / [风险提示] / [明细截断说明]
  774. ClassMethod %BuildReportText(visits As %Library.DynamicArray, drgPayment As %Library.DynamicArray, settleSummary As %Library.DynamicArray, feeItem As %Library.DynamicArray, diagnoses As %Library.DynamicArray, operations As %Library.DynamicArray, itemTruncated As %Boolean) As %Library.DynamicArray
  775. {
  776. new txt, n, i, mi, ri, v, p, c, r, dr, orow, mk, maxV, minV, maxIdx, minIdx, sumFee, avgFee, s, drgCount, dc, sMax, skey, take, overList, overCnt, onlyList, onlyCnt, onlyIdx, onlyFlag, sameDiag, sameOprn, firstDiag, firstOprn, aid
  777. set txt = []
  778. set n = visits.%Size()
  779. if (n = 0) quit txt
  780. // 段落 1 结论摘要
  781. set maxV = visits.%Get(0).medfeeSumamt
  782. set minV = visits.%Get(0).medfeeSumamt
  783. set maxIdx = 0
  784. set minIdx = 0
  785. set sumFee = 0
  786. for i = 0:1:(n - 1) {
  787. set v = visits.%Get(i)
  788. set sumFee = sumFee + v.medfeeSumamt
  789. if (v.medfeeSumamt > maxV) { set maxV = v.medfeeSumamt set maxIdx = i }
  790. if (v.medfeeSumamt < minV) { set minV = v.medfeeSumamt set minIdx = i }
  791. }
  792. set s = "【结论摘要】本次共比对 " _ n _ " 例就诊。总费用最高为第 " _ (maxIdx + 1) _ " 例(" _ visits.%Get(maxIdx).patName _ "," _ $FN(maxV, "", 2) _ " 元),"
  793. set s = s _ "最低为第 " _ (minIdx + 1) _ " 例(" _ visits.%Get(minIdx).patName _ "," _ $FN(minV, "", 2) _ " 元),差额 " _ $FN(maxV - minV, "", 2) _ " 元"
  794. if (minV > 0) set s = s _ ",倍差 " _ $FN(maxV / minV, "", 2) _ " 倍"
  795. set s = s _ "。"
  796. do txt.%Push(s)
  797. // 段落 2 费用总览
  798. set avgFee = sumFee / n
  799. set s = "【费用总览】"
  800. for i = 0:1:(n - 1) {
  801. set v = visits.%Get(i)
  802. set s = s _ "第" _ (i + 1) _ "例 " _ v.patName _ "(就诊号 " _ v.admID _ "):" _ $FN(v.medfeeSumamt, "", 2) _ " 元,住院 " _ v.iptDays _ " 天;"
  803. }
  804. set s = s _ "例均费用 " _ $FN(avgFee, "", 2) _ " 元。"
  805. do txt.%Push(s)
  806. // 段落 3 结构差异 Top5(按结算清单费用项极差降序)
  807. kill sortIdx
  808. for ri = 0:1:(settleSummary.%Size() - 1) {
  809. set r = settleSummary.%Get(ri)
  810. set sortIdx(r.rangeAmount, ri) = ri
  811. }
  812. set s = "【结构差异 Top5】按结算清单费用项极差降序:"
  813. set take = 0
  814. set sMax = ""
  815. for {
  816. set sMax = $ORDER(sortIdx(sMax), -1)
  817. quit:(sMax = "")
  818. quit:(take >= 5)
  819. set skey = ""
  820. for {
  821. set skey = $ORDER(sortIdx(sMax, skey), 1)
  822. quit:(skey = "")
  823. quit:(take >= 5)
  824. if (sMax <= 0) continue
  825. set r = settleSummary.%Get(sortIdx(sMax, skey))
  826. set s = s _ "|" _ r.fieldName _ " 极差 " _ $FN(r.rangeAmount, "", 2) _ " 元("
  827. for i = 0:1:(r.cells.%Size() - 1) {
  828. set c = r.cells.%Get(i)
  829. set s = s _ $FN(c.value, "", 2)
  830. if (i < (r.cells.%Size() - 1)) set s = s _ " / "
  831. }
  832. set s = s _ ")"
  833. set take = take + 1
  834. }
  835. }
  836. if (take = 0) set s = s _ "各例结算清单费用项无差异"
  837. set s = s _ "。"
  838. do txt.%Push(s)
  839. // 段落 4 诊断与手术差异
  840. kill mainDiagOf, mainOprnOf
  841. for i = 0:1:(diagnoses.%Size() - 1) {
  842. set dr = diagnoses.%Get(i)
  843. for mi = 0:1:(dr.marks.%Size() - 1) {
  844. set mk = dr.marks.%Get(mi)
  845. if (mk.isMain = 1) set mainDiagOf(mk.admID) = dr.diagCode _ " " _ dr.diagName
  846. }
  847. }
  848. for i = 0:1:(operations.%Size() - 1) {
  849. set orow = operations.%Get(i)
  850. for mi = 0:1:(orow.marks.%Size() - 1) {
  851. set mk = orow.marks.%Get(mi)
  852. if (mk.isMain = 1) set mainOprnOf(mk.admID) = orow.oprnCode _ " " _ orow.oprnName
  853. }
  854. }
  855. set firstDiag = $get(mainDiagOf(visits.%Get(0).admID), "")
  856. set firstOprn = $get(mainOprnOf(visits.%Get(0).admID), "")
  857. set sameDiag = 1
  858. set sameOprn = 1
  859. for i = 0:1:(n - 1) {
  860. set aid = visits.%Get(i).admID
  861. if ($get(mainDiagOf(aid)) '= firstDiag) set sameDiag = 0
  862. if ($get(mainOprnOf(aid)) '= firstOprn) set sameOprn = 0
  863. }
  864. set s = "【诊断与手术差异】主诊断"
  865. if (sameDiag) {
  866. set s = s _ "一致:" _ firstDiag
  867. } else {
  868. set s = s _ "不一致:"
  869. for i = 0:1:(n - 1) {
  870. set v = visits.%Get(i)
  871. set s = s _ "第" _ (i + 1) _ "例 " _ $get(mainDiagOf(v.admID), "无") _ ";"
  872. }
  873. }
  874. set s = s _ "。主手术"
  875. if (sameOprn) {
  876. set s = s _ "一致:" _ firstOprn
  877. } else {
  878. set s = s _ "不一致:"
  879. for i = 0:1:(n - 1) {
  880. set v = visits.%Get(i)
  881. set s = s _ "第" _ (i + 1) _ "例 " _ $get(mainOprnOf(v.admID), "无") _ ";"
  882. }
  883. }
  884. set s = s _ "。"
  885. do txt.%Push(s)
  886. // 段落 5 支付标准与盈亏
  887. set s = "【支付标准与盈亏】"
  888. for i = 0:1:(drgPayment.%Size() - 1) {
  889. set p = drgPayment.%Get(i)
  890. set s = s _ "第" _ (i + 1) _ "例 " _ p.drgCode _ " " _ p.drgName _ ":支付标准 " _ $FN(p.payStandard, "", 2) _ " 元,实际费用 " _ $FN(p.totalFee, "", 2) _ " 元,盈亏 " _ $FN(p.profitAmount, "", 2) _ " 元(" _ $FN(p.profitRate, "", 2) _ "%);"
  891. }
  892. set s = s _ "。"
  893. do txt.%Push(s)
  894. // 跨病组比对提示(各例 DRG 不一致时强制输出)
  895. kill drgSet
  896. set drgCount = 0
  897. for i = 0:1:(drgPayment.%Size() - 1) {
  898. set dc = drgPayment.%Get(i).drgCode
  899. if (dc = "") continue
  900. if ('$data(drgSet(dc))) { set drgSet(dc) = 1 set drgCount = drgCount + 1 }
  901. }
  902. if (drgCount > 1) {
  903. do txt.%Push("【跨病组比对提示】本次比对的就诊分属 " _ drgCount _ " 个不同 DRG 病组,费用结构差异受病组差异影响,上述结论仅供参考,请结合各病组支付标准分别评估。")
  904. }
  905. // 段落 6 风险提示(无风险项时不输出)
  906. set overList = ""
  907. set overCnt = 0
  908. for i = 0:1:(drgPayment.%Size() - 1) {
  909. set p = drgPayment.%Get(i)
  910. if (p.totalFee > p.payStandard) {
  911. set overCnt = overCnt + 1
  912. if (overList '= "") set overList = overList _ ";"
  913. set overList = overList _ "第" _ (i + 1) _ "例超支 " _ $FN(p.totalFee - p.payStandard, "", 2) _ " 元(" _ $FN($select(p.payStandard > 0 : ((p.totalFee - p.payStandard) / p.payStandard) * 100, 1 : 0), "", 2) _ "%)"
  914. }
  915. }
  916. set onlyList = ""
  917. set onlyCnt = 0
  918. for ri = 0:1:(feeItem.%Size() - 1) {
  919. set r = feeItem.%Get(ri)
  920. set onlyIdx = -1
  921. set onlyFlag = 1
  922. for i = 0:1:(r.cells.%Size() - 1) {
  923. set c = r.cells.%Get(i)
  924. if (c.value > 0) {
  925. if (onlyIdx = -1) { set onlyIdx = i } else { set onlyFlag = 0 }
  926. }
  927. }
  928. if (onlyFlag && (onlyIdx >= 0)) {
  929. set c = r.cells.%Get(onlyIdx)
  930. if (c.value >= 5000) {
  931. set onlyCnt = onlyCnt + 1
  932. if (onlyList '= "") set onlyList = onlyList _ ";"
  933. set onlyList = onlyList _ "第" _ (onlyIdx + 1) _ "例独有「" _ r.name _ "」" _ $FN(c.value, "", 2) _ " 元"
  934. if (onlyCnt >= 5) quit
  935. }
  936. }
  937. }
  938. if ((overCnt > 0) || (onlyCnt > 0)) {
  939. set s = "【风险提示】"
  940. if (overCnt > 0) set s = s _ "超支病例 " _ overCnt _ " 例:" _ overList _ "。"
  941. if (onlyCnt > 0) set s = s _ "单边特有高值项目(≥5000 元):" _ onlyList _ "。"
  942. do txt.%Push(s)
  943. }
  944. // 明细截断说明
  945. if (itemTruncated = 1) {
  946. do txt.%Push("【说明】费用明细项目较多,仅展示金额 Top 500 项。")
  947. }
  948. quit txt
  949. }
  950. /// ============================================================
  951. /// 重复收费统计(02010603 / 02010604 / 02010605)
  952. /// 判定口径:分组键 = 就诊号 | 费用日期(YYYY-MM-DD) | 收费项目编码 MedinsListCodg
  953. /// 组内记录数 >= dupTimes(默认 2)判定为重复
  954. /// 仅 DetItemFeeSumamt >= 0 且 MedinsListCodg 非空的记录参与判定(排除退费)
  955. /// 金额口径:dupAmountMode = excess(默认)重复金额 = 组内总额 * (次数-1) / 次数
  956. /// total 重复金额 = 组内总额
  957. /// 比重口径:dupRatioOfCategory 分母为该收费类型全部有效明细金额(含退费)
  958. /// dupRatioOfTotal 分母为查询范围内全部有效明细金额(含退费)
  959. /// ============================================================
  960. /// Description: 构建重复收费统计的公共过滤条件(02010603 / 02010604 共用)
  961. /// 基础口径:FD.Deleted = 0 AND (FD.ValidFlag IS NULL OR FD.ValidFlag <> 'N')
  962. /// MR 基准(任何日期口径都必须附加):存在病案首页且 DRG 非空(已分组)
  963. /// dupOnly = 1:追加重复判定过滤(金额 >= 0 且项目编码非空,排除退费)
  964. /// dateType:adm -> MR.AdmDate / discharge -> MR.DscgDate / fee -> FD.FeeOcurTime
  965. ClassMethod %BuildDupWhere(params As %Library.DynamicObject, dupOnly As %Integer) As %String
  966. {
  967. new w, v, dateType
  968. set w = " WHERE FD.Deleted = 0 AND (FD.ValidFlag IS NULL OR FD.ValidFlag <> 'N')"
  969. set w = w _ " AND EXISTS (SELECT 1 FROM BS_DRGMedInsuMedicalRecord MR WHERE MR.HISAdmID = FD.AdmID AND (MR.ValiFlag IS NULL OR MR.ValiFlag <> '0') AND MR.DRG IS NOT NULL AND MR.DRG <> '')"
  970. if (dupOnly = 1) set w = w _ " AND FD.DetItemFeeSumamt >= 0 AND (FD.MedinsListCodg IS NOT NULL AND FD.MedinsListCodg <> '')"
  971. set v = params.fixmedinsCode
  972. if (v '= "") set w = w _ " AND FD.FixmedinsCode = '" _ $REPLACE(v, "'", "") _ "'"
  973. set v = params.admID
  974. if (v '= "") set w = w _ " AND FD.AdmID = '" _ $REPLACE(v, "'", "") _ "'"
  975. set v = params.patName
  976. if (v '= "") set w = w _ " AND FD.PatName LIKE '%" _ $REPLACE(v, "'", "") _ "%'"
  977. set v = params.itemCodeOrName
  978. if (v '= "") set w = w _ " AND (FD.MedinsListCodg = '" _ $REPLACE(v, "'", "") _ "' OR FD.MedinsListDesc LIKE '%" _ $REPLACE(v, "'", "") _ "%')"
  979. set v = params.ecCode
  980. if (v '= "") set w = w _ " AND FD.EcCode = '" _ $REPLACE(v, "'", "") _ "'"
  981. set v = params.deptName
  982. if (v '= "") set w = w _ " AND FD.BilgDeptName LIKE '%" _ $REPLACE(v, "'", "") _ "%'"
  983. set dateType = params.dateType
  984. set v = params.startDate
  985. if (v '= "") {
  986. if (dateType = "fee") {
  987. set w = w _ " AND FD.FeeOcurTime >= '" _ $REPLACE(v, "'", "") _ " 00:00:00'"
  988. } elseif (dateType = "discharge") {
  989. set w = w _ " AND EXISTS (SELECT 1 FROM BS_DRGMedInsuMedicalRecord m WHERE m.HISAdmID = FD.AdmID AND m.DscgDate >= '" _ $REPLACE(v, "'", "") _ "')"
  990. } else {
  991. set w = w _ " AND EXISTS (SELECT 1 FROM BS_DRGMedInsuMedicalRecord m WHERE m.HISAdmID = FD.AdmID AND m.AdmDate >= '" _ $REPLACE(v, "'", "") _ "')"
  992. }
  993. }
  994. set v = params.endDate
  995. if (v '= "") {
  996. if (dateType = "fee") {
  997. set w = w _ " AND FD.FeeOcurTime <= '" _ $REPLACE(v, "'", "") _ " 23:59:59'"
  998. } elseif (dateType = "discharge") {
  999. set w = w _ " AND EXISTS (SELECT 1 FROM BS_DRGMedInsuMedicalRecord m WHERE m.HISAdmID = FD.AdmID AND m.DscgDate <= '" _ $REPLACE(v, "'", "") _ " 23:59:59')"
  1000. } else {
  1001. set w = w _ " AND EXISTS (SELECT 1 FROM BS_DRGMedInsuMedicalRecord m WHERE m.HISAdmID = FD.AdmID AND m.AdmDate <= '" _ $REPLACE(v, "'", "") _ " 23:59:59')"
  1002. }
  1003. }
  1004. quit w
  1005. }
  1006. /// Description: 重复金额折算
  1007. /// total = 组内全部金额
  1008. /// excess = 组内总额 * (次数 - 1) / 次数(按均价保留一次,其余视为多收)
  1009. ClassMethod %CalcDupAmount(amount As %Numeric, times As %Integer, mode As %String) As %Numeric
  1010. {
  1011. if (times <= 1) quit 0
  1012. if (mode = "total") quit +$FN(amount, "", 2)
  1013. quit +$FN((amount * (times - 1)) / times, "", 2)
  1014. }
  1015. /// Description: 重复数量折算(语义同 %CalcDupAmount)
  1016. ClassMethod %CalcDupQty(qty As %Numeric, times As %Integer, mode As %String) As %Numeric
  1017. {
  1018. if (times <= 1) quit 0
  1019. if (mode = "total") quit +$FN(qty, "", 2)
  1020. quit +$FN((qty * (times - 1)) / times, "", 2)
  1021. }
  1022. /// Description: 百分比计算(分母为 0 时返回 0),保留两位小数
  1023. ClassMethod %Ratio(molecule As %Numeric, denominator As %Numeric) As %Numeric
  1024. {
  1025. if (denominator = 0) quit 0
  1026. quit +$FN((molecule / denominator) * 100, "", 2)
  1027. }
  1028. /// Description: 重复收费排序列的定长排序键(16 位补零,保证字符串序 = 数值序且永不为 "")
  1029. ClassMethod %SortKey(amount As %Numeric) As %String
  1030. {
  1031. quit $TRANSLATE($JUSTIFY($FN(amount * 100, "", 0), 16), " ", "0")
  1032. }
  1033. /// Description: 构建命中重复组(02010603 / 02010604 共用)
  1034. /// 分组键 dk = 就诊号 | 费用日期(YYYY-MM-DD) | 收费项目编码 MedinsListCodg
  1035. /// 两段式:SQL-1 按 (就诊, 项目编码) 预筛候选 -> SQL-2 按就诊分批回捞明细 -> 应用层按自然日归并
  1036. /// ByRef out 输出:
  1037. /// out("hitCnt") / out("truncated")
  1038. /// out("hit", n) = dk(按重复金额降序)
  1039. /// out("adm"/"date"/"code"/"name"/"cat"/"catName"/"times"/"qty"/"amt"/"dupAmt"/"dupQty", dk)
  1040. /// out("admList", n) = 命中涉及的就诊号
  1041. /// @return 命中组数(截断后);-1 表示 SQL 预编译失败
  1042. ClassMethod %BuildDupGroups(params As %Library.DynamicObject, dupTimes As %Integer, dupAmountMode As %String, ByRef out) As %Integer
  1043. {
  1044. new (params, dupTimes, dupAmountMode, out)
  1045. set w = ..%BuildDupWhere(params, 1)
  1046. set sqlObj = ##class(%SQL.Statement).%New(1)
  1047. set sc = sqlObj.%Prepare("SELECT FD.AdmID AS admID, FD.MedinsListCodg AS itemCode, COUNT(*) AS recCnt FROM BS_HISFeeDetail FD" _ w _ " GROUP BY FD.AdmID, FD.MedinsListCodg")
  1048. if ('$$$ISOK(sc)) quit -1
  1049. set rs = sqlObj.%Execute()
  1050. set admCnt = 0
  1051. while (rs.%Next()) {
  1052. if (rs.%Get("recCnt") < dupTimes) continue
  1053. set admCnt = admCnt + 1
  1054. set admArr(rs.%Get("admID")) = 1
  1055. }
  1056. set out("hitCnt") = 0
  1057. set out("truncated") = 0
  1058. if (admCnt = 0) quit 0
  1059. set seq = 0
  1060. set admID = ""
  1061. set batchCnt = 0
  1062. set inList = ""
  1063. set errFlag = 0
  1064. set done = 0
  1065. while ('done) {
  1066. set admID = $ORDER(admArr(admID))
  1067. if (admID '= "") {
  1068. set batchCnt = batchCnt + 1
  1069. if (inList '= "") set inList = inList _ ","
  1070. set inList = inList _ "'" _ $REPLACE(admID, "'", "") _ "'"
  1071. }
  1072. if ((admID = "") || (batchCnt >= 200)) {
  1073. if (inList '= "") {
  1074. set sc = sqlObj.%Prepare("SELECT FD.AdmID AS admID, FD.MedinsListCodg AS itemCode, FD.MedinsListDesc AS itemName, FD.EcCode AS catCode, FD.EcDesc AS catName, FD.Cnt AS cnt, FD.DetItemFeeSumamt AS amount, FD.FeeOcurTime AS feeOcurTime FROM BS_HISFeeDetail FD" _ w _ " AND FD.AdmID IN (" _ inList _ ")")
  1075. if ('$$$ISOK(sc)) {
  1076. set errFlag = 1
  1077. } else {
  1078. set rs = sqlObj.%Execute()
  1079. while (rs.%Next()) {
  1080. set admID2 = rs.%Get("admID")
  1081. set itemCode = rs.%Get("itemCode")
  1082. set itemName = rs.%Get("itemName")
  1083. set catCode = rs.%Get("catCode")
  1084. set catName = rs.%Get("catName")
  1085. set cnt = +rs.%Get("cnt")
  1086. set amount = +rs.%Get("amount")
  1087. set feeOcurTime = rs.%Get("feeOcurTime")
  1088. set fd = $EXTRACT(feeOcurTime, 1, 10)
  1089. set dk = admID2 _ "|" _ fd _ "|" _ itemCode
  1090. set t = $INCREMENT(out("times", dk))
  1091. if (t = 1) {
  1092. set seq = seq + 1
  1093. set out("seq", seq) = dk
  1094. set out("adm", dk) = admID2
  1095. set out("date", dk) = fd
  1096. set out("code", dk) = itemCode
  1097. set out("name", dk) = itemName
  1098. set out("cat", dk) = catCode
  1099. set out("catName", dk) = catName
  1100. set out("qty", dk) = 0
  1101. set out("amt", dk) = 0
  1102. }
  1103. set out("qty", dk) = out("qty", dk) + cnt
  1104. set out("amt", dk) = out("amt", dk) + amount
  1105. if (itemName '= "") set out("name", dk) = itemName
  1106. if (catCode '= "") {
  1107. set out("cat", dk) = catCode
  1108. set out("catName", dk) = catName
  1109. }
  1110. }
  1111. }
  1112. set inList = ""
  1113. set batchCnt = 0
  1114. }
  1115. if (admID = "") set done = 1
  1116. }
  1117. if (errFlag) set done = 1
  1118. }
  1119. if (errFlag) quit -1
  1120. set dk = ""
  1121. set done = 0
  1122. while ('done) {
  1123. set dk = $ORDER(out("times", dk))
  1124. if (dk = "") {
  1125. set done = 1
  1126. } else {
  1127. if (out("times", dk) >= dupTimes) {
  1128. set dupAmt = ..%CalcDupAmount(out("amt", dk), out("times", dk), dupAmountMode)
  1129. set out("dupAmt", dk) = dupAmt
  1130. set out("dupQty", dk) = ..%CalcDupQty(out("qty", dk), out("times", dk), dupAmountMode)
  1131. set sk = ..%SortKey(dupAmt)
  1132. set sortIdx(sk, dk) = ""
  1133. }
  1134. }
  1135. }
  1136. set hitCnt = 0
  1137. set admN = 0
  1138. set done = 0
  1139. set sk = ""
  1140. while ('done) {
  1141. set sk = $ORDER(sortIdx(sk), -1)
  1142. if (sk = "") {
  1143. set done = 1
  1144. } else {
  1145. set dk2 = ""
  1146. set done2 = 0
  1147. while ('done2) {
  1148. set dk2 = $ORDER(sortIdx(sk, dk2))
  1149. if (dk2 = "") {
  1150. set done2 = 1
  1151. } else {
  1152. if (hitCnt >= 2000) {
  1153. set out("truncated") = 1
  1154. set done2 = 1
  1155. set done = 1
  1156. } else {
  1157. set hitCnt = hitCnt + 1
  1158. set out("hit", hitCnt) = dk2
  1159. set m = $INCREMENT(admSeen(out("adm", dk2)))
  1160. if (m = 1) {
  1161. set admN = admN + 1
  1162. set out("admList", admN) = out("adm", dk2)
  1163. }
  1164. }
  1165. }
  1166. }
  1167. }
  1168. }
  1169. set out("hitCnt") = hitCnt
  1170. quit hitCnt
  1171. }
  1172. /// Creator: 系统
  1173. /// CreatDate: 2026-09-17
  1174. /// Description: 重复收费汇总统计(按收费项目类型/收费项目,含双比重与全局KPI)
  1175. /// Code: 02010603
  1176. /// Input: {"params":[{"fixmedinsCode":"","dateType":"adm","startDate":"","endDate":"",
  1177. /// "dupTimes":2,"dupAmountMode":"excess","groupBy":"category",
  1178. /// "admID":"","patName":"","itemCodeOrName":"","ecCode":"","deptName":""}]}
  1179. /// Output: {errorCode:"0", errorMessage:"", result:{rows:[{groupCode,groupName,totalAmount,
  1180. /// dupAmount,dupQty,dupRecordCount,dupItemCount,dupVisitCount,
  1181. /// dupRatioOfCategory,dupRatioOfTotal}], statistics:{...}, message:""}}
  1182. ClassMethod QueryDuplicateChargeSummary(jsonObj As %Library.DynamicObject) As %Library.DynamicObject
  1183. {
  1184. new (jsonObj)
  1185. set resultObj = {"errorCode":"0","errorMessage":"","result":{}}
  1186. try
  1187. {
  1188. if (jsonObj = "") || (jsonObj.params = "") {
  1189. set resultObj = ..SetErrorResult("-1", "入参异常:缺少params参数或参数为空")
  1190. quit
  1191. }
  1192. set params = jsonObj.params.%Get(0)
  1193. set fixmedinsCode = params.fixmedinsCode
  1194. set startDate = params.startDate
  1195. set endDate = params.endDate
  1196. set admIDIn = params.admID
  1197. set patNameIn = params.patName
  1198. if ((fixmedinsCode = "") && (startDate = "") && (endDate = "") && (admIDIn = "") && (patNameIn = "")) {
  1199. set resultObj = ..SetErrorResult("-1", "查询条件不足:请至少提供机构代码、日期区间或就诊标识之一")
  1200. quit
  1201. }
  1202. set dupTimes = $CASE(params.dupTimes, "" : 2, : +params.dupTimes)
  1203. if (dupTimes < 2) set dupTimes = 2
  1204. set dupAmountMode = $CASE(params.dupAmountMode, "total" : "total", : "excess")
  1205. set groupBy = $CASE(params.groupBy, "item" : "item", : "category")
  1206. set hitCnt = ..%BuildDupGroups(params, dupTimes, dupAmountMode, .out)
  1207. if (hitCnt < 0) {
  1208. set resultObj = ..SetErrorResult("-1", "重复收费统计失败:查询预编译异常,请稍后重试")
  1209. quit
  1210. }
  1211. set w0 = ..%BuildDupWhere(params, 0)
  1212. set sqlObj = ##class(%SQL.Statement).%New(1)
  1213. set sc = sqlObj.%Prepare("SELECT COUNT(DISTINCT FD.AdmID) AS cnt FROM BS_HISFeeDetail FD" _ w0)
  1214. if ('$$$ISOK(sc)) {
  1215. set resultObj = ..%HandleError("重复收费汇总统计", "02010603", jsonObj, sc)
  1216. quit
  1217. }
  1218. set rs = sqlObj.%Execute()
  1219. set visitCount = 0
  1220. if (rs.%Next()) set visitCount = +rs.%Get("cnt")
  1221. set sc = sqlObj.%Prepare("SELECT SUM(COALESCE(FD.DetItemFeeSumamt,0)) AS totalAmount FROM BS_HISFeeDetail FD" _ w0)
  1222. if ('$$$ISOK(sc)) {
  1223. set resultObj = ..%HandleError("重复收费汇总统计", "02010603", jsonObj, sc)
  1224. quit
  1225. }
  1226. set rs = sqlObj.%Execute()
  1227. set totalAmount = 0
  1228. if (rs.%Next()) set totalAmount = +rs.%Get("totalAmount")
  1229. set rowCnt = 0
  1230. set dupAmount = 0
  1231. set dupRecordCount = 0
  1232. set dupItemCount = 0
  1233. set dupVisitCount = 0
  1234. for hi = 1:1:hitCnt {
  1235. set dk = out("hit", hi)
  1236. if (groupBy = "item") {
  1237. set rk = out("code", dk)
  1238. set rname = out("name", dk)
  1239. } else {
  1240. set rk = out("cat", dk)
  1241. set rname = out("catName", dk)
  1242. }
  1243. if (rname = "") set rname = "未分类"
  1244. set t = $INCREMENT(rowSeen(rk))
  1245. if (t = 1) {
  1246. set rowCnt = rowCnt + 1
  1247. set rowKey(rowCnt) = rk
  1248. set rowName(rk) = rname
  1249. set rowDupAmt(rk) = 0
  1250. set rowDupQty(rk) = 0
  1251. set rowRec(rk) = 0
  1252. set rowItemCnt(rk) = 0
  1253. set rowVisitCnt(rk) = 0
  1254. set rowTotal(rk) = 0
  1255. }
  1256. set rowDupAmt(rk) = rowDupAmt(rk) + out("dupAmt", dk)
  1257. set rowDupQty(rk) = rowDupQty(rk) + out("dupQty", dk)
  1258. set rowRec(rk) = rowRec(rk) + out("times", dk)
  1259. set m = $INCREMENT(rowItemSeen(rk, out("code", dk)))
  1260. if (m = 1) set rowItemCnt(rk) = rowItemCnt(rk) + 1
  1261. set m = $INCREMENT(rowVisitSeen(rk, out("adm", dk)))
  1262. if (m = 1) set rowVisitCnt(rk) = rowVisitCnt(rk) + 1
  1263. set dupAmount = dupAmount + out("dupAmt", dk)
  1264. set dupRecordCount = dupRecordCount + out("times", dk)
  1265. set m = $INCREMENT(admSeen(out("adm", dk)))
  1266. if (m = 1) set dupVisitCount = dupVisitCount + 1
  1267. set m = $INCREMENT(itemSeen(out("code", dk)))
  1268. if (m = 1) set dupItemCount = dupItemCount + 1
  1269. }
  1270. if (groupBy = "item") {
  1271. set sc = sqlObj.%Prepare("SELECT FD.MedinsListCodg AS gCode, SUM(COALESCE(FD.DetItemFeeSumamt,0)) AS gAmount FROM BS_HISFeeDetail FD" _ w0 _ " GROUP BY FD.MedinsListCodg")
  1272. } else {
  1273. set sc = sqlObj.%Prepare("SELECT FD.EcCode AS gCode, SUM(COALESCE(FD.DetItemFeeSumamt,0)) AS gAmount FROM BS_HISFeeDetail FD" _ w0 _ " GROUP BY FD.EcCode")
  1274. }
  1275. if ('$$$ISOK(sc)) {
  1276. set resultObj = ..%HandleError("重复收费汇总统计", "02010603", jsonObj, sc)
  1277. quit
  1278. }
  1279. set rs = sqlObj.%Execute()
  1280. while (rs.%Next()) {
  1281. set gk = rs.%Get("gCode")
  1282. set rowTotal(gk) = +rs.%Get("gAmount")
  1283. }
  1284. for i = 1:1:rowCnt {
  1285. set rk = rowKey(i)
  1286. set sk = ..%SortKey(rowDupAmt(rk))
  1287. set rowSort(sk, rk) = ""
  1288. }
  1289. set rows = []
  1290. set done = 0
  1291. set sk = ""
  1292. while ('done) {
  1293. set sk = $ORDER(rowSort(sk), -1)
  1294. if (sk = "") {
  1295. set done = 1
  1296. } else {
  1297. set rk2 = ""
  1298. set done2 = 0
  1299. while ('done2) {
  1300. set rk2 = $ORDER(rowSort(sk, rk2))
  1301. if (rk2 = "") {
  1302. set done2 = 1
  1303. } else {
  1304. set r = {}
  1305. set r.groupCode = rk2
  1306. set r.groupName = rowName(rk2)
  1307. set r.totalAmount = +$FN(rowTotal(rk2), "", 2)
  1308. set r.dupAmount = +$FN(rowDupAmt(rk2), "", 2)
  1309. set r.dupQty = +$FN(rowDupQty(rk2), "", 2)
  1310. set r.dupRecordCount = rowRec(rk2)
  1311. set r.dupItemCount = rowItemCnt(rk2)
  1312. set r.dupVisitCount = rowVisitCnt(rk2)
  1313. set r.dupRatioOfCategory = ..%Ratio(rowDupAmt(rk2), rowTotal(rk2))
  1314. set r.dupRatioOfTotal = ..%Ratio(rowDupAmt(rk2), totalAmount)
  1315. do rows.%Push(r)
  1316. }
  1317. }
  1318. }
  1319. }
  1320. set stat = {}
  1321. set stat.visitCount = visitCount
  1322. set stat.dupVisitCount = dupVisitCount
  1323. set stat.dupVisitRatio = ..%Ratio(dupVisitCount, visitCount)
  1324. set stat.dupItemCount = dupItemCount
  1325. set stat.dupGroupCount = hitCnt
  1326. set stat.dupRecordCount = dupRecordCount
  1327. set stat.totalAmount = +$FN(totalAmount, "", 2)
  1328. set stat.dupAmount = +$FN(dupAmount, "", 2)
  1329. set stat.dupRatioOfTotal = ..%Ratio(dupAmount, totalAmount)
  1330. set resultObj.result.rows = rows
  1331. set resultObj.result.total = hitCnt
  1332. set resultObj.result.statistics = stat
  1333. set resultObj.result.message = ""
  1334. if (out("truncated") = 1) set resultObj.result.message = "命中重复组过多,仅展示重复金额最高的 2000 组,请缩小查询范围"
  1335. }
  1336. catch(e)
  1337. {
  1338. set resultObj = ..%HandleError("重复收费汇总统计", "02010603", jsonObj, e.AsStatus())
  1339. }
  1340. quit resultObj
  1341. }
  1342. /// Creator: 系统
  1343. /// CreatDate: 2026-09-17
  1344. /// Description: 重复收费明细查询(按重复组分页,同组同色号,同组不被跨页切断)
  1345. /// Code: 02010604
  1346. /// Input: {"params":[{...同 02010603}], "pagination":[{"pageSize":10,"currentPage":1}]}
  1347. /// Output: {errorCode:"0", errorMessage:"", result:{rows:[{...dupGroupKey,colorIndex,times,
  1348. /// amount,dupAmount,isDup,...}], total:N, statistics:{...}, message:""}}
  1349. ClassMethod QueryDuplicateChargeDetail(jsonObj As %Library.DynamicObject) As %Library.DynamicObject
  1350. {
  1351. new (jsonObj)
  1352. set resultObj = {"errorCode":"0","errorMessage":"","result":{}}
  1353. try
  1354. {
  1355. if (jsonObj = "") || (jsonObj.params = "") {
  1356. set resultObj = ..SetErrorResult("-1", "入参异常:缺少params参数或参数为空")
  1357. quit
  1358. }
  1359. set params = jsonObj.params.%Get(0)
  1360. set fixmedinsCode = params.fixmedinsCode
  1361. set startDate = params.startDate
  1362. set endDate = params.endDate
  1363. set admIDIn = params.admID
  1364. set patNameIn = params.patName
  1365. if ((fixmedinsCode = "") && (startDate = "") && (endDate = "") && (admIDIn = "") && (patNameIn = "")) {
  1366. set resultObj = ..SetErrorResult("-1", "查询条件不足:请至少提供机构代码、日期区间或就诊标识之一")
  1367. quit
  1368. }
  1369. set dupTimes = $CASE(params.dupTimes, "" : 2, : +params.dupTimes)
  1370. if (dupTimes < 2) set dupTimes = 2
  1371. set dupAmountMode = $CASE(params.dupAmountMode, "total" : "total", : "excess")
  1372. set pg = ..%GetPage(jsonObj)
  1373. set hitCnt = ..%BuildDupGroups(params, dupTimes, dupAmountMode, .out)
  1374. if (hitCnt < 0) {
  1375. set resultObj = ..SetErrorResult("-1", "重复收费明细查询失败:查询预编译异常,请稍后重试")
  1376. quit
  1377. }
  1378. set dupAmount = 0
  1379. set dupRecordCount = 0
  1380. set dupItemCount = 0
  1381. set dupVisitCount = 0
  1382. for hi = 1:1:hitCnt {
  1383. set dk = out("hit", hi)
  1384. set dupAmount = dupAmount + out("dupAmt", dk)
  1385. set dupRecordCount = dupRecordCount + out("times", dk)
  1386. set m = $INCREMENT(admSeen(out("adm", dk)))
  1387. if (m = 1) set dupVisitCount = dupVisitCount + 1
  1388. set m = $INCREMENT(itemSeen(out("code", dk)))
  1389. if (m = 1) set dupItemCount = dupItemCount + 1
  1390. }
  1391. set w0 = ..%BuildDupWhere(params, 0)
  1392. set sqlObj = ##class(%SQL.Statement).%New(1)
  1393. set sc = sqlObj.%Prepare("SELECT COUNT(DISTINCT FD.AdmID) AS cnt FROM BS_HISFeeDetail FD" _ w0)
  1394. if ('$$$ISOK(sc)) {
  1395. set resultObj = ..%HandleError("重复收费明细查询", "02010604", jsonObj, sc)
  1396. quit
  1397. }
  1398. set rs = sqlObj.%Execute()
  1399. set visitCount = 0
  1400. if (rs.%Next()) set visitCount = +rs.%Get("cnt")
  1401. set sc = sqlObj.%Prepare("SELECT SUM(COALESCE(FD.DetItemFeeSumamt,0)) AS totalAmount FROM BS_HISFeeDetail FD" _ w0)
  1402. if ('$$$ISOK(sc)) {
  1403. set resultObj = ..%HandleError("重复收费明细查询", "02010604", jsonObj, sc)
  1404. quit
  1405. }
  1406. set rs = sqlObj.%Execute()
  1407. set totalAmount = 0
  1408. if (rs.%Next()) set totalAmount = +rs.%Get("totalAmount")
  1409. set startIdx = (pg.currentPage - 1) * pg.pageSize + 1
  1410. if (startIdx < 1) set startIdx = 1
  1411. set endIdx = startIdx + pg.pageSize - 1
  1412. if (endIdx > hitCnt) set endIdx = hitCnt
  1413. set rows = []
  1414. if (startIdx <= endIdx) {
  1415. set pageAdmN = 0
  1416. for hi = startIdx:1:endIdx {
  1417. set dk = out("hit", hi)
  1418. set m = $INCREMENT(pageAdmSeen(out("adm", dk)))
  1419. if (m = 1) {
  1420. set pageAdmN = pageAdmN + 1
  1421. set pageAdm(pageAdmN) = out("adm", dk)
  1422. }
  1423. }
  1424. set inList = ""
  1425. for i = 1:1:pageAdmN {
  1426. set pName(pageAdm(i)) = ""
  1427. set pMed(pageAdm(i)) = ""
  1428. set pDrg(pageAdm(i)) = ""
  1429. set pDrgN(pageAdm(i)) = ""
  1430. set pDept(pageAdm(i)) = ""
  1431. set pDoc(pageAdm(i)) = ""
  1432. if (inList '= "") set inList = inList _ ","
  1433. set inList = inList _ "'" _ $REPLACE(pageAdm(i), "'", "") _ "'"
  1434. }
  1435. set sc = sqlObj.%Prepare("SELECT MR.HISAdmID AS admID, MR.PsnName AS patName, MR.MedcasNo AS medcasNo, MR.DRG AS drgCode, MR.DRGDesc AS drgName, PA.InLocDesc AS deptName, PA.AdmDocDesc AS doctorName FROM BS_DRGMedInsuMedicalRecord MR LEFT JOIN BS_HISPatAdm PA ON PA.AdmID = MR.HISAdmID AND PA.Deleted = 0 WHERE MR.HISAdmID IN (" _ inList _ ")")
  1436. if ('$$$ISOK(sc)) {
  1437. set resultObj = ..%HandleError("重复收费明细查询", "02010604", jsonObj, sc)
  1438. quit
  1439. }
  1440. set rs = sqlObj.%Execute()
  1441. while (rs.%Next()) {
  1442. set a = rs.%Get("admID")
  1443. set pName(a) = rs.%Get("patName")
  1444. set pMed(a) = rs.%Get("medcasNo")
  1445. set pDrg(a) = rs.%Get("drgCode")
  1446. set pDrgN(a) = rs.%Get("drgName")
  1447. set pDept(a) = rs.%Get("deptName")
  1448. set pDoc(a) = rs.%Get("doctorName")
  1449. }
  1450. set sc = sqlObj.%Prepare("SELECT FD.AdmID AS admID, FD.FeedetlSn AS feedetlSn, FD.MedinsListCodg AS itemCode, FD.MedinsListDesc AS itemName, FD.EcCode AS catCode, FD.EcDesc AS catName, FD.Spec AS spec, FD.Pric AS pric, FD.Cnt AS cnt, FD.DetItemFeeSumamt AS amount, FD.FeeOcurTime AS feeOcurTime, FD.BilgDeptName AS bilgDeptName, FD.OrdersDrName AS ordersDrName FROM BS_HISFeeDetail FD" _ w0 _ " AND FD.AdmID IN (" _ inList _ ")")
  1451. if ('$$$ISOK(sc)) {
  1452. set resultObj = ..%HandleError("重复收费明细查询", "02010604", jsonObj, sc)
  1453. quit
  1454. }
  1455. set rs = sqlObj.%Execute()
  1456. while (rs.%Next()) {
  1457. set admID2 = rs.%Get("admID")
  1458. set itemCode = rs.%Get("itemCode")
  1459. set feeOcurTime = rs.%Get("feeOcurTime")
  1460. set dk = admID2 _ "|" _ $EXTRACT(feeOcurTime, 1, 10) _ "|" _ itemCode
  1461. set n = $INCREMENT(bTot(dk))
  1462. if (n <= 30) {
  1463. set bRow(dk, n) = $LB(rs.%Get("feedetlSn"), admID2, itemCode, rs.%Get("itemName"), rs.%Get("catCode"), rs.%Get("catName"), rs.%Get("spec"), +rs.%Get("pric"), +rs.%Get("cnt"), +rs.%Get("amount"), feeOcurTime, rs.%Get("bilgDeptName"), rs.%Get("ordersDrName"))
  1464. }
  1465. }
  1466. for hi = startIdx:1:endIdx {
  1467. set dk = out("hit", hi)
  1468. set admID2 = out("adm", dk)
  1469. set colorIndex = (hi - 1) # 8
  1470. set gTimes = out("times", dk)
  1471. set gAmt = out("amt", dk)
  1472. set gDupAmt = out("dupAmt", dk)
  1473. set tot = bTot(dk)
  1474. set lim = tot
  1475. if (lim > 30) set lim = 30
  1476. for j = 1:1:lim {
  1477. set lb = bRow(dk, j)
  1478. set r = {}
  1479. set r.dupGroupKey = dk
  1480. set r.colorIndex = colorIndex
  1481. set r.times = gTimes
  1482. set r.amount = +$FN(gAmt, "", 2)
  1483. set r.dupAmount = gDupAmt
  1484. set r.isDup = 1
  1485. if ($LG(lb, 10) < 0) set r.isDup = 0
  1486. set r.isTip = 0
  1487. set r.feedetlSn = $LG(lb, 1)
  1488. set r.admID = $LG(lb, 2)
  1489. set r.patName = pName($LG(lb, 2))
  1490. set r.medcasNo = pMed($LG(lb, 2))
  1491. set r.deptName = pDept($LG(lb, 2))
  1492. set r.doctorName = pDoc($LG(lb, 2))
  1493. set r.feeDate = out("date", dk)
  1494. set r.medinsListCodg = $LG(lb, 3)
  1495. set r.medinsListDesc = $LG(lb, 4)
  1496. set r.ecCode = $LG(lb, 5)
  1497. set r.ecDesc = $LG(lb, 6)
  1498. if (r.ecDesc = "") set r.ecDesc = "未分类"
  1499. set r.spec = $LG(lb, 7)
  1500. set r.pric = +$FN($LG(lb, 8), "", 2)
  1501. set r.cnt = +$FN($LG(lb, 9), "", 2)
  1502. set r.detItemFeeSumamt = +$FN($LG(lb, 10), "", 2)
  1503. set r.feeOcurTime = $LG(lb, 11)
  1504. set r.bilgDeptName = $LG(lb, 12)
  1505. set r.ordersDrName = $LG(lb, 13)
  1506. set r.drgCode = pDrg($LG(lb, 2))
  1507. set r.drgName = pDrgN($LG(lb, 2))
  1508. do rows.%Push(r)
  1509. }
  1510. if (tot > 30) {
  1511. set tr = {}
  1512. set tr.isTip = 1
  1513. set tr.dupGroupKey = dk
  1514. set tr.colorIndex = colorIndex
  1515. set tr.medinsListDesc = "…该组还有 " _ (tot - 30) _ " 条未展示"
  1516. set tr.detItemFeeSumamt = 0
  1517. set tr.cnt = 0
  1518. do rows.%Push(tr)
  1519. }
  1520. }
  1521. }
  1522. set stat = {}
  1523. set stat.visitCount = visitCount
  1524. set stat.dupVisitCount = dupVisitCount
  1525. set stat.dupVisitRatio = ..%Ratio(dupVisitCount, visitCount)
  1526. set stat.dupItemCount = dupItemCount
  1527. set stat.dupGroupCount = hitCnt
  1528. set stat.dupRecordCount = dupRecordCount
  1529. set stat.totalAmount = +$FN(totalAmount, "", 2)
  1530. set stat.dupAmount = +$FN(dupAmount, "", 2)
  1531. set stat.dupRatioOfTotal = ..%Ratio(dupAmount, totalAmount)
  1532. set resultObj.result.rows = rows
  1533. set resultObj.result.total = hitCnt
  1534. set resultObj.result.statistics = stat
  1535. set resultObj.result.message = ""
  1536. if (out("truncated") = 1) set resultObj.result.message = "命中重复组过多,仅展示重复金额最高的 2000 组,请缩小查询范围"
  1537. }
  1538. catch(e)
  1539. {
  1540. set resultObj = ..%HandleError("重复收费明细查询", "02010604", jsonObj, e.AsStatus())
  1541. }
  1542. quit resultObj
  1543. }
  1544. /// Creator: 系统
  1545. /// CreatDate: 2026-09-17
  1546. /// Description: 单次就诊费用信息(明细 + 双维度汇总 + 重复分组统计),只读已落库数据、不触发 HIS 同步
  1547. /// Code: 02010605
  1548. /// Input: {"params":[{"admID":"","fixmedinsCode":"","dupTimes":2,"dupAmountMode":"excess"}]}
  1549. /// Output: {errorCode:"0", errorMessage:"", result:{visit:{}, summaryByCategory:[],
  1550. /// summaryByItem:[], dupGroups:[], rows:[], statistics:{}}}
  1551. ClassMethod QueryVisitFeeDetail(jsonObj As %Library.DynamicObject) As %Library.DynamicObject
  1552. {
  1553. new (jsonObj)
  1554. set resultObj = {"errorCode":"0","errorMessage":"","result":{}}
  1555. try
  1556. {
  1557. if (jsonObj = "") || (jsonObj.params = "") {
  1558. set resultObj = ..SetErrorResult("-1", "入参异常:缺少params参数或参数为空")
  1559. quit
  1560. }
  1561. set params = jsonObj.params.%Get(0)
  1562. set admID = params.admID
  1563. if (admID = "") {
  1564. set resultObj = ..SetErrorResult("-1", "缺少就诊号admID")
  1565. quit
  1566. }
  1567. set dupTimes = $CASE(params.dupTimes, "" : 2, : +params.dupTimes)
  1568. if (dupTimes < 2) set dupTimes = 2
  1569. set dupAmountMode = $CASE(params.dupAmountMode, "total" : "total", : "excess")
  1570. set fixmedinsCode = params.fixmedinsCode
  1571. set admIDSql = $REPLACE(admID, "'", "")
  1572. set fixSql = ""
  1573. if (fixmedinsCode '= "") set fixSql = " AND MR.FixmedinsCode = '" _ $REPLACE(fixmedinsCode, "'", "") _ "'"
  1574. set sqlObj = ##class(%SQL.Statement).%New(1)
  1575. set sc = sqlObj.%Prepare("SELECT MR.HISAdmID AS admID, MR.PsnName AS patName, MR.MedcasNo AS medcasNo, MR.DRG AS drgCode, MR.DRGDesc AS drgName, MR.AdmDate AS admDate, MR.DscgDate AS dscgDate, MR.MedfeeSumamt AS medfeeSumamt, PA.InsuType AS insuType, PA.InLocDesc AS deptName, PA.AdmDocDesc AS doctorName FROM BS_DRGMedInsuMedicalRecord MR LEFT JOIN BS_HISPatAdm PA ON PA.AdmID = MR.HISAdmID AND PA.Deleted = 0 WHERE MR.HISAdmID = '" _ admIDSql _ "'" _ fixSql)
  1576. if ('$$$ISOK(sc)) {
  1577. set resultObj = ..%HandleError("查询单次就诊费用信息", "02010605", jsonObj, sc)
  1578. quit
  1579. }
  1580. set rs = sqlObj.%Execute()
  1581. set visit = {}
  1582. if (rs.%Next()) {
  1583. set visit.admID = rs.%Get("admID")
  1584. set visit.patName = rs.%Get("patName")
  1585. set visit.medcasNo = rs.%Get("medcasNo")
  1586. set visit.drgCode = rs.%Get("drgCode")
  1587. set visit.drgName = rs.%Get("drgName")
  1588. set visit.admDate = rs.%Get("admDate")
  1589. set visit.dscgDate = rs.%Get("dscgDate")
  1590. set visit.medfeeSumamt = +rs.%Get("medfeeSumamt")
  1591. set visit.insuType = ..%GetInsuTypeName(rs.%Get("insuType"))
  1592. set visit.deptName = rs.%Get("deptName")
  1593. set visit.doctorName = rs.%Get("doctorName")
  1594. }
  1595. set fixSql2 = ""
  1596. if (fixmedinsCode '= "") set fixSql2 = " AND FD.FixmedinsCode = '" _ $REPLACE(fixmedinsCode, "'", "") _ "'"
  1597. set sc = sqlObj.%Prepare("SELECT FD.FeedetlSn AS feedetlSn, FD.MedinsListCodg AS itemCode, FD.MedinsListDesc AS itemName, FD.EcCode AS catCode, FD.EcDesc AS catName, FD.Spec AS spec, FD.Pric AS pric, FD.Cnt AS cnt, FD.DetItemFeeSumamt AS amount, FD.FeeOcurTime AS feeOcurTime, FD.BilgDeptName AS bilgDeptName, FD.OrdersDrName AS ordersDrName FROM BS_HISFeeDetail FD WHERE FD.AdmID = '" _ admIDSql _ "' AND FD.Deleted = 0 AND (FD.ValidFlag IS NULL OR FD.ValidFlag <> 'N')" _ fixSql2)
  1598. if ('$$$ISOK(sc)) {
  1599. set resultObj = ..%HandleError("查询单次就诊费用信息", "02010605", jsonObj, sc)
  1600. quit
  1601. }
  1602. set rs = sqlObj.%Execute()
  1603. set rowN = 0
  1604. while (rs.%Next()) {
  1605. set rowN = rowN + 1
  1606. set dRow(rowN) = $LB(rs.%Get("feedetlSn"), rs.%Get("itemCode"), rs.%Get("itemName"), rs.%Get("catCode"), rs.%Get("catName"), rs.%Get("spec"), +rs.%Get("pric"), +rs.%Get("cnt"), +rs.%Get("amount"), rs.%Get("feeOcurTime"), rs.%Get("bilgDeptName"), rs.%Get("ordersDrName"))
  1607. }
  1608. set totalAmount = 0
  1609. set refundAmount = 0
  1610. set dupAmount = 0
  1611. set cN = 0
  1612. set iN = 0
  1613. set seq = 0
  1614. for i = 1:1:rowN {
  1615. set lb = dRow(i)
  1616. set amount = $LG(lb, 9)
  1617. set cnt = $LG(lb, 8)
  1618. set totalAmount = totalAmount + amount
  1619. if (amount < 0) set refundAmount = refundAmount + amount
  1620. set ck = $LG(lb, 4)
  1621. set cn = $LG(lb, 5)
  1622. set t = $INCREMENT(cSeen(ck))
  1623. if (t = 1) {
  1624. set cN = cN + 1
  1625. set cKey(cN) = ck
  1626. set cName(ck) = cn
  1627. set cAmt(ck) = 0
  1628. set cQty(ck) = 0
  1629. set cRec(ck) = 0
  1630. }
  1631. set cAmt(ck) = cAmt(ck) + amount
  1632. set cQty(ck) = cQty(ck) + cnt
  1633. set cRec(ck) = cRec(ck) + 1
  1634. if (cn '= "") set cName(ck) = cn
  1635. set ik = $LG(lb, 2)
  1636. set in = $LG(lb, 3)
  1637. set t = $INCREMENT(iSeen(ik))
  1638. if (t = 1) {
  1639. set iN = iN + 1
  1640. set iKey(iN) = ik
  1641. set iName(ik) = in
  1642. set iAmt(ik) = 0
  1643. set iQty(ik) = 0
  1644. set iRec(ik) = 0
  1645. }
  1646. set iAmt(ik) = iAmt(ik) + amount
  1647. set iQty(ik) = iQty(ik) + cnt
  1648. set iRec(ik) = iRec(ik) + 1
  1649. if (in '= "") set iName(ik) = in
  1650. if ($LG(lb, 2) '= "") {
  1651. set gdk = $EXTRACT($LG(lb, 10), 1, 10) _ "|" _ $LG(lb, 2)
  1652. set a2 = $INCREMENT(gAll(gdk))
  1653. if (a2 = 1) {
  1654. set seq = seq + 1
  1655. set gKey(seq) = gdk
  1656. set gDate(gdk) = $EXTRACT($LG(lb, 10), 1, 10)
  1657. set gCode(gdk) = $LG(lb, 2)
  1658. set gName(gdk) = $LG(lb, 3)
  1659. set gCat(gdk) = $LG(lb, 5)
  1660. set gTimes(gdk) = 0
  1661. set gQty(gdk) = 0
  1662. set gAmt(gdk) = 0
  1663. }
  1664. if (amount >= 0) {
  1665. set gTimes(gdk) = gTimes(gdk) + 1
  1666. set gQty(gdk) = gQty(gdk) + cnt
  1667. set gAmt(gdk) = gAmt(gdk) + amount
  1668. if ($LG(lb, 3) '= "") set gName(gdk) = $LG(lb, 3)
  1669. if ($LG(lb, 5) '= "") set gCat(gdk) = $LG(lb, 5)
  1670. }
  1671. }
  1672. }
  1673. for i = 1:1:seq {
  1674. set gdk = gKey(i)
  1675. if (gTimes(gdk) < dupTimes) continue
  1676. set d1 = ..%CalcDupAmount(gAmt(gdk), gTimes(gdk), dupAmountMode)
  1677. set gDupAmt(gdk) = d1
  1678. set gDupQty(gdk) = ..%CalcDupQty(gQty(gdk), gTimes(gdk), dupAmountMode)
  1679. set gSort(gDate(gdk) _ "|" _ ..%SortKey(d1), gdk) = ""
  1680. set dupAmount = dupAmount + d1
  1681. }
  1682. set dupGroups = []
  1683. set ord = 0
  1684. set done = 0
  1685. set sk = ""
  1686. while ('done) {
  1687. set sk = $ORDER(gSort(sk), -1)
  1688. if (sk = "") {
  1689. set done = 1
  1690. } else {
  1691. set gdk2 = ""
  1692. set done2 = 0
  1693. while ('done2) {
  1694. set gdk2 = $ORDER(gSort(sk, gdk2))
  1695. if (gdk2 = "") {
  1696. set done2 = 1
  1697. } else {
  1698. set gColor(gdk2) = ord # 8
  1699. set ord = ord + 1
  1700. set g = {}
  1701. set g.date = gDate(gdk2)
  1702. set g.itemCode = gCode(gdk2)
  1703. set g.itemName = gName(gdk2)
  1704. set g.catName = gCat(gdk2)
  1705. if (g.catName = "") set g.catName = "未分类"
  1706. set g.times = gTimes(gdk2)
  1707. set g.qty = +$FN(gQty(gdk2), "", 2)
  1708. set g.amount = +$FN(gAmt(gdk2), "", 2)
  1709. set g.dupAmount = gDupAmt(gdk2)
  1710. do dupGroups.%Push(g)
  1711. }
  1712. }
  1713. }
  1714. }
  1715. set summaryByCategory = []
  1716. for i = 1:1:cN {
  1717. set ck = cKey(i)
  1718. set cSort(..%SortKey(cAmt(ck)), ck) = ""
  1719. }
  1720. set done = 0
  1721. set sk = ""
  1722. while ('done) {
  1723. set sk = $ORDER(cSort(sk), -1)
  1724. if (sk = "") {
  1725. set done = 1
  1726. } else {
  1727. set ck2 = ""
  1728. set done2 = 0
  1729. while ('done2) {
  1730. set ck2 = $ORDER(cSort(sk, ck2))
  1731. if (ck2 = "") {
  1732. set done2 = 1
  1733. } else {
  1734. set it = {}
  1735. set it.groupCode = ck2
  1736. set it.groupName = cName(ck2)
  1737. if (it.groupName = "") set it.groupName = "未分类"
  1738. set it.amount = +$FN(cAmt(ck2), "", 2)
  1739. set it.qty = +$FN(cQty(ck2), "", 2)
  1740. set it.recordCount = cRec(ck2)
  1741. set it.avgPrice = 0
  1742. if (cQty(ck2) '= 0) set it.avgPrice = +$FN(cAmt(ck2) / cQty(ck2), "", 2)
  1743. set it.ratio = ..%Ratio(cAmt(ck2), totalAmount)
  1744. do summaryByCategory.%Push(it)
  1745. }
  1746. }
  1747. }
  1748. }
  1749. set summaryByItem = []
  1750. for i = 1:1:iN {
  1751. set ik = iKey(i)
  1752. set iSort(..%SortKey(iAmt(ik)), ik) = ""
  1753. }
  1754. set done = 0
  1755. set sk = ""
  1756. while ('done) {
  1757. set sk = $ORDER(iSort(sk), -1)
  1758. if (sk = "") {
  1759. set done = 1
  1760. } else {
  1761. set ik2 = ""
  1762. set done2 = 0
  1763. while ('done2) {
  1764. set ik2 = $ORDER(iSort(sk, ik2))
  1765. if (ik2 = "") {
  1766. set done2 = 1
  1767. } else {
  1768. set it = {}
  1769. set it.groupCode = ik2
  1770. set it.groupName = iName(ik2)
  1771. if (it.groupName = "") set it.groupName = "未分类"
  1772. set it.amount = +$FN(iAmt(ik2), "", 2)
  1773. set it.qty = +$FN(iQty(ik2), "", 2)
  1774. set it.recordCount = iRec(ik2)
  1775. set it.avgPrice = 0
  1776. if (iQty(ik2) '= 0) set it.avgPrice = +$FN(iAmt(ik2) / iQty(ik2), "", 2)
  1777. set it.ratio = ..%Ratio(iAmt(ik2), totalAmount)
  1778. do summaryByItem.%Push(it)
  1779. }
  1780. }
  1781. }
  1782. }
  1783. set rows = []
  1784. for i = 1:1:rowN {
  1785. set lb = dRow(i)
  1786. set amount = $LG(lb, 9)
  1787. set isDup = 0
  1788. set gdk = ""
  1789. set times = 0
  1790. set gamount = 0
  1791. set gdupAmount = 0
  1792. if ($LG(lb, 2) '= "") {
  1793. set gdk = $EXTRACT($LG(lb, 10), 1, 10) _ "|" _ $LG(lb, 2)
  1794. if ((amount >= 0) && (gTimes(gdk) >= dupTimes)) {
  1795. set isDup = 1
  1796. set times = gTimes(gdk)
  1797. set gamount = +$FN(gAmt(gdk), "", 2)
  1798. set gdupAmount = gDupAmt(gdk)
  1799. }
  1800. }
  1801. set r = {}
  1802. set r.feedetlSn = $LG(lb, 1)
  1803. set r.admID = admID
  1804. set r.medinsListCodg = $LG(lb, 2)
  1805. set r.medinsListDesc = $LG(lb, 3)
  1806. set r.ecCode = $LG(lb, 4)
  1807. set r.ecDesc = $LG(lb, 5)
  1808. if (r.ecDesc = "") set r.ecDesc = "未分类"
  1809. set r.spec = $LG(lb, 6)
  1810. set r.pric = +$FN($LG(lb, 7), "", 2)
  1811. set r.cnt = +$FN($LG(lb, 8), "", 2)
  1812. set r.detItemFeeSumamt = +$FN($LG(lb, 9), "", 2)
  1813. set r.feeOcurTime = $LG(lb, 10)
  1814. set r.feeDate = $EXTRACT($LG(lb, 10), 1, 10)
  1815. set r.bilgDeptName = $LG(lb, 11)
  1816. set r.ordersDrName = $LG(lb, 12)
  1817. set r.isDup = isDup
  1818. set r.times = times
  1819. set r.amount = gamount
  1820. set r.dupAmount = gdupAmount
  1821. set r.dupGroupKey = ""
  1822. if (isDup = 1) {
  1823. set r.dupGroupKey = gdk
  1824. set r.colorIndex = gColor(gdk)
  1825. }
  1826. do rows.%Push(r)
  1827. }
  1828. set stat = {}
  1829. set stat.recordCount = rowN
  1830. set stat.totalAmount = +$FN(totalAmount, "", 2)
  1831. set stat.dupAmount = +$FN(dupAmount, "", 2)
  1832. set stat.dupRatio = ..%Ratio(dupAmount, totalAmount)
  1833. set stat.refundAmount = +$FN(refundAmount, "", 2)
  1834. set resultObj.result.visit = visit
  1835. set resultObj.result.summaryByCategory = summaryByCategory
  1836. set resultObj.result.summaryByItem = summaryByItem
  1837. set resultObj.result.dupGroups = dupGroups
  1838. set resultObj.result.rows = rows
  1839. set resultObj.result.statistics = stat
  1840. }
  1841. catch(e)
  1842. {
  1843. set resultObj = ..%HandleError("查询单次就诊费用信息", "02010605", jsonObj, e.AsStatus())
  1844. }
  1845. quit resultObj
  1846. }
  1847. /// 报表服务类主数据来源表(置于类末尾,规避类文件最后一个成员为方法时被自动重写吞掉结束大括号)
  1848. Parameter ReportSourceTable As %String = "BS_DRGMedInsuMedicalRecord";
  1849. }