YiZhuLuRuServer.java 71 KB

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