YiZhuLuRuServer.java 60 KB

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