YiZhuLuRuServer.java 57 KB

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