YiZhuLuRuServer.java 75 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643
  1. package thyyxxk.webserver.service.zhuyuanyisheng;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5. import com.baomidou.mybatisplus.core.metadata.IPage;
  6. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.apache.commons.collections4.ListUtils;
  9. import org.springframework.stereotype.Service;
  10. import org.springframework.transaction.annotation.Transactional;
  11. import thyyxxk.webserver.config.exception.BizException;
  12. import thyyxxk.webserver.config.exception.ExceptionEnum;
  13. import thyyxxk.webserver.constants.Capacity;
  14. import thyyxxk.webserver.constants.sidicts.ChargeStatus;
  15. import thyyxxk.webserver.dao.his.inpatient.XiangMuLuRuDao;
  16. import thyyxxk.webserver.dao.his.zhuyuanyisheng.YiZhuLuRuDao;
  17. import thyyxxk.webserver.entity.ResultVo;
  18. import thyyxxk.webserver.entity.RoleCode;
  19. import thyyxxk.webserver.entity.datamodify.GetDropdownBox;
  20. import thyyxxk.webserver.entity.datamodify.YzActOrder;
  21. import thyyxxk.webserver.entity.datamodify.ZyDetailCharge;
  22. import thyyxxk.webserver.entity.inpatient.patient.Overview;
  23. import thyyxxk.webserver.entity.inpatient.patient.Patient;
  24. import thyyxxk.webserver.entity.login.UserInfo;
  25. import thyyxxk.webserver.entity.zhuyuanyisheng.DoctorSOrderFee;
  26. import thyyxxk.webserver.entity.zhuyuanyisheng.ZyOrderZk;
  27. import thyyxxk.webserver.entity.zhuyuanyisheng.yizhuluru.*;
  28. import thyyxxk.webserver.service.PublicServer;
  29. import thyyxxk.webserver.service.externalhttp.DrgWebServices;
  30. import thyyxxk.webserver.service.heliyongyao.RationalUseServer;
  31. import thyyxxk.webserver.service.redislike.RedisLikeService;
  32. import thyyxxk.webserver.utils.*;
  33. import java.math.BigDecimal;
  34. import java.util.*;
  35. import java.util.stream.Collectors;
  36. import java.util.stream.Stream;
  37. /**
  38. * <p>
  39. * 描述: 医嘱录入
  40. * </p>
  41. *
  42. * @author xc
  43. * @date 2022-01-04 16:59
  44. */
  45. @Service
  46. @Slf4j
  47. public class YiZhuLuRuServer {
  48. private final YiZhuLuRuDao dao;
  49. private final PublicServer publicServer;
  50. private final RedisLikeService redisLikeService;
  51. private final XiangMuLuRuDao xiangMuLuRuDao;
  52. private final RationalUseServer rationalUseServer;
  53. private final DrgWebServices drgWebServices;
  54. /**
  55. * 转科的医嘱编码
  56. */
  57. private final String ZK_CODE = "06286";
  58. private final String ONCE = "ONCE";
  59. private final String ITEM = "00";
  60. private final String SMALL_PACKAGE = "01";
  61. private final String BIG_PACKAGE = "99";
  62. public YiZhuLuRuServer(YiZhuLuRuDao dao, PublicServer publicServer, RedisLikeService redisLikeService, XiangMuLuRuDao xiangMuLuRuDao, RationalUseServer rationalUseServer, DrgWebServices drgWebServices) {
  63. this.dao = dao;
  64. this.publicServer = publicServer;
  65. this.redisLikeService = redisLikeService;
  66. this.xiangMuLuRuDao = xiangMuLuRuDao;
  67. this.rationalUseServer = rationalUseServer;
  68. this.drgWebServices = drgWebServices;
  69. }
  70. public ResultVo<String> getOrderNo() {
  71. return ResultVoUtil.success(BigDecimal.valueOf(publicServer.getActOrderNo()).stripTrailingZeros().toPlainString());
  72. }
  73. public ResultVo<List<Patient>> getMyPatient() {
  74. return ResultVoUtil.success(dao.getMyPatient(TokenUtil.getTokenUserId()));
  75. }
  76. /**
  77. * 获取医嘱的名称 这里为什么不用 医嘱的code和医嘱号呢,是因为药品编码和项目编码有些一样而医嘱号,又每次只能查询一个
  78. *
  79. * @param inpatientNo 住院号
  80. * @param admissTimes 住院次数
  81. * @param orderName 前端搜索的医嘱名称
  82. * @return 返回医嘱名称去重了
  83. */
  84. public ResultVo<List<GetDropdownBox>> huoQuYiZhuMingCheng(String inpatientNo, Integer admissTimes, String orderName) {
  85. return ResultVoUtil.success(dao.huoQuYiZhuMingZi(inpatientNo, admissTimes, StringUtil.isContainChinese(orderName)));
  86. }
  87. /**
  88. * 获取患者个人的频率
  89. *
  90. * @param patNo 住院号
  91. * @param times 住院次数
  92. * @return 返回自己的医嘱频率
  93. */
  94. @Deprecated
  95. public ResultVo<List<GetDropdownBox>> huoQuGeRenPinLv(String patNo, Integer times) {
  96. return ResultVoUtil.success(dao.huoQuGeRenPinLv(patNo, times));
  97. }
  98. /**
  99. * 获取医嘱的数据
  100. * 可以根据,医嘱时间区间,执行频率,医嘱名
  101. *
  102. * @param param 查询条件
  103. * @return 返回分页数据,同时做了树状图,这样会有一个问题,那就是开了套餐的数据查询不出来
  104. */
  105. public ResultVo<List<XinZhenYzActOrder>> huoQuYiZhuShuJu(YiZhuFeiYongChaXunTiaoJian param) {
  106. QueryWrapper<?> qw = new QueryWrapper<>();
  107. qw.eq("a.inpatient_no", param.getPatNo()).eq("a.admiss_times", param.getTimes());
  108. // qw.orderByDesc("a.act_order_no");
  109. qw.orderByAsc("a.order_time");
  110. List<XinZhenYzActOrder> yiZhuList = dao.huoQuYiZhuShuJu(qw);
  111. // 还有那些没有被匹配的子级医嘱
  112. Map<BigDecimal, XinZhenYzActOrder> wuFuJiYiZhu = yiZhuList.stream().collect(Collectors.toMap(XinZhenYzActOrder::getActOrderNo, a -> a, (k1, k2) -> k1));
  113. if (ListUtil.isBlank(yiZhuList)) {
  114. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
  115. }
  116. // 做成树状图
  117. Map<BigDecimal, XinZhenYzActOrder> map = new HashMap<>();
  118. List<XinZhenYzActOrder> tree = new ArrayList<>();
  119. for (XinZhenYzActOrder item : yiZhuList) {
  120. if (item.getParentNo() == null) {
  121. tree.add(item);
  122. wuFuJiYiZhu.remove(item.getActOrderNo());
  123. }
  124. map.put(item.getActOrderNo(), item);
  125. EntityStringTrim.beanAttributeValueTrim(item);
  126. if ("00".equals(item.getSerial())) {
  127. item.setGroupNoName("项目");
  128. item.setSerialName("项目");
  129. } else {
  130. if ("01".equals(item.getSerial())) {
  131. item.setSerialName("小包装");
  132. } else if ("99".equals(item.getSerial())) {
  133. item.setSerialName("大包装");
  134. }
  135. }
  136. }
  137. for (XinZhenYzActOrder item : yiZhuList) {
  138. XinZhenYzActOrder actOrder = map.get(item.getParentNo());
  139. if (actOrder != null) {
  140. wuFuJiYiZhu.remove(item.getActOrderNo());
  141. if (actOrder.getChildren() == null) {
  142. actOrder.setChildren(new ArrayList<>());
  143. actOrder.setOrderGroup("┌");
  144. }
  145. item.setOrderGroup("丨");
  146. actOrder.getChildren().add(item);
  147. }
  148. }
  149. if (!wuFuJiYiZhu.isEmpty()) {
  150. tree.addAll(wuFuJiYiZhu.values());
  151. }
  152. // 删除前后空格
  153. EntityStringTrim.beanAttributeValueTrimList(tree);
  154. List<XinZhenYzActOrder> list = new ArrayList<>();
  155. for (XinZhenYzActOrder zy : tree) {
  156. list.add(zy);
  157. if (ListUtil.notBlank(zy.getChildren())) {
  158. zy.getChildren().get(zy.getChildren().size() - 1).setOrderGroup("└");
  159. list.addAll(zy.getChildren());
  160. zy.setChildren(null);
  161. }
  162. }
  163. return ResultVoUtil.success(list);
  164. }
  165. /**
  166. * 获取搜索的项目信息,如药品和项目
  167. *
  168. * @param code 拼音首字母,中文,编码来进行搜索
  169. * @return 返回项目信息
  170. */
  171. public ResultVo<List<YiZhuMingChen>> huoQuXiangMu(String code) {
  172. code = StringUtil.isContainChinese(code);
  173. // 药品
  174. List<YiZhuMingChen> list = dao.yiZhuYaoPing(code, publicServer.getGroupNo());
  175. // 项目
  176. list.addAll(dao.yiZhuXiangMu(code));
  177. // 模板
  178. list.addAll(dao.composeOrders(code, redisLikeService.getUserInfoByToken().getDeptCode()));
  179. EntityStringTrim.beanAttributeValueTrimList(list);
  180. return ResultVoUtil.success(list);
  181. }
  182. /**
  183. * 获取父医嘱
  184. *
  185. * @param patNo 住院号
  186. * @param times 次数
  187. * @return
  188. */
  189. public ResultVo<List<XinZhenYzActOrder>> getParentOrders(String patNo, String times) {
  190. return ResultVoUtil.success(dao.getParentOrders(patNo, times));
  191. }
  192. /**
  193. * 确认医嘱 , 这个是最新的正确的
  194. *
  195. * @param param 数据
  196. * @return 返回提示
  197. */
  198. public ResultVo<Map<String, Object>> confirmOrders(XinZhenYiZhu param) {
  199. QueryWrapper<?> qw = new QueryWrapper<>();
  200. qw.eq("a.inpatient_no", param.getInpatientNo())
  201. .eq("a.admiss_times", param.getAdmissTimes())
  202. .eq("a.status_flag", "1")
  203. .eq("a.enter_oper", TokenUtil.getTokenUserId())
  204. // 排除出院带药的医嘱
  205. .ne("a.self_buy", "4");
  206. param.setList(dao.huoQuYiZhuShuJu(qw));
  207. List<XinZhenYzActOrder> yiZhuList = param.getList();
  208. if (ListUtil.isBlank(yiZhuList)) {
  209. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有需要确认的医嘱.");
  210. }
  211. // 药品 code
  212. Set<String> yaoPingCode = new HashSet<>();
  213. // 项目的 code
  214. Set<String> xiangMuCode = new HashSet<>();
  215. for (XinZhenYzActOrder item : yiZhuList) {
  216. if (ITEM.equals(item.getSerial())) {
  217. xiangMuCode.add(item.getOrderCode());
  218. } else {
  219. yaoPingCode.add(item.getOrderCode().trim() + item.getSerial().trim());
  220. }
  221. }
  222. // 合理用药校验
  223. Map<String, List<String>> rationalUseOfMedicine = rationalUseServer.jiaoYan(param);
  224. String userCode = TokenUtil.getTokenUserId();
  225. // 获取医生开药品的权限
  226. Integer doctorLevel = dao.huoQuYiShenDengJi(userCode);
  227. XinZhenYiZhu huanZheXinXi = dao.huoQuHuanZheXinXi(param.getInpatientNo(), param.getAdmissTimes());
  228. Map<String, XinZhenYzActOrder> drug = getDrugInformation(yaoPingCode, huanZheXinXi.getSmallDept());
  229. Map<String, List<XinZhenYzActOrder>> project = getProjectInformation(xiangMuCode);
  230. // 是否可以确认
  231. boolean isThereAnyErrorMessage = false;
  232. Map<String, Object> map = new HashMap<>();
  233. List<BigDecimal> confirmOrderInformation = new ArrayList<>();
  234. Date excludeOrders = null;
  235. BigDecimal orderNo = null;
  236. for (XinZhenYzActOrder item : yiZhuList) {
  237. if (ITEM.equals(item.getSerial())) {
  238. Integer paiChiYiZhu = dao.shiFouPaiChiYiZhu(item.getOrderCode());
  239. if (excludeOrders != null) {
  240. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "一次性不能确认多条全排斥医嘱。");
  241. }
  242. if (paiChiYiZhu != null && paiChiYiZhu.equals(1)) {
  243. excludeOrders = item.getStartTime();
  244. orderNo = item.getActOrderNo();
  245. }
  246. }
  247. confirmOrderInformation.add(item.getActOrderNo());
  248. Map<String, Object> errorMessageMap = checkData(item, drug, project, huanZheXinXi, doctorLevel);
  249. String key = item.getId();
  250. if (rationalUseOfMedicine.containsKey(key)) {
  251. List<String> temp = (List<String>) errorMessageMap.get("error");
  252. if (temp == null) {
  253. errorMessageMap.put("error", rationalUseOfMedicine.get(key));
  254. } else {
  255. temp.addAll(rationalUseOfMedicine.get(key));
  256. }
  257. }
  258. log.info("错误信息:{}", JSON.toJSONString(errorMessageMap));
  259. if (!errorMessageMap.isEmpty()) {
  260. if (!isThereAnyErrorMessage && errorMessageMap.containsKey("error")) {
  261. isThereAnyErrorMessage = true;
  262. }
  263. errorMessageMap.put("data", item);
  264. map.put(item.getId(), errorMessageMap);
  265. }
  266. }
  267. if (isThereAnyErrorMessage) {
  268. return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, "请修改错误的医嘱", map);
  269. }
  270. if (excludeOrders != null) {
  271. int count = dao.thereAreUnexecutedOrders(param.getInpatientNo(), param.getAdmissTimes(), orderNo);
  272. if (count > 0) {
  273. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "有未确认和未执行的长期医嘱,无法确认全排斥医嘱,请先确认其他医嘱。");
  274. }
  275. dao.stopOrder(param.getInpatientNo(), param.getAdmissTimes(), excludeOrders, userCode, orderNo);
  276. }
  277. for (BigDecimal decimal : confirmOrderInformation) {
  278. dao.confirmOrders(decimal, userCode, new Date());
  279. }
  280. try {
  281. JSONObject jsonDrg = new JSONObject();
  282. jsonDrg.put("visit_id", Collections.singletonList(huanZheXinXi.getInpatientNo() + "_" + huanZheXinXi.getAdmissTimes()));
  283. jsonDrg.put("scene_type", 1);
  284. drgWebServices.etlClient(jsonDrg);
  285. } catch (Exception e) {
  286. e.printStackTrace();
  287. }
  288. log.info("确认的医嘱:{}", JSON.toJSONString(yiZhuList));
  289. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
  290. }
  291. private void dischargeMedicineList(Map<String, List<XinZhenYzActOrder>> map, XinZhenYiZhu huanZheXinXi) {
  292. if (dao.obtainTheNumberOfDischargedDrugs(huanZheXinXi.getInpatientNo(), huanZheXinXi.getAdmissTimes()) > 4) {
  293. throw new BizException(ExceptionEnum.LOGICAL_ERROR, "出院带药医嘱不得超过 4 种,且不得超过 15 天。");
  294. }
  295. String userCode = TokenUtil.getTokenUserId();
  296. // 根据不同的药房,生成不同的单子.
  297. for (Map.Entry<String, List<XinZhenYzActOrder>> entry : map.entrySet()) {
  298. Integer pageNo = publicServer.getTheDrugListNo();
  299. dao.summarySheetOfDrugs(pageNo, huanZheXinXi, userCode, entry.getKey());
  300. dao.insertDetailedMedicineList(pageNo, huanZheXinXi, userCode, entry.getKey(), entry.getValue());
  301. }
  302. }
  303. /**
  304. * 录入单条医嘱 新的 下面的保存医嘱的都无效了
  305. *
  306. * @param param 参数
  307. * @return 错误信息和提示
  308. */
  309. public ResultVo<Map<String, Object>> enterOrders(XinZhenYiZhu param) {
  310. XinZhenYzActOrder oldOrderNo = dao.getActOrderNoOne(param.getActOrderNo());
  311. if (oldOrderNo != null) {
  312. if (!"1".equals(oldOrderNo.getStatusFlag().trim())) {
  313. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该医嘱不是录入状态无法保存.");
  314. }
  315. if (!oldOrderNo.getInpatientNo().trim().equals(param.getInpatientNo())) {
  316. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "两次医嘱的.");
  317. }
  318. }
  319. String userCode = TokenUtil.getTokenUserId();
  320. // 获取医生开药品的权限
  321. Integer doctorLevel = dao.huoQuYiShenDengJi(userCode);
  322. XinZhenYiZhu huanZheXinXi = dao.huoQuHuanZheXinXi(param.getInpatientNo(), param.getAdmissTimes());
  323. XinZhenYzActOrder data = param.getData();
  324. // 设置 药房
  325. data.setGroupNo(param.getGroupNo());
  326. if (ITEM.equals(data.getSerial().trim())) {
  327. data.setGroupNo("00");
  328. }
  329. if (data.getParentNo() != null) {
  330. data.setSupplyCode("044");
  331. }
  332. // 药品的 code
  333. Set<String> yaoPingCode = new HashSet<>();
  334. // 项目的 code
  335. Set<String> xiangMuCode = new HashSet<>();
  336. if (ITEM.equals(data.getSerial())) {
  337. xiangMuCode.add(data.getOrderCode());
  338. } else {
  339. yaoPingCode.add(data.getOrderCode().trim() + data.getSerial().trim());
  340. }
  341. Map<String, XinZhenYzActOrder> drug = getDrugInformation(yaoPingCode, huanZheXinXi.getSmallDept());
  342. Map<String, List<XinZhenYzActOrder>> project = getProjectInformation(xiangMuCode);
  343. Map<String, Object> errorMessageMap = checkData(data, drug, project, huanZheXinXi, doctorLevel);
  344. if (data.getParentNo() != null) {
  345. XinZhenYzActOrder parentOrder = dao.getActOrderNoOne(data.getParentNo().stripTrailingZeros().toPlainString());
  346. if (parentOrder != null) {
  347. data.setFrequCode(parentOrder.getFrequCode());
  348. }
  349. }
  350. // 删除抗菌药物信息
  351. dao.deleteAntimicrobialInformation(param.getActOrderNo());
  352. // 先删除转科在插入
  353. dao.deleteTransferOrder(param.getActOrderNo());
  354. if (errorMessageMap.isEmpty()) {
  355. if (ZK_CODE.equals(data.getOrderCode())) {
  356. ZyOrderZk transferData = new ZyOrderZk();
  357. transferData
  358. .setActOrderNo(param.getActOrderNo())
  359. .setNewDept(data.getZkDeptCode())
  360. .setNewWard(data.getZkWardCode())
  361. .setOldWard(huanZheXinXi.getDeptCode())
  362. .setOldDept(huanZheXinXi.getSmallDept());
  363. dao.insertDoctorSOrder(transferData);
  364. }
  365. // 判断是不是抗菌药物
  366. XinZhenYzActOrder kssItem = drug.get(data.getOrderCode().trim() + data.getSerial().trim());
  367. if (kssItem != null && kssItem.getKjywFlag() != null && kssItem.getKjywFlag() == 1) {
  368. YzActRecordKss kss = new YzActRecordKss();
  369. kss.setActOrderNo(data.getActOrderNo());
  370. kss.setChargeCode(data.getOrderCode());
  371. kss.setYyfs(data.getYyfs());
  372. kss.setSsqk(data.getSsqk());
  373. kss.setYysj(data.getYysj());
  374. dao.insertAntimicrobialInformation(param.getActOrderNo(),
  375. kss, userCode, param.getInpatientNo(), param.getAdmissTimes());
  376. }
  377. }
  378. dao.deleteOrderNo(param.getActOrderNo(), param.getInpatientNo(), param.getAdmissTimes());
  379. dao.insertEntryOrder(huanZheXinXi, param.getData(), userCode);
  380. if (!errorMessageMap.isEmpty()) {
  381. Map<String, Object> map = new HashMap<>();
  382. errorMessageMap.put("data", data);
  383. map.put(param.getActOrderNo(), errorMessageMap);
  384. if (errorMessageMap.containsKey("error")) {
  385. return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, "请修改有错误的医嘱。", map);
  386. }
  387. }
  388. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "添加成功.");
  389. }
  390. /**
  391. * 把医嘱模板中的数据插入到 患者的医嘱表中
  392. *
  393. * @param param 参数
  394. * @return
  395. */
  396. public ResultVo<String> insertTemplateOrder(XinZhenYiZhu param) {
  397. if (StringUtil.isBlank(param.getInpatientNo())) {
  398. return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, "请先选择患者.");
  399. }
  400. Map<String, XinZhenYzActOrder> fatherAndSonDoctorSAdvice = new HashMap<>(param.getList().size());
  401. param.getList().forEach(item -> {
  402. fatherAndSonDoctorSAdvice.put(item.getId(), item);
  403. item.setActOrderNo(BigDecimal.valueOf(publicServer.getActOrderNo()));
  404. });
  405. XinZhenYiZhu huanZheXinXi = dao.huoQuHuanZheXinXi(param.getInpatientNo(), param.getAdmissTimes());
  406. String userCode = TokenUtil.getTokenUserId();
  407. param.getList().forEach(item -> {
  408. String key = item.getParentNo() != null ? item.getParentNo().stripTrailingZeros().toPlainString() : "";
  409. item.setGroupNo(param.getGroupNo());
  410. if (StringUtil.notBlank(key)) {
  411. if (fatherAndSonDoctorSAdvice.containsKey(key)) {
  412. item.setParentNo(fatherAndSonDoctorSAdvice.get(key).getActOrderNo());
  413. }
  414. }
  415. dao.insertEntryOrder(huanZheXinXi, item, userCode);
  416. });
  417. return ResultVoUtil.success();
  418. }
  419. /**
  420. * 删除单条医嘱
  421. *
  422. * @param orderNo 医嘱号
  423. * @return 提示
  424. */
  425. public ResultVo<String> toDeleteAnOrder(String orderNo) {
  426. XinZhenYzActOrder oldData = dao.getActOrderNoOne(orderNo);
  427. String message = judgeWhetherItCanBeDeleted(oldData);
  428. if (StringUtil.notBlank(message)) {
  429. return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, message);
  430. }
  431. dao.toDeleteAnOrder(orderNo, oldData.getInpatientNo());
  432. dao.deleteGroup(orderNo);
  433. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
  434. }
  435. /**
  436. * 删除多条录入的医嘱
  437. *
  438. * @param param 参数
  439. * @return 返回提示
  440. */
  441. public ResultVo<Map<String, String>> deleteMultipleOrders(XinZhenYiZhu param) {
  442. QueryWrapper<?> qw = new QueryWrapper<>();
  443. qw.eq("inpatient_no", param.getInpatientNo());
  444. qw.eq("admiss_times", param.getAdmissTimes());
  445. List<BigDecimal> list = new ArrayList<>();
  446. param.getList().forEach(item -> {
  447. list.add(item.getActOrderNo());
  448. });
  449. qw.in("act_order_no", list);
  450. List<XinZhenYzActOrder> deleteOrderList = dao.getOrdersToDelete(qw);
  451. if (ListUtil.isBlank(deleteOrderList)) {
  452. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有找到原医嘱可能已经被删除了");
  453. }
  454. Map<String, String> map = new HashMap<>();
  455. deleteOrderList.forEach(item -> {
  456. String error = judgeWhetherItCanBeDeleted(item);
  457. if (StringUtil.notBlank(error)) {
  458. map.put(item.getActOrderNo().stripTrailingZeros().toPlainString(), error);
  459. }
  460. });
  461. log.info("数据:{}", deleteOrderList);
  462. if (map.isEmpty()) {
  463. dao.deleteParentChildRelationship(param.getInpatientNo(), param.getAdmissTimes(), list);
  464. dao.deleteMultipleOrders(qw);
  465. return ResultVoUtil.fail(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
  466. }
  467. return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, "删除失败", map);
  468. }
  469. private String judgeWhetherItCanBeDeleted(XinZhenYzActOrder oldData) {
  470. StringBuilder str = new StringBuilder();
  471. if (oldData == null) {
  472. return "没有找到原医嘱可能已经被删除了";
  473. }
  474. if (!"1".equals(oldData.getStatusFlag())) {
  475. str.append("该医嘱不是录入状态,无法删除");
  476. }
  477. if (!oldData.getEnterOper().equals(TokenUtil.getTokenUserId())) {
  478. str.append("该医嘱录入人不是您,无法删除.");
  479. }
  480. return str.toString();
  481. }
  482. public ResultVo<Map<BigDecimal, String>> stopOrder(XinZhenYiZhu param) {
  483. if (ListUtil.isBlank(param.getList())) {
  484. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请先选择数据");
  485. }
  486. Map<BigDecimal, String> map = new HashMap<>();
  487. param.getList().forEach(item -> {
  488. if (item.getEndTime() == null) {
  489. map.put(item.getActOrderNo(), "停止时间不能为空。");
  490. } else {
  491. // 因为前端用的是浏览器自带的 所以要删除 T
  492. if (DateUtil.shiJianDaXiao(item.getEndTime(), item.getStartTime(), "<")) {
  493. map.put(item.getActOrderNo(), "停止时间不能小于医嘱的开始时间。");
  494. }
  495. }
  496. });
  497. if (map.isEmpty()) {
  498. dao.setStopTime(param.getList(), TokenUtil.getTokenUserId(), param.getInpatientNo(), param.getAdmissTimes());
  499. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
  500. }
  501. return ResultVoUtil.success(ExceptionEnum.ERROR_MESSAGE, "请修改有错误的医嘱", map);
  502. }
  503. @Transactional(rollbackFor = Exception.class)
  504. public ResultVo<String> voidOrders(String orderNo, String reasonForCancellation) {
  505. XinZhenYzActOrder yz = dao.getActOrderNoOne(orderNo);
  506. if (yz == null) {
  507. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "原医嘱找不到了。");
  508. }
  509. if ("6".equals(yz.getStatusFlag())) {
  510. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医嘱已作废了。");
  511. }
  512. UserInfo userInfo = redisLikeService.getUserInfoByToken();
  513. if (!DateUtil.within24Hours(yz.getStartTime())) {
  514. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "只能对24小时内的医嘱进行作废处理");
  515. }
  516. List<String> list = dao.getTheDoctorSDepartment(userInfo.getDeptCode());
  517. list.add(userInfo.getDeptCode());
  518. if (!list.contains(yz.getWardCode())) {
  519. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "非本科室开的医嘱不可作废");
  520. }
  521. if (dao.getADoctorSOrderWithADefiniteFee(yz.getInpatientNo(), yz.getAdmissTimes(), orderNo) > 0) {
  522. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该医嘱已经产生了医技费用,请对应的医技科室进行退费处理。");
  523. }
  524. if (dao.getDetailChargeFee(yz.getInstruction(), yz.getAdmissTimes(), orderNo) > 0) {
  525. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该医嘱已经产生了医技费用,请对应的医技科室进行退费处理。");
  526. }
  527. // 患者最大的 detail_sn
  528. int maxDetailSn = publicServer.getMaxDetailSn(yz.getInpatientNo(), yz.getAdmissTimes());
  529. dao.cancelMedicalTechnologyAssuranceFee(TokenUtil.getTokenUserId(), orderNo, yz.getInpatientNo(), yz.getAdmissTimes());
  530. // 如果是药品的话就需要自动退费
  531. if (!yz.getSerial().equals(ITEM)) {
  532. List<String> parentNoList = dao.getParentChildOrders(orderNo);
  533. parentNoList.add(orderNo);
  534. List<ZyDetailCharge> feeList = dao.getExpenseData(yz.getInpatientNo(), yz.getAdmissTimes(), parentNoList);
  535. if (ListUtil.notBlank(feeList)) {
  536. List<ZyDetailCharge> refundArray = new ArrayList<>(feeList.size());
  537. for (ZyDetailCharge item : feeList) {
  538. // 取负数的费用
  539. item.setChargeFee(item.getChargeFee().negate());
  540. item.setChargeAmount(item.getChargeAmount().negate());
  541. item.setOpIdCode(userInfo.getCode());
  542. item.setOriDetailSn(item.getDetailSn());
  543. // 设置 流水号
  544. item.setDetailSn(maxDetailSn += 1);
  545. item.setOrderNo(new BigDecimal(0));
  546. refundArray.add(item);
  547. }
  548. List<List<ZyDetailCharge>> fenGe = ListUtils.partition(refundArray, 20);
  549. fenGe.forEach(xiangMuLuRuDao::xiangMuTuiFei);
  550. dao.updateItemFlag(yz.getInpatientNo(), yz.getAdmissTimes(), parentNoList);
  551. }
  552. }
  553. dao.updateVoidedOrders(orderNo, userInfo.getCode(), reasonForCancellation);
  554. dao.updateChildOrders(orderNo, userInfo.getCode(), reasonForCancellation);
  555. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "撤销成功。");
  556. }
  557. /**
  558. * 获取某一个费用的详细信息
  559. *
  560. * @param code 编码
  561. * @param serial 00-项目 01-小包装的药品 99-大包装
  562. * @return 返回该费用的一些详细信息,以及一些提示信息。
  563. */
  564. public ResultVo<Map<String, Object>> huoQuFeiYongXinXi(String code, String serial, String deptCode) {
  565. Map<String, Object> map = new HashMap<>();
  566. // 一些提示
  567. List<String> prompt = new ArrayList<>();
  568. // 加载项目信息
  569. if (ITEM.equals(serial.trim())) {
  570. List<XinZhenYzActOrder> xiangMu = dao.huoQuXiangMu(code);
  571. for (XinZhenYzActOrder item : xiangMu) {
  572. if (item.getDelFlag() == 1) {
  573. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("该医嘱下的【%s】,已经被停用了,请联系物价科。", item.getOrderName()));
  574. } else if (StringUtil.isBlank(item.getNationalCode())) {
  575. prompt.add(String.format("该医嘱下面的【%s】,没有医保编码,请注意。", item.getOrderName()));
  576. } else {
  577. prompt.add(String.format("该医嘱下【%s】,医保码为:【%s】。", item.getOrderName(), item.getNationalCode()));
  578. }
  579. }
  580. if (ListUtil.isBlank(xiangMu)) {
  581. Integer paiChiYiZhu = dao.shiFouPaiChiYiZhu(code);
  582. if (paiChiYiZhu != null) {
  583. switch (paiChiYiZhu) {
  584. case 1:
  585. prompt.add("全排斥医嘱");
  586. break;
  587. case 2:
  588. prompt.add("单组排斥医嘱");
  589. break;
  590. case 3:
  591. prompt.add("多组斥医嘱");
  592. break;
  593. default:
  594. break;
  595. }
  596. }
  597. }
  598. } else {
  599. YaoPinXinXi yp = dao.huoQuYaoPin(code.trim() + serial.trim(), publicServer.getGroupNo());
  600. if (StringUtil.notBlank(deptCode)) {
  601. if (dao.restrictedUseInTheDepartment(code.trim(), deptCode) > 0) {
  602. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "该药品禁止在患者所在的科室使用。");
  603. }
  604. }
  605. if (yp == null) {
  606. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "该医嘱下的药品,可能已经被停用了,请联系药剂科。");
  607. }
  608. if (yp.getVisibleFlagZy() == 1) {
  609. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "该药品禁止住院使用。");
  610. }
  611. Integer yiShenDengJi = dao.huoQuYiShenDengJi(TokenUtil.getTokenUserId());
  612. int yiShen = yiShenDengJi == null ? 0 : yiShenDengJi;
  613. if (yp.getYpLevel() > yiShen + 1) {
  614. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "您没有开此药品的权限。");
  615. }
  616. List<YaoPingJiLiang> yaoPingJiLiang = new ArrayList<>();
  617. if (StringUtil.notBlank(yp.getWeighUnit())) {
  618. yaoPingJiLiang.add(new YaoPingJiLiang(yp.getWeighUnit(), yp.getWeighUnitName(), yp.getWeight()));
  619. }
  620. if (StringUtil.notBlank(yp.getVolUnit())) {
  621. yaoPingJiLiang.add(new YaoPingJiLiang(yp.getVolUnit(), yp.getVolUnitName(), yp.getVolum()));
  622. }
  623. if (StringUtil.notBlank(yp.getPackUnit())) {
  624. yaoPingJiLiang.add(new YaoPingJiLiang(yp.getPackUnit(), yp.getPackUnitName(), yp.getPackSize()));
  625. }
  626. if (yp.getKjywFlag() == 1) {
  627. prompt.add("抗菌药物,需填写抗菌药物医嘱附注");
  628. }
  629. if (yp.getSelfFlagYb() == 1) {
  630. prompt.add("该药品医保自费药品,如符合条件请填写记账,不是请填写自费");
  631. }
  632. if (StringUtil.isBlank(yp.getNationalCode())) {
  633. prompt.add("该药品医保没有匹配医保码");
  634. } else {
  635. prompt.add(String.format("药品医保码为:【%s】", yp.getNationalCode()));
  636. }
  637. if (yp.getStockAmount() != null && BigUtils.bigXiaoYu(yp.getStockAmount(), 10)) {
  638. prompt.add(String.format("该药品剩余数量为:【%s】", yp.getStockAmount().stripTrailingZeros().toPlainString()));
  639. }
  640. if (yp.getPsFlag() == 1) {
  641. prompt.add("此药品为皮试药品");
  642. map.put("piShi", dao.piShiGeiYaoFangShi());
  643. }
  644. map.put("yaoPingJiLiang", yaoPingJiLiang);
  645. map.put("data", yp);
  646. }
  647. map.put("prompt", prompt);
  648. return ResultVoUtil.success(map);
  649. }
  650. /**
  651. * 获取频率
  652. *
  653. * @param code 五笔,拼音,中文,编码
  654. * @return 返回对应的数据
  655. */
  656. public ResultVo<List<GetDropdownBox>> huoQuZhuYuanPinLv(String code) {
  657. return ResultVoUtil.success(dao.huoQuZhuYuanPinLv("%" + code.toUpperCase() + "%"));
  658. }
  659. /**
  660. * 获取给药方式
  661. *
  662. * @param code 五笔,拼音,中文,编码
  663. * @return 返回对应的数据
  664. */
  665. public ResultVo<List<GetDropdownBox>> huoQuGeiYaoFangShi(String code) {
  666. return ResultVoUtil.success(dao.huoQuGeiYaoFangShi(StringUtil.isContainChinese(code)));
  667. }
  668. public ResultVo<List<GetDropdownBox>> getCostFreeDosing(String code) {
  669. return ResultVoUtil.success(dao.getCostFreeDosing(StringUtil.isContainChinese(code)));
  670. }
  671. /**
  672. * 获取执行科室
  673. *
  674. * @param code 五笔,拼音,中文,编码
  675. * @return 返回对应的数据
  676. */
  677. public ResultVo<List<GetDropdownBox>> huoQuZhiXinKeShi(String code) {
  678. return ResultVoUtil.success(dao.huoQuZhiXinKeShi(StringUtil.isContainChinese(code)));
  679. }
  680. public ResultVo<Map<String, Object>> singleDataCheck(XinZhenYiZhu param) {
  681. // 获取医生开药品的权限
  682. Integer doctorLevel = dao.huoQuYiShenDengJi(TokenUtil.getTokenUserId());
  683. Set<String> yaoPingCode = new HashSet<>();
  684. Set<String> xiangMuCode = new HashSet<>();
  685. for (XinZhenYzActOrder item : param.getList()) {
  686. if (ITEM.equals(item.getSerial().trim())) {
  687. xiangMuCode.add(item.getOrderCode().trim());
  688. } else {
  689. yaoPingCode.add(item.getOrderCode().trim() + item.getSerial().trim());
  690. }
  691. }
  692. XinZhenYiZhu huanZheXinXi = dao.huoQuHuanZheXinXi(param.getInpatientNo(), param.getAdmissTimes());
  693. Map<String, Object> errorMessage = checkData(param.getList().get(0), getDrugInformation(yaoPingCode, huanZheXinXi == null ? null : huanZheXinXi.getSmallDept()), getProjectInformation(xiangMuCode), huanZheXinXi, doctorLevel);
  694. errorMessage.put("data", param.getList().get(0));
  695. return ResultVoUtil.success(errorMessage);
  696. }
  697. /**
  698. * 保存医嘱
  699. *
  700. * @param param 医嘱数据
  701. * @return 返回错误提示或者别的
  702. */
  703. @Deprecated
  704. public ResultVo<Map<String, Object>> saveTheDoctorSOrder(XinZhenYiZhu param) {
  705. log.info("上传数据:{}", JSON.toJSONStringWithDateFormat(param, DateUtil.DEFAULT_PATTERN));
  706. // 获取医生开药品的权限
  707. Integer doctorLevel = dao.huoQuYiShenDengJi(TokenUtil.getTokenUserId());
  708. // 药品的 code
  709. Set<String> yaoPingCode = new HashSet<>();
  710. // 项目的 code
  711. Set<String> xiangMuCode = new HashSet<>();
  712. // id 做 map
  713. Map<String, XinZhenYzActOrder> doctorSOrderMap = new HashMap<>(param.getList().size());
  714. for (XinZhenYzActOrder item : param.getList()) {
  715. if (ITEM.equals(item.getSerial().trim())) {
  716. xiangMuCode.add(item.getOrderCode().trim());
  717. } else {
  718. yaoPingCode.add(item.getOrderCode().trim() + item.getSerial().trim());
  719. }
  720. doctorSOrderMap.put(item.getId(), item);
  721. }
  722. // 医嘱 map {医嘱号: { 具体数据 }}
  723. // 获取患者信息
  724. XinZhenYiZhu huanZheXinXi = dao.huoQuHuanZheXinXi(param.getInpatientNo(), param.getAdmissTimes());
  725. if (huanZheXinXi == null) {
  726. throw new BizException(ExceptionEnum.LOGICAL_ERROR, "没有查询到患者的在院信息。");
  727. }
  728. // 设置婴儿标志
  729. huanZheXinXi.setInfantFlag(PublicServer.getInfantFlag(huanZheXinXi.getInpatientNo()));
  730. boolean isThereAnyErrorMessage = false;
  731. Map<String, Object> map = new HashMap<>();
  732. Map<String, XinZhenYzActOrder> drug = getDrugInformation(yaoPingCode, huanZheXinXi.getSmallDept());
  733. Map<String, List<XinZhenYzActOrder>> project = getProjectInformation(xiangMuCode);
  734. int index = 0;
  735. for (XinZhenYzActOrder item : param.getList()) {
  736. Map<String, Object> errorMessageMap = checkData(item, drug, project, huanZheXinXi, doctorLevel);
  737. if (!errorMessageMap.isEmpty()) {
  738. if (!isThereAnyErrorMessage && errorMessageMap.containsKey("error")) {
  739. isThereAnyErrorMessage = true;
  740. }
  741. map.put(item.getId(), errorMessageMap);
  742. }
  743. errorMessageMap.put("data", item);
  744. errorMessageMap.put("index", index++);
  745. }
  746. if (isThereAnyErrorMessage) {
  747. return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, "请修改错误的医嘱", map);
  748. }
  749. /* 在这里上传医嘱,一点错误信息都没了的话 */
  750. // 这个是 抗菌药物的信息
  751. List<YzActRecordKss> kssList = new ArrayList<>();
  752. // 这个是 转科医嘱的
  753. ZyOrderZk transferData = null;
  754. for (XinZhenYzActOrder item : param.getList()) {
  755. // 生成医嘱号
  756. item.setActOrderNo(BigDecimal.valueOf(publicServer.getActOrderNo()));
  757. if (item.getParentNo() != null && doctorSOrderMap.containsKey(item.getParentNo().stripTrailingZeros().toPlainString())) {
  758. item.setParentNo(doctorSOrderMap.get(item.getParentNo().stripTrailingZeros().toPlainString()).getActOrderNo());
  759. }
  760. if (item.getKjywFlag() != null && item.getKjywFlag() == 1) {
  761. YzActRecordKss kss = new YzActRecordKss();
  762. kss.setActOrderNo(item.getActOrderNo());
  763. kss.setChargeCode(item.getOrderCode());
  764. kss.setYyfs(item.getYyfs());
  765. kss.setSsqk(item.getSsqk());
  766. kss.setYysj(item.getYysj());
  767. kssList.add(kss);
  768. }
  769. if (ZK_CODE.equals(item.getOrderCode())) {
  770. transferData = new ZyOrderZk();
  771. transferData.setActOrderNo(item.getActOrderNo().stripTrailingZeros().toPlainString()).setNewDept(item.getZkDeptCode()).setNewWard(item.getZkWardCode());
  772. }
  773. }
  774. // 执行人
  775. String inputCode = TokenUtil.getTokenUserId();
  776. // 判断患者是否结算了
  777. publicServer.huanZheJieSuan(param.getInpatientNo(), param.getAdmissTimes());
  778. if (ListUtil.notBlank(kssList)) {
  779. dao.shanChuYuanKuangJunYaoWu(kssList);
  780. dao.chaRuKuangJunYaoWuXinXi(huanZheXinXi.getInpatientNo(), huanZheXinXi.getAdmissTimes(), inputCode, kssList);
  781. }
  782. if (transferData != null) {
  783. transferData.setOldWard(huanZheXinXi.getDeptCode()).setOldDept(huanZheXinXi.getSmallDept());
  784. dao.insertDoctorSOrder(transferData);
  785. }
  786. String groupNo = publicServer.getGroupNo();
  787. sendAMessageToTheNurse(param, inputCode, huanZheXinXi, groupNo);
  788. // dao.chaRuYiZhu(huanZheXinXi.getInpatientNo(), huanZheXinXi.getAdmissTimes(), inputCode, huanZheXinXi.getInfantFlag(), huanZheXinXi.getDeptCode(), huanZheXinXi.getDeptCode(), huanZheXinXi.getReferPhysician(), param.getList());
  789. return ResultVoUtil.success(map);
  790. }
  791. public ResultVo<String> doesTheTemplateExist(String name) {
  792. if (dao.duplicateTemplateName(name, TokenUtil.getTokenUserId()) == 0) {
  793. return ResultVoUtil.success();
  794. }
  795. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "模板名称重复");
  796. }
  797. public ResultVo<String> saveTemplate(YzOrderPattern param) {
  798. // 如果名字重复了,那么就修改原来的模板
  799. YzOrderPattern yzOrderPattern = dao.yuanLaiDeMuBanBianMa(param.getPatternName(), TokenUtil.getTokenUserId());
  800. UserInfo userInfo = redisLikeService.getUserInfoByCode(TokenUtil.getTokenUserId());
  801. if (null == yzOrderPattern) {
  802. yzOrderPattern = new YzOrderPattern();
  803. }
  804. String patternCode = yzOrderPattern.getPatternCode();
  805. // 有原来的模板名称而且 还要是自己创建的才能删除,否则就只能创建新的模板了
  806. if (StringUtil.notBlank(patternCode) && userInfo.getCode().equals(yzOrderPattern.getInputId())) {
  807. // 更新的时候先删除模板 原来的模板
  808. dao.shanChuLaoMuBan(patternCode);
  809. param.setPatternCode(patternCode);
  810. } else {
  811. // 设置新的模板号
  812. param.setPatternCode(publicServer.getPatternCode());
  813. }
  814. String py = PingYinUtils.pyShouZiMuDaXie(param.getPatternName());
  815. String wb = PingYinUtils.getWBCode(param.getPatternName());
  816. param.setPyCode(py.length() > 9 ? py.substring(0, 9) : py);
  817. param.setDCode(wb.length() > 9 ? wb.substring(0, 9) : wb);
  818. param.setInputId(TokenUtil.getTokenUserId());
  819. param.setDeptCode(userInfo.getDeptCode());
  820. dao.chaRuMuBan(param);
  821. Map<String, XinZhenYzActOrder> map = param.getList().stream().collect(Collectors.toMap(XinZhenYzActOrder::getId, a -> a, (k1, k2) -> k1));
  822. for (XinZhenYzActOrder item : param.getList()) {
  823. // 设置模板号
  824. item.setActOrderNo(BigDecimal.valueOf(publicServer.getPatternOrderCode()));
  825. if (item.getParentNo() != null && map.containsKey(item.getParentNo().stripTrailingZeros().toPlainString())) {
  826. item.setParentNo(map.get(item.getParentNo().stripTrailingZeros().toPlainString()).getActOrderNo());
  827. }
  828. }
  829. dao.chaRuMuBanShuJu(param.getList(), param.getPatternCode());
  830. return ResultVoUtil.success();
  831. }
  832. private void calculateDrugAmount(XinZhenYzActOrder item, XinZhenYzActOrder feiYongXinXi, List<String> 错误信息) {
  833. if (feiYongXinXi == null) {
  834. return;
  835. }
  836. if (StringUtil.notBlank(feiYongXinXi.getDrugWeightUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getDrugWeightUnit().trim())) {
  837. item.setDrugOcc(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugWeight(), 2));
  838. } else if (StringUtil.notBlank(feiYongXinXi.getDrugVolUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getDrugVolUnit())) {
  839. item.setDrugOcc(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugVolume(), 2));
  840. } else if (StringUtil.notBlank(feiYongXinXi.getPackUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getPackUnit())) {
  841. if (new BigDecimal(item.getDose().intValue()).compareTo(item.getDose()) != 0) {
  842. 错误信息.add("已经是最小单位了请不要带小数点");
  843. }
  844. item.setDrugOcc(DecimalUtil.divide(item.getDose(), feiYongXinXi.getPackSize(), 2));
  845. }
  846. }
  847. private Map<String, Object> checkData(XinZhenYzActOrder item, Map<String, XinZhenYzActOrder> drug, Map<String, List<XinZhenYzActOrder>> project, XinZhenYiZhu huanZheXinXi, Integer 医生级别) {
  848. boolean 严格校验 = huanZheXinXi != null;
  849. List<String> 错误信息 = new ArrayList<>();
  850. List<String> 警告信息 = new ArrayList<>();
  851. if (ITEM.equals(item.getSerial())) {
  852. List<XinZhenYzActOrder> 项目明细 = project.get(item.getOrderCode());
  853. // 如果这个项目下面没有费用明细,那么这就是一条口头医,口头医嘱每次只能开一个
  854. if (ListUtil.isBlank(项目明细)) {
  855. item.setDrugQuan(BigDecimal.valueOf(1));
  856. item.setDrugOcc(BigDecimal.valueOf(1));
  857. } else {
  858. for (XinZhenYzActOrder 明细 : 项目明细) {
  859. if (明细.getDelFlag() == 1) {
  860. 错误信息.add(String.format("项目:【%s】,已经被物价停用了", 明细.getOrderName()));
  861. }
  862. if (StringUtil.isBlank(明细.getNationalCode())) {
  863. 警告信息.add(String.format("项目:【%s】,没有匹配医保码", 明细.getOrderName()));
  864. }
  865. }
  866. }
  867. } else {
  868. XinZhenYzActOrder feiYongXinXi = drug.get(item.getOrderCode().trim() + item.getSerial().trim());
  869. if (feiYongXinXi != null) {
  870. if (feiYongXinXi.getDelFlag() == 1) {
  871. 错误信息.add("药品已经被停用了,请联系药剂科");
  872. }
  873. if (feiYongXinXi.getYpLevel() > 医生级别 + 1) {
  874. 错误信息.add("您没有开此药品的权限");
  875. }
  876. if (StringUtil.isBlank(feiYongXinXi.getNationalCode())) {
  877. 警告信息.add("该药品没有医保编码");
  878. }
  879. if (feiYongXinXi.getStockAmount() != null && BigUtils.bigXiaoYu(feiYongXinXi.getStockAmount(), 10)) {
  880. 警告信息.add(String.format("该药品剩余数量为:【%s】", feiYongXinXi.getStockAmount().stripTrailingZeros().toPlainString()));
  881. }
  882. if (严格校验) {
  883. if (feiYongXinXi.getDeptRestrictions() > 0) {
  884. 错误信息.add("该药品禁止在患者所在的科室使用。");
  885. }
  886. if (feiYongXinXi.getVisibleFlagZy() == 1) {
  887. 错误信息.add("该药品禁止住院患者使用。");
  888. }
  889. item.setKjywFlag(feiYongXinXi.getKjywFlag());
  890. if (feiYongXinXi.getKjywFlag() == 1) {
  891. if (item.getYyfs() == null) {
  892. 错误信息.add("请填写抗菌药物医嘱附注信息录入");
  893. } else if (item.getYyfs() == 1 || item.getYyfs() == 2) {
  894. if (item.getSsqk() == null) {
  895. 错误信息.add("当用药方式为 1 或 2 时,手术切口和用药时间不能为空");
  896. }
  897. }
  898. }
  899. }
  900. if (item.getSelfBuy() != null && "4".equals(item.getSelfBuy())) {
  901. // 如果是临时医嘱 开了就结束了.
  902. if ("ONCE".equals(item.getFrequCode())) {
  903. item.setEndTime(item.getStartTime());
  904. }
  905. if (dao.dischargeWithMedicationAdministration(item.getSupplyCode()) == 0) {
  906. 错误信息.add("出院带药给药方式不能包含费用。");
  907. }
  908. int day = 1;
  909. if (item.getStartTime() == null) {
  910. 错误信息.add("出院带药请输入开始时间。");
  911. }
  912. if (item.getEndTime() == null) {
  913. 错误信息.add("出院带药请输入结束时间。");
  914. } else {
  915. long cha = item.getEndTime().getTime() - item.getStartTime().getTime();
  916. long nd = 1000 * 24 * 60 * 60;
  917. day = (int) (cha / nd);
  918. if (day > 15) {
  919. 错误信息.add("出院带药天数不得超过 15 天,计算方式结束时间减去开始时间。");
  920. }
  921. }
  922. // 计算出院带药的领量
  923. Map<String, Short> numberOfTimesADay = dao.numberOfTimesADay(item.getFrequCode());
  924. int times = 1;
  925. for (Map.Entry<String, Short> entry : numberOfTimesADay.entrySet()) {
  926. if (entry.getValue() != null) {
  927. times += entry.getValue();
  928. }
  929. }
  930. // 最小天数一天
  931. BigDecimal total = new BigDecimal((day <= 0 ? 1 : day) * times);
  932. if (StringUtil.notBlank(feiYongXinXi.getDrugWeightUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getDrugWeightUnit().trim())) {
  933. item.setDrugOcc(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugWeight(), 2), total));
  934. item.setDrugQuan(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugWeight()), total));
  935. } else if (StringUtil.notBlank(feiYongXinXi.getDrugVolUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getDrugVolUnit())) {
  936. item.setDrugOcc(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugVolume(), 2), total));
  937. item.setDrugQuan(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugVolume()), total));
  938. } else if (StringUtil.notBlank(feiYongXinXi.getPackUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getPackUnit())) {
  939. if (new BigDecimal(item.getDose().intValue()).compareTo(item.getDose()) != 0) {
  940. 错误信息.add("已经是最小单位了请不要带小数点");
  941. }
  942. item.setDrugOcc(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getPackSize(), 2), total));
  943. item.setDrugQuan(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getPackSize()), total));
  944. }
  945. } else {
  946. // 计算普通药品的领量 durg_quan durg_occ
  947. calculateDrugAmount(item, feiYongXinXi, 错误信息);
  948. }
  949. }
  950. }
  951. if (StringUtil.isBlank(item.getOrderCode())) {
  952. 错误信息.add("项目编码不能为空");
  953. }
  954. if (StringUtil.isBlank(item.getOrderName())) {
  955. 错误信息.add("项目名称不能为空");
  956. }
  957. if (StringUtil.isBlank(item.getExecUnit())) {
  958. 错误信息.add("执行科室不能为空");
  959. } else if (item.getExecUnit().startsWith("8")) {
  960. 错误信息.add("执行科室不能选择为病区");
  961. }
  962. if (ZK_CODE.equals(item.getOrderCode())) {
  963. if (StringUtil.isBlank(item.getZkWardCode())) {
  964. 错误信息.add("转科病房不能为空");
  965. }
  966. if (StringUtil.isBlank(item.getZkDeptCode())) {
  967. 错误信息.add("转科科室不能为空");
  968. }
  969. }
  970. if (StringUtil.isBlank(item.getFrequCode())) {
  971. 错误信息.add("频次不能为空");
  972. }
  973. // 药品的校验
  974. if (!ITEM.equals(item.getSerial().trim())) {
  975. if (StringUtil.isBlank(item.getDrugSpecification())) {
  976. 错误信息.add("药品规格不能为空");
  977. }
  978. if (StringUtil.isBlank(item.getSupplyCode())) {
  979. 错误信息.add("给药方式不能为空");
  980. }
  981. if (item.getDose() == null || BigUtils.dengYu(item.getDose(), 0)) {
  982. 错误信息.add("一次计量不能为空");
  983. }
  984. if (StringUtil.isBlank(item.getDoseUnit())) {
  985. 错误信息.add("计量单位不能为空");
  986. }
  987. if (StringUtil.isBlank(item.getSerial())) {
  988. 错误信息.add("包装大小不能为空");
  989. }
  990. }
  991. if (严格校验) {
  992. // 获取患者的入院时间
  993. if (item.getOrderTime() == null) {
  994. 错误信息.add("医嘱时间不能为空");
  995. } else if (item.getStartTime() == null) {
  996. 错误信息.add("开始时间不能为空");
  997. } else if (huanZheXinXi.getAdmissDate() == null) {
  998. 错误信息.add("没有查询到患者的入院时间");
  999. } else if (DateUtil.shiJianDaXiao(item.getStartTime(), huanZheXinXi.getAdmissDate(), "<")) {
  1000. 错误信息.add("开始时间不能在患者入院之前,患者入院时间" + DateUtil.formatDatetime(huanZheXinXi.getAdmissDate()));
  1001. } else if (DateUtil.shiJianDaXiao(item.getStartTime(), item.getOrderTime(), "<")) {
  1002. 错误信息.add("开始时间不能在开医嘱之前");
  1003. }
  1004. if (item.getEndTime() != null) {
  1005. if (ONCE.equals(item.getFrequCode().trim())) {
  1006. item.setEndTime(null);
  1007. } else {
  1008. if (DateUtil.shiJianDaXiao(item.getEndTime(), item.getStartTime(), "<")) {
  1009. 错误信息.add("结束时间不能在开始时间之前");
  1010. }
  1011. }
  1012. }
  1013. }
  1014. Map<String, Object> map = new HashMap<>(Capacity.TWO);
  1015. if (ListUtil.notBlank(错误信息)) {
  1016. map.put("error", 错误信息);
  1017. }
  1018. if (ListUtil.notBlank(警告信息)) {
  1019. map.put("warning", 警告信息);
  1020. }
  1021. return map;
  1022. }
  1023. /***
  1024. * 获取项目信息
  1025. * @param xiangMuCode 项目编码
  1026. * @return 返回数据
  1027. */
  1028. private Map<String, List<XinZhenYzActOrder>> getProjectInformation(Set<String> xiangMuCode) {
  1029. if (!xiangMuCode.isEmpty()) {
  1030. return dao.huoQuXiangMuXinXi(xiangMuCode).stream().collect(Collectors.groupingBy(item -> item.getOrderCode().trim()));
  1031. }
  1032. return new HashMap<>(0);
  1033. }
  1034. /**
  1035. * 获取药品信息
  1036. *
  1037. * @param yaoPingCode 药品编码
  1038. * @return 返回数据
  1039. */
  1040. private Map<String, XinZhenYzActOrder> getDrugInformation(Set<String> yaoPingCode, String dept) {
  1041. if (!yaoPingCode.isEmpty()) {
  1042. return dao.huoQuYaoPinXinXi(yaoPingCode, publicServer.getGroupNo(), dept).stream().collect(Collectors.toMap(item -> item.getOrderCode().trim() + item.getSerial().trim(), a -> a, (k1, k2) -> k1));
  1043. }
  1044. return new HashMap<>(0);
  1045. }
  1046. private void sendAMessageToTheNurse(XinZhenYiZhu param, String inputCode, XinZhenYiZhu huanZheXinXi, String groupNo) {
  1047. List<String> content = new ArrayList<>();
  1048. for (XinZhenYzActOrder item : param.getList()) {
  1049. if (StringUtil.isBlank(item.getDrugFlag())) {
  1050. item.setDrugFlag("o");
  1051. }
  1052. if ("00".equals(item.getSerial().trim())) {
  1053. item.setGroupNo("00");
  1054. } else if ("01".equals(item.getSerial().trim()) || "99".equals(item.getSerial().trim())) {
  1055. item.setGroupNo(groupNo);
  1056. }
  1057. if (item.getEndTime() != null) {
  1058. item.setModifier(inputCode);
  1059. }
  1060. content.add(String.format("医嘱名:<span style='color:#409eff'>【%s】</span><br>" + "医嘱时间:<span style='color:#409eff'>【%tF %<tT】</span><br>" + "患者姓名:<span style='color:#409eff'>【%s】</span><br>" + "床位:<span style='color:#409eff'>【%s】</span><br>" + "频次:<span style='color:#409eff'>【%s】</span>", item.getOrderName(), item.getOrderTime(), huanZheXinXi.getName(), huanZheXinXi.getBedNo(), item.getFrequCode()));
  1061. }
  1062. publicServer.faSongXiaoXi(huanZheXinXi, content, "新增医嘱", inputCode);
  1063. }
  1064. /**
  1065. * 获取医嘱录入的模板1
  1066. *
  1067. * @param code 模板编码
  1068. * @param deptCode 科室编码
  1069. * @param muBanLeiXing 项目类型
  1070. * @param currentPage 当前页
  1071. * @param total 总数
  1072. * @return 返回模板
  1073. */
  1074. public ResultVo<IPage<YzOrderPattern>> huoQuYiZhuMuBan(String code, String deptCode, Integer muBanLeiXing, long currentPage, long total) {
  1075. IPage<YzOrderPattern> page = new Page<>();
  1076. if (total == 0) {
  1077. page.setTotal(dao.huoQuMuBanTotal(StringUtil.isContainChinese(code), TokenUtil.getTokenUserId(), deptCode, muBanLeiXing));
  1078. }
  1079. page.setRecords(dao.huoQuMuBan(StringUtil.isContainChinese(code), TokenUtil.getTokenUserId(), deptCode, muBanLeiXing, currentPage));
  1080. return ResultVoUtil.success(page);
  1081. }
  1082. /**
  1083. * 获取 我的医嘱模板的最大医嘱码
  1084. *
  1085. * @return 最大排序码
  1086. */
  1087. public ResultVo<Integer> getDoctorSOrderTemplateMaxSortNo() {
  1088. Integer sortCode = dao.getMyTemplateMaxSortNo(TokenUtil.getTokenUserId());
  1089. return ResultVoUtil.success(sortCode == null ? 0 : sortCode);
  1090. }
  1091. private String getActOrderNo() {
  1092. Random random = new Random();
  1093. String a = String.valueOf(random.nextInt(5) + 1);
  1094. String b = String.valueOf(random.nextInt(99999));
  1095. return a + b;
  1096. }
  1097. /**
  1098. * 获取模板数据
  1099. *
  1100. * @param code 模板的编码
  1101. * @return 返回数据
  1102. */
  1103. public ResultVo<List<YzActOrder>> huoQuMuBanShuJu(String code) {
  1104. List<YzActOrder> muBanShuJu = dao.huoQuMuBanShuJu(code);
  1105. Map<BigDecimal, YzActOrder> map = new HashMap<>(muBanShuJu.size());
  1106. List<YzActOrder> tree = new ArrayList<>();
  1107. for (YzActOrder item : muBanShuJu) {
  1108. item.setId(getActOrderNo());
  1109. if (item.getParentNo() == null) {
  1110. tree.add(item);
  1111. }
  1112. map.put(item.getActOrderNo(), item);
  1113. }
  1114. for (YzActOrder item : muBanShuJu) {
  1115. YzActOrder yzActOrder = map.get(item.getParentNo());
  1116. if (yzActOrder != null) {
  1117. item.setParentNo(new BigDecimal(yzActOrder.getId()));
  1118. item.setIsChildren(true);
  1119. if (yzActOrder.getChildren() == null) {
  1120. yzActOrder.setChildren(new ArrayList<>());
  1121. }
  1122. yzActOrder.getChildren().add(item);
  1123. // 没有副医嘱的就返回到最上层
  1124. } else if (!tree.contains(item)) {
  1125. item.setParentNo(null);
  1126. tree.add(item);
  1127. }
  1128. }
  1129. return ResultVoUtil.success(tree);
  1130. }
  1131. /**
  1132. * 删除医嘱模板
  1133. *
  1134. * @param patternCode 模板的编码
  1135. * @return 提示
  1136. */
  1137. public ResultVo<String> deleteADoctorSOrderTemplate(String patternCode) {
  1138. if (StringUtil.isBlank(patternCode)) {
  1139. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "模板编号为空。");
  1140. }
  1141. YzOrderPattern yzOrderPattern = dao.huoQuMuBanXinXi(patternCode);
  1142. EntityStringTrim.beanAttributeValueTrim(yzOrderPattern);
  1143. if (yzOrderPattern == null) {
  1144. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有查询到对应的模板信息。");
  1145. }
  1146. String userId = TokenUtil.getTokenUserId();
  1147. List<Integer> role = publicServer.getRoleCode().getData();
  1148. if (publicServer.needRule(role, RoleCode.PHYSICIAN_S_ORDER_TEMPLATEEDIT)) {
  1149. return startDeletingTemplates(patternCode);
  1150. }
  1151. if (userId.equals(yzOrderPattern.getInputId())) {
  1152. return startDeletingTemplates(patternCode);
  1153. }
  1154. // 主任可以删除本科室的任意模板
  1155. if (publicServer.needRule(role, RoleCode.DIRECTOR) && dao.userDeptCode(userId).equals(yzOrderPattern.getDeptCode())) {
  1156. return startDeletingTemplates(patternCode);
  1157. }
  1158. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "您没有权限删除这个模板。");
  1159. }
  1160. /**
  1161. * 删除父模板以及下面的子模板 数据
  1162. *
  1163. * @param patternCode 模板编码
  1164. */
  1165. private ResultVo<String> startDeletingTemplates(String patternCode) {
  1166. dao.shanChuMuBan(patternCode);
  1167. log.info("删除医嘱模板==> 操作人:{},模板编码:{}", TokenUtil.getTokenUserId(), patternCode);
  1168. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "删除成功。");
  1169. }
  1170. /**
  1171. * 收藏医嘱模板或者取消收藏
  1172. * 如果以及收藏了就删除,没有就收藏
  1173. *
  1174. * @param patternCode 模板号
  1175. * @return 提示
  1176. */
  1177. public ResultVo<String> collectDoctorSOrderTemplate(String patternCode) {
  1178. String userId = TokenUtil.getTokenUserId();
  1179. String saveTheDoctorSOrderNumber = dao.whetherToSaveTheDoctorSOrderTemplate(patternCode, userId);
  1180. if (StringUtil.notBlank(saveTheDoctorSOrderNumber)) {
  1181. dao.shanChuMuBan(saveTheDoctorSOrderNumber);
  1182. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "已取消删除。");
  1183. } else {
  1184. YzOrderPattern yzOrderPattern = dao.huoQuMuBanXinXi(patternCode);
  1185. EntityStringTrim.beanAttributeValueTrim(yzOrderPattern);
  1186. dao.chaRuShouCang(publicServer.getPatternCode(), yzOrderPattern.getPatternName() + "(收藏)", yzOrderPattern.getPyCode(), yzOrderPattern.getDCode(), dao.userDeptCode(userId), userId, yzOrderPattern.getPatternCode());
  1187. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "收藏成功。");
  1188. }
  1189. }
  1190. /**
  1191. * 删除或修改模板
  1192. *
  1193. * @param patternCode 模板点吗
  1194. * @param patternName 模板名称
  1195. * @param sortNo 排序号
  1196. * @param flag 标志 1-修改 2- 删除 3-收藏和取消收藏
  1197. * @return 返回给前端提示
  1198. */
  1199. public ResultVo<String> muBanCaoZuo(String patternCode, String patternName, String deptCode, Integer sortNo, Integer flag) {
  1200. if (StringUtil.isBlank(patternCode)) {
  1201. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "模板编码为空。");
  1202. }
  1203. YzOrderPattern yzOrderPattern = dao.huoQuMuBanXinXi(patternCode);
  1204. if (yzOrderPattern == null) {
  1205. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有查询到对应的模板信息。");
  1206. }
  1207. EntityStringTrim.beanAttributeValueTrim(yzOrderPattern);
  1208. String inputId = TokenUtil.getTokenUserId();
  1209. List<Integer> role = publicServer.getRoleCode().getData();
  1210. // 管理员 和 医务部的无视 规则
  1211. if (!role.contains(1) && !role.contains(38) && flag != 3) {
  1212. // 只有模板在不等于 自己的时候触发
  1213. if (!inputId.equals(yzOrderPattern.getInputId())) {
  1214. if ("2".equals(yzOrderPattern.getInputType()) && !role.contains(11)) {
  1215. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该模板为科室模板您没有权限修改或删除,请联系科主任进行修改。");
  1216. } else if ("1".equals(yzOrderPattern.getInputType())) {
  1217. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该模板为全院模板,无法删除或修改。");
  1218. }
  1219. }
  1220. }
  1221. if (flag == 1) {
  1222. if (StringUtil.isBlank(patternName)) {
  1223. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "模板名称不能为空。");
  1224. }
  1225. if (patternName.trim().equals(yzOrderPattern.getPatternName().trim()) && sortNo.equals(yzOrderPattern.getSortNo())) {
  1226. return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "数据没有变化,请勿点击。");
  1227. }
  1228. dao.genXingMuBan(patternName.trim(), PingYinUtils.pyShouZiMuDaXie(patternName), PingYinUtils.getWBCode(patternName), yzOrderPattern.getPatternCode(), sortNo);
  1229. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "修改成功。");
  1230. } else if (flag == 2) {
  1231. // 删除父模板以及下面的子模板 数据
  1232. dao.shanChuMuBan(yzOrderPattern.getPatternCode());
  1233. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "删除成功。");
  1234. } else if (flag == 3) {
  1235. // 收藏模板
  1236. String collectCode = dao.chongFuShouCang(inputId, patternCode);
  1237. if (collectCode == null) {
  1238. dao.chaRuShouCang(publicServer.getPatternCode(), yzOrderPattern.getPatternName() + "(收藏)", yzOrderPattern.getPyCode(), yzOrderPattern.getDCode(), deptCode, inputId, yzOrderPattern.getPatternCode());
  1239. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "收藏成功。");
  1240. } else {
  1241. dao.shanChuMuBan(yzOrderPattern.getPatternCode());
  1242. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "已取消收藏。");
  1243. }
  1244. }
  1245. return ResultVoUtil.success();
  1246. }
  1247. /**
  1248. * 获取医嘱下面产生的费用
  1249. *
  1250. * @param patNo 住院号
  1251. * @param times 住院次数
  1252. * @return 返回
  1253. */
  1254. public ResultVo<Map<String, Object>> expensesForGettingADoctorSOrder(String patNo, Integer times) {
  1255. List<DoctorSOrderFee> feeDate = dao.expensesForGettingADoctorSOrder(patNo, times);
  1256. // 这些编码的医嘱都是有问题的
  1257. List<String> problem = Arrays.asList("5", "6", "7", "9");
  1258. Map<String, String> problemDoctorSOrder = new HashMap<>();
  1259. Map<String, FeeSum> totalCost = new HashMap<>();
  1260. Map<String, List<DoctorSOrderFee>> map = new HashMap<>(feeDate.size());
  1261. for (DoctorSOrderFee fee : feeDate) {
  1262. // 如果这个没有就代表没有产生费用
  1263. if (fee.getOrderNoStr() == null) {
  1264. continue;
  1265. }
  1266. String chargeStatusName = ChargeStatus.getValue(fee.getChargeStatus());
  1267. String amount = fee.getChargeAmount().abs().stripTrailingZeros().toPlainString();
  1268. String money = fee.getChargeFee().stripTrailingZeros().toPlainString();
  1269. // 计算费用总和
  1270. if (totalCost.containsKey(fee.getOrderNoStr())) {
  1271. FeeSum sum = totalCost.get(fee.getOrderNoStr());
  1272. sum.setSum(DecimalUtil.add(money, sum.getSum()));
  1273. sum.setAmount(DecimalUtil.add(amount, sum.getAmount()));
  1274. totalCost.replace(fee.getOrderNoStr(), sum);
  1275. } else {
  1276. FeeSum sum = new FeeSum();
  1277. sum.setAmount(amount);
  1278. sum.setSum(money);
  1279. totalCost.put(fee.getOrderNoStr(), sum);
  1280. }
  1281. if (problem.contains(fee.getChargeStatus())) {
  1282. problemDoctorSOrder.put(fee.getOrderNoStr(), chargeStatusName);
  1283. }
  1284. fee.setChargeStatusName(chargeStatusName);
  1285. if (map.containsKey(fee.getOrderNoStr())) {
  1286. map.get(fee.getOrderNoStr()).add(fee);
  1287. } else {
  1288. List<DoctorSOrderFee> list = new ArrayList<>();
  1289. list.add(fee);
  1290. map.put(fee.getOrderNoStr(), list);
  1291. }
  1292. }
  1293. Map<String, Object> feeData = new HashMap<>(3);
  1294. feeData.put("data", map);
  1295. feeData.put("problem", problemDoctorSOrder);
  1296. feeData.put("totalCost", totalCost);
  1297. return ResultVoUtil.success(feeData);
  1298. }
  1299. /**
  1300. * 退药医嘱
  1301. *
  1302. * @param param 医嘱数组
  1303. * @return 返回提示
  1304. */
  1305. @Deprecated
  1306. public ResultVo<String> drugWithdrawal(List<String> param) {
  1307. if (ListUtil.isBlank(param)) {
  1308. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有可以退的药品。");
  1309. }
  1310. List<List<String>> list = ListUtils.partition(param, 40);
  1311. List<YzActOrder> yzActOrders = new ArrayList<>();
  1312. for (List<String> strings : list) {
  1313. yzActOrders.addAll(dao.getOriginalOrderData(strings));
  1314. }
  1315. List<List<YzActOrder>> returnedDoctorSOrder = ListUtils.partition(yzActOrders, 20);
  1316. String userCode = TokenUtil.getTokenUserId();
  1317. Map<String, String> fatherAndSonDoctorSAdvice = new HashMap<>();
  1318. for (YzActOrder item : yzActOrders) {
  1319. BigDecimal orderNo = BigDecimal.valueOf(publicServer.getActOrderNo());
  1320. BigDecimal oldOrderNo = item.getActOrderNo();
  1321. fatherAndSonDoctorSAdvice.put(oldOrderNo.stripTrailingZeros().toPlainString(), orderNo.stripTrailingZeros().toPlainString());
  1322. if (item.getParentNo() != null && fatherAndSonDoctorSAdvice.containsKey(item.getParentNo().stripTrailingZeros().toPlainString())) {
  1323. item.setParentNo(new BigDecimal(fatherAndSonDoctorSAdvice.get(item.getParentNo().stripTrailingZeros().toPlainString())));
  1324. }
  1325. item.setActOrderNo(orderNo);
  1326. }
  1327. for (List<YzActOrder> orders : returnedDoctorSOrder) {
  1328. dao.insertAReturnOrder(userCode, orders);
  1329. }
  1330. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "退药成功。");
  1331. }
  1332. /**
  1333. * 设置患者三级医生
  1334. *
  1335. * @param param 参数
  1336. * @return 返回值
  1337. */
  1338. public ResultVo<String> saveTheThirdLevelDoctor(Overview param) {
  1339. log.info("设置三级医生:==> 操作人{},数据:{}", TokenUtil.getTokenUserId(), JSON.toJSONString(param));
  1340. dao.updateTheThirdLevelDoctor(param);
  1341. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
  1342. }
  1343. /**
  1344. * 设置父子医嘱
  1345. *
  1346. * @param param 主医嘱 和 多个子医嘱
  1347. * @return 返回数据
  1348. */
  1349. public ResultVo<String> associateOrders(XinZhenYiZhu param) {
  1350. log.info("数据:{}", JSON.toJSONString(param));
  1351. XinZhenYzActOrder order = dao.getActOrderNoOne(param.getActOrderNo());
  1352. if (order.getParentNo() != null) {
  1353. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "操作失败,父医嘱不能为子医嘱。");
  1354. }
  1355. dao.associateOrders(param.getAssociatedGroup(), param.getActOrderNo());
  1356. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "关联成功。");
  1357. }
  1358. /**
  1359. * 批量检验医嘱是否正确
  1360. *
  1361. * @param list 医嘱数据
  1362. * @param huanZheXinXi 患者信息
  1363. * @param rationalUse 是否要用合理用药
  1364. * @return
  1365. */
  1366. public Map<String, Object> batchVerification(List<XinZhenYzActOrder> list,
  1367. XinZhenYiZhu huanZheXinXi,
  1368. boolean rationalUse) {
  1369. Map<String, Object> returnMap = new HashMap<>();
  1370. // 药品 code
  1371. Set<String> yaoPingCode = new HashSet<>();
  1372. // 项目的 code
  1373. Set<String> xiangMuCode = new HashSet<>();
  1374. huanZheXinXi.setList(list);
  1375. // 合理用药校验
  1376. Map<String, List<String>> rationalUseOfMedicine = rationalUse ? rationalUseServer.jiaoYan(huanZheXinXi) : new HashMap<>(list.size());
  1377. for (XinZhenYzActOrder item : list) {
  1378. if (ITEM.equals(item.getSerial())) {
  1379. xiangMuCode.add(item.getOrderCode());
  1380. } else {
  1381. yaoPingCode.add(item.getOrderCode().trim() + item.getSerial().trim());
  1382. }
  1383. }
  1384. String userCode = TokenUtil.getTokenUserId();
  1385. // 获取医生开药品的权限
  1386. Integer doctorLevel = dao.huoQuYiShenDengJi(userCode);
  1387. Map<String, XinZhenYzActOrder> drug = getDrugInformation(yaoPingCode, huanZheXinXi.getZkWard());
  1388. Map<String, List<XinZhenYzActOrder>> project = getProjectInformation(xiangMuCode);
  1389. for (XinZhenYzActOrder item : list) {
  1390. String key = item.getId();
  1391. Map<String, Object> errorMessageMap = checkData(item, drug, project, huanZheXinXi, doctorLevel);
  1392. if (rationalUseOfMedicine.containsKey(key)) {
  1393. List<String> temp = (List<String>) errorMessageMap.get("error");
  1394. if (temp == null) {
  1395. errorMessageMap.put("error", rationalUseOfMedicine.get(key));
  1396. } else {
  1397. temp.addAll(rationalUseOfMedicine.get(key));
  1398. }
  1399. }
  1400. if (!errorMessageMap.isEmpty()) {
  1401. if (errorMessageMap.get("error") != null) {
  1402. errorMessageMap.put("data", item);
  1403. returnMap.put(item.getId(), errorMessageMap);
  1404. }
  1405. }
  1406. }
  1407. return returnMap;
  1408. }
  1409. /**
  1410. * 确认出院带药医嘱
  1411. *
  1412. * @param patNo
  1413. * @param times
  1414. * @return
  1415. */
  1416. public ResultVo<Map<String, Object>> confirmTheDoctorSOrderWithMedicine(String patNo, Integer times) {
  1417. QueryWrapper<?> qw = new QueryWrapper<>();
  1418. qw.eq("a.inpatient_no", patNo)
  1419. .eq("a.admiss_times", times)
  1420. .eq("a.status_flag", "1")
  1421. .eq("a.enter_oper", TokenUtil.getTokenUserId())
  1422. .eq("a.self_buy", "4");
  1423. XinZhenYiZhu patInfo = dao.huoQuHuanZheXinXi(patNo, times);
  1424. patInfo.setList(dao.huoQuYiZhuShuJu(qw));
  1425. if (dao.obtainTheNumberOfDischargedDrugs(patNo, times) > 4) {
  1426. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "出院带药医嘱不得超过 4 种,且不得超过 15 天。");
  1427. }
  1428. String userCode = TokenUtil.getTokenUserId();
  1429. // 出院带药需要生成药单 key 是不同的药房。不同的药房就要
  1430. Map<String, List<XinZhenYzActOrder>> takeTheMedicineList = new HashMap<>(Capacity.TWO);
  1431. for (XinZhenYzActOrder item : patInfo.getList()) {
  1432. XinZhenYzActOrder feiYongXinXi = dao.getDrugOne(item.getOrderCode() + item.getSerial(), item.getGroupNo());
  1433. int day = 1;
  1434. // 如果是临时医嘱 开了就结束了.
  1435. if ("ONCE".equals(item.getFrequCode())) {
  1436. item.setEndTime(item.getStartTime());
  1437. }
  1438. if (item.getStartTime() != null && item.getEndTime() != null) {
  1439. long cha = item.getEndTime().getTime() - item.getStartTime().getTime();
  1440. long nd = 1000 * 24 * 60 * 60;
  1441. day = (int) (cha / nd);
  1442. }
  1443. // 计算出院带药的领量
  1444. Map<String, Short> numberOfTimesADay = dao.numberOfTimesADay(item.getFrequCode());
  1445. int tempTimes = 1;
  1446. for (Map.Entry<String, Short> entry : numberOfTimesADay.entrySet()) {
  1447. if (entry.getValue() != null) {
  1448. tempTimes += entry.getValue();
  1449. }
  1450. }
  1451. // 最小天数一天
  1452. BigDecimal total = new BigDecimal((day <= 0 ? 1 : day) * tempTimes);
  1453. if (StringUtil.notBlank(feiYongXinXi.getDrugWeightUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getDrugWeightUnit().trim())) {
  1454. item.setDrugOcc(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugWeight(), 2), total));
  1455. item.setDrugQuan(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugWeight()), total));
  1456. } else if (StringUtil.notBlank(feiYongXinXi.getDrugVolUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getDrugVolUnit())) {
  1457. item.setDrugOcc(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugVolume(), 2), total));
  1458. item.setDrugQuan(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugVolume()), total));
  1459. } else if (StringUtil.notBlank(feiYongXinXi.getPackUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getPackUnit())) {
  1460. item.setDrugOcc(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getPackSize(), 2), total));
  1461. item.setDrugQuan(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getPackSize()), total));
  1462. }
  1463. // 在这里更新出院带药领量
  1464. dao.updateThePickup(item);
  1465. // 费用标志为 4 的就是出院带药
  1466. if ("4".equals(item.getSelfBuy())) {
  1467. if (takeTheMedicineList.containsKey(item.getGroupNo())) {
  1468. takeTheMedicineList.get(item.getGroupNo()).add(item);
  1469. } else {
  1470. List<XinZhenYzActOrder> temp = new ArrayList<>();
  1471. temp.add(item);
  1472. takeTheMedicineList.put(item.getGroupNo(), temp);
  1473. }
  1474. }
  1475. }
  1476. Map<String, Object> check = batchVerification(patInfo.getList(), patInfo, true);
  1477. if (check.isEmpty()) {
  1478. for (XinZhenYzActOrder order : patInfo.getList()) {
  1479. // 确认医嘱
  1480. dao.confirmOrders(order.getActOrderNo(), userCode, new Date());
  1481. }
  1482. // 生成药单
  1483. dischargeMedicineList(takeTheMedicineList, patInfo);
  1484. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
  1485. } else {
  1486. return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, "请修改有错误的医嘱。", check);
  1487. }
  1488. }
  1489. }