YiZhuLuRuServer.java 58 KB

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