YiZhuLuRuServer.java 73 KB

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