WfTextbookClaimServiceImpl.java 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. package com.xjrsoft.module.textbook.service.impl;
  2. import cn.dev33.satoken.stp.StpUtil;
  3. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4. import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  5. import com.baomidou.mybatisplus.core.metadata.IPage;
  6. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  7. import com.github.yulichang.base.MPJBaseServiceImpl;
  8. import com.github.yulichang.wrapper.MPJLambdaWrapper;
  9. import com.xjrsoft.common.enums.ClaimTypeEnum;
  10. import com.xjrsoft.common.enums.DeleteMark;
  11. import com.xjrsoft.common.enums.IssueModeEnum;
  12. import com.xjrsoft.common.exception.MyException;
  13. import com.xjrsoft.common.page.ConventPage;
  14. import com.xjrsoft.common.utils.VoToColumnUtil;
  15. import com.xjrsoft.module.base.entity.BaseClass;
  16. import com.xjrsoft.module.base.entity.BaseSemester;
  17. import com.xjrsoft.module.generator.entity.ImportConfig;
  18. import com.xjrsoft.module.system.entity.DictionaryDetail;
  19. import com.xjrsoft.module.teacher.entity.XjrUser;
  20. import com.xjrsoft.module.teacher.mapper.XjrUserMapper;
  21. import com.xjrsoft.module.textbook.dto.*;
  22. import com.xjrsoft.module.textbook.entity.*;
  23. import com.xjrsoft.module.textbook.mapper.*;
  24. import com.xjrsoft.module.textbook.service.IWfTextbookClaimService;
  25. import com.xjrsoft.module.textbook.vo.*;
  26. import com.xjrsoft.module.veb.util.ImportExcelUtil;
  27. import com.xjrsoft.module.workflow.entity.WorkflowFormRelation;
  28. import com.xjrsoft.module.workflow.mapper.WorkflowFormRelationMapper;
  29. import lombok.AllArgsConstructor;
  30. import org.apache.commons.collections.CollectionUtils;
  31. import org.apache.commons.collections.MapUtils;
  32. import org.apache.commons.lang3.ObjectUtils;
  33. import org.apache.commons.lang3.StringUtils;
  34. import org.apache.poi.ss.usermodel.*;
  35. import org.apache.poi.ss.util.CellRangeAddress;
  36. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  37. import org.camunda.bpm.engine.history.HistoricProcessInstance;
  38. import org.springframework.stereotype.Service;
  39. import org.springframework.transaction.annotation.Transactional;
  40. import java.io.ByteArrayOutputStream;
  41. import java.io.IOException;
  42. import java.math.BigDecimal;
  43. import java.time.LocalDateTime;
  44. import java.time.ZoneId;
  45. import java.time.format.DateTimeFormatter;
  46. import java.util.*;
  47. import java.util.function.Function;
  48. import java.util.stream.Collectors;
  49. /**
  50. * @title: 教材申领
  51. * @Author szs
  52. * @Date: 2023-12-26
  53. * @Version 1.0
  54. */
  55. @Service
  56. @AllArgsConstructor
  57. public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl<WfTextbookClaimMapper, WfTextbookClaim> implements IWfTextbookClaimService {
  58. private final WfTextbookClaimMapper wfTextbookClaimWfTextbookClaimMapper;
  59. private final WfTextbookClaimItemMapper wfTextbookClaimWfTextbookClaimItemMapper;
  60. private final XjrUserMapper xjrUserMapper;
  61. private final TextbookIssueRecordMapper textbookIssueRecordMapper;
  62. private final TextbookClaimUserMapper textbookClaimUserMapper;
  63. private final WorkflowFormRelationMapper workflowFormRelationMapper;
  64. private final TextbookWarehouseRecordMapper textbookWarehouseRecordMapper;
  65. private final TextbookStudentClaimMapper textbookStudentClaimMapper;
  66. @Override
  67. public IPage<DistributePageVo> distributePage(DistributePageDto dto) {
  68. // 申领主表记录
  69. MPJLambdaWrapper<WfTextbookClaim> wfTextbookClaimMPJLambdaWrapper = new MPJLambdaWrapper<>();
  70. wfTextbookClaimMPJLambdaWrapper
  71. .disableSubLogicDel()
  72. .select(WfTextbookClaim::getId)
  73. .select(WfTextbookClaim.class, x -> VoToColumnUtil.fieldsToColumns(DistributePageVo.class).contains(x.getProperty()))
  74. .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, WfTextbookClaim::getClaimType,
  75. wrapper -> wrapper
  76. .selectAs(DictionaryDetail::getName, DistributePageVo::getClaimTypeCn)
  77. )
  78. .leftJoin(XjrUser.class, XjrUser::getId, WfTextbookClaim::getApplicantUserId,
  79. wrapper -> wrapper
  80. .selectAs(XjrUser::getName, DistributePageVo::getApplicantUserIdCn)
  81. )
  82. .leftJoin(BaseClass.class, BaseClass::getId, WfTextbookClaim::getClassId,
  83. wrapper -> wrapper
  84. .selectAs(BaseClass::getName, DistributePageVo::getClassIdCn)
  85. )
  86. .leftJoin(BaseSemester.class, BaseSemester::getId, WfTextbookClaim::getBaseSemesterId,
  87. wrapper -> wrapper
  88. .selectAs(BaseSemester::getName, DistributePageVo::getBaseSemesterIdCn)
  89. )
  90. .leftJoin(XjrUser.class, XjrUser::getId, WfTextbookClaim::getStudentUserId,
  91. wrapper -> wrapper
  92. .selectAs(XjrUser::getName, DistributePageVo::getStudentUserIdCn)
  93. )
  94. .eq(WfTextbookClaim::getBaseSemesterId, dto.getBaseSemesterId())
  95. .eq(StringUtils.isNotEmpty(dto.getClaimType()), WfTextbookClaim::getClaimType, dto.getClaimType())
  96. .and(StringUtils.isNotEmpty(dto.getName()),
  97. wrapper -> wrapper
  98. .like(XjrUser::getName, dto.getName())
  99. .or()
  100. .like(BaseClass::getName, dto.getName())
  101. )
  102. ;
  103. // 发放状态(是否有过发放(1:未发放,2:部分发放,3:全部发放,4:有发放))
  104. if (ObjectUtils.isNotEmpty(dto.getDistributeStatus())) {
  105. // 有发放,除了未发放其他所有的状态
  106. if (dto.getDistributeStatus() == 4) {
  107. wfTextbookClaimMPJLambdaWrapper
  108. .ne(WfTextbookClaim::getStatus, 1)
  109. ;
  110. } else {
  111. wfTextbookClaimMPJLambdaWrapper
  112. .eq(WfTextbookClaim::getStatus, dto.getDistributeStatus())
  113. ;
  114. }
  115. }
  116. // 流程状态(0:未结束,1:已结束,正常通过,2:已结束,未通过,3:作废)
  117. if (ObjectUtils.isNotEmpty(dto.getWorkflowStatus())) {
  118. wfTextbookClaimMPJLambdaWrapper
  119. .eq(WfTextbookClaim::getWorkflowStatus, dto.getWorkflowStatus())
  120. ;
  121. } else {
  122. wfTextbookClaimMPJLambdaWrapper
  123. .and(wrapper -> wrapper
  124. .eq(WfTextbookClaim::getWorkflowStatus, 1)
  125. .or()
  126. .eq(WfTextbookClaim::getWorkflowStatus, 3)
  127. )
  128. ;
  129. }
  130. IPage<DistributePageVo> page = this.selectJoinListPage(ConventPage.getPage(dto), DistributePageVo.class, wfTextbookClaimMPJLambdaWrapper);
  131. // 当申领记录为空
  132. List<DistributePageVo> records = page.getRecords();
  133. List<Long> claimIds = records.stream()
  134. .map(DistributePageVo::getId)
  135. .collect(Collectors.toList());
  136. // 查询统计数据
  137. MPJLambdaWrapper<WfTextbookClaimItem> statsWrapper = new MPJLambdaWrapper<>();
  138. statsWrapper
  139. .selectAs(WfTextbookClaimItem::getWfTextbookClaimId, WfTextbookClaimItem::getWfTextbookClaimId)
  140. .selectSum(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItem::getApplicantNumber)
  141. .selectSum(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItem::getIssueNumber)
  142. .in(WfTextbookClaimItem::getWfTextbookClaimId, claimIds)
  143. .groupBy(WfTextbookClaimItem::getWfTextbookClaimId);
  144. List<WfTextbookClaimItem> statsList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItem.class, statsWrapper);
  145. Map<Long, WfTextbookClaimItem> statsMap = statsList.stream()
  146. .collect(Collectors.toMap(
  147. WfTextbookClaimItem::getWfTextbookClaimId,
  148. Function.identity(),
  149. (w1, w2) -> w1)); // 可视情况记录冲突日志
  150. // 查询子项数据
  151. MPJLambdaWrapper<WfTextbookClaimItem> itemWrapper = new MPJLambdaWrapper<>();
  152. itemWrapper.disableSubLogicDel()
  153. .select(WfTextbookClaimItem::getId)
  154. .selectAs(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItemVo::getApplicantNumber)
  155. .selectAs(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItemVo::getIssueNumber)
  156. .select(WfTextbookClaimItem.class, x -> VoToColumnUtil.fieldsToColumns(WfTextbookClaimItemVo.class).contains(x.getProperty()))
  157. .leftJoin(Textbook.class, Textbook::getId, WfTextbookClaimItem::getTextbookId,
  158. w -> w
  159. .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn)
  160. .selectAs(Textbook::getIssn, DistributeRecordVo::getIssn))
  161. .in(WfTextbookClaimItem::getWfTextbookClaimId, claimIds);
  162. List<WfTextbookClaimItemVo> itemList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItemVo.class, itemWrapper);
  163. Map<Long, List<WfTextbookClaimItemVo>> itemMap = itemList.stream()
  164. .collect(Collectors.groupingBy(WfTextbookClaimItemVo::getWfTextbookClaimId));
  165. // 查询发放记录
  166. MPJLambdaWrapper<TextbookIssueRecord> recordWrapper = new MPJLambdaWrapper<>();
  167. recordWrapper.disableSubLogicDel()
  168. .selectAs(TextbookIssueRecord::getDataId, DistributeRecordVo::getWfTextbookClaimId)
  169. .selectAs(TextbookIssueRecord::getDataItemId, DistributeRecordVo::getWfTextbookClaimItemId)
  170. .selectAs(TextbookIssueRecord::getCreateDate, DistributeRecordVo::getIssueDate)
  171. .selectAs(TextbookIssueRecord::getIssueNumber, DistributeRecordVo::getIssueNumber)
  172. .selectAs(TextbookIssueRecord::getOrderNumber, DistributeRecordVo::getOrderNumber)
  173. .selectAs(TextbookIssueRecord::getRemark, DistributeRecordVo::getRemark)
  174. .leftJoin(Textbook.class, Textbook::getId, TextbookIssueRecord::getTextbookId,
  175. w -> w
  176. .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn)
  177. .selectAs(Textbook::getIssn, DistributeRecordVo::getIssn))
  178. .leftJoin(XjrUser.class, XjrUser::getId, TextbookIssueRecord::getIssueUserId,
  179. w -> w
  180. .selectAs(XjrUser::getName, DistributeRecordVo::getIssueUser))
  181. .in(TextbookIssueRecord::getDataId, claimIds);
  182. List<DistributeRecordVo> recordList = textbookIssueRecordMapper.selectJoinList(DistributeRecordVo.class, recordWrapper);
  183. Map<Long, List<DistributeRecordVo>> recordMap = recordList.stream()
  184. .collect(Collectors.groupingBy(DistributeRecordVo::getWfTextbookClaimItemId));
  185. // 组装数据
  186. for (DistributePageVo vo : records) {
  187. Long claimId = vo.getId();
  188. // 填充统计信息
  189. if (MapUtils.isNotEmpty(statsMap) && statsMap.containsKey(claimId)) {
  190. WfTextbookClaimItem stat = statsMap.get(claimId);
  191. vo.setApplicantTatolNumber(stat.getApplicantNumber());
  192. vo.setIssueTatolNumber(stat.getIssueNumber());
  193. }
  194. // 填充子项及发放记录
  195. if (MapUtils.isNotEmpty(itemMap) && CollectionUtils.isNotEmpty(itemMap.get(claimId))) {
  196. List<WfTextbookClaimItemVo> items = itemMap.get(claimId);
  197. for (WfTextbookClaimItemVo item : items) {
  198. if (recordMap.containsKey(item.getId())) {
  199. item.setDistributeRecordVos(recordMap.get(item.getId()));
  200. }
  201. }
  202. vo.setWfTextbookClaimItemVoList(items);
  203. }
  204. }
  205. return page;
  206. }
  207. @Override
  208. @Transactional(rollbackFor = Exception.class)
  209. public Boolean add(WfTextbookClaim wfTextbookClaim) {
  210. wfTextbookClaimWfTextbookClaimMapper.insert(wfTextbookClaim);
  211. for (WfTextbookClaimItem wfTextbookClaimItem : wfTextbookClaim.getWfTextbookClaimItemList()) {
  212. wfTextbookClaimItem.setWfTextbookClaimId(wfTextbookClaim.getId());
  213. wfTextbookClaimWfTextbookClaimItemMapper.insert(wfTextbookClaimItem);
  214. }
  215. return true;
  216. }
  217. @Override
  218. @Transactional(rollbackFor = Exception.class)
  219. public Boolean update(WfTextbookClaim wfTextbookClaim) {
  220. wfTextbookClaimWfTextbookClaimMapper.updateById(wfTextbookClaim);
  221. //********************************* WfTextbookClaimItem 增删改 开始 *******************************************/
  222. {
  223. // 查出所有子级的id
  224. List<WfTextbookClaimItem> wfTextbookClaimItemList = wfTextbookClaimWfTextbookClaimItemMapper.selectList(Wrappers.lambdaQuery(WfTextbookClaimItem.class).eq(WfTextbookClaimItem::getWfTextbookClaimId, wfTextbookClaim.getId()).select(WfTextbookClaimItem::getId));
  225. List<Long> wfTextbookClaimItemIds = wfTextbookClaimItemList.stream().map(WfTextbookClaimItem::getId).collect(Collectors.toList());
  226. //原有子表单 没有被删除的主键
  227. List<Long> wfTextbookClaimItemOldIds = wfTextbookClaim.getWfTextbookClaimItemList().stream().map(WfTextbookClaimItem::getId).filter(Objects::nonNull).collect(Collectors.toList());
  228. //找到需要删除的id
  229. List<Long> wfTextbookClaimItemRemoveIds = wfTextbookClaimItemIds.stream().filter(item -> !wfTextbookClaimItemOldIds.contains(item)).collect(Collectors.toList());
  230. for (WfTextbookClaimItem wfTextbookClaimItem : wfTextbookClaim.getWfTextbookClaimItemList()) {
  231. //如果不等于空则修改
  232. if (wfTextbookClaimItem.getId() != null) {
  233. wfTextbookClaimWfTextbookClaimItemMapper.updateById(wfTextbookClaimItem);
  234. }
  235. //如果等于空 则新增
  236. else {
  237. //已经不存在的id 删除
  238. wfTextbookClaimItem.setWfTextbookClaimId(wfTextbookClaim.getId());
  239. wfTextbookClaimWfTextbookClaimItemMapper.insert(wfTextbookClaimItem);
  240. }
  241. }
  242. //已经不存在的id 删除
  243. if (wfTextbookClaimItemRemoveIds.size() > 0) {
  244. wfTextbookClaimWfTextbookClaimItemMapper.deleteBatchIds(wfTextbookClaimItemRemoveIds);
  245. }
  246. }
  247. //********************************* WfTextbookClaimItem 增删改 结束 *******************************************/
  248. return true;
  249. }
  250. @Override
  251. @Transactional(rollbackFor = Exception.class)
  252. public Boolean delete(List<Long> ids) {
  253. wfTextbookClaimWfTextbookClaimMapper.deleteBatchIds(ids);
  254. wfTextbookClaimWfTextbookClaimItemMapper.delete(Wrappers.lambdaQuery(WfTextbookClaimItem.class).in(WfTextbookClaimItem::getWfTextbookClaimId, ids));
  255. return true;
  256. }
  257. @Override
  258. public IPage<WfTextbookClaimPageVo> getPage(WfTextbookClaimPageDto dto) {
  259. dto.setUserId(StpUtil.getLoginIdAsLong());
  260. IPage<WfTextbookClaimPageVo> page = wfTextbookClaimWfTextbookClaimMapper.getPage(ConventPage.getPage(dto), dto);
  261. for (WfTextbookClaimPageVo wfTextbookClaimPageVo : page.getRecords()) {
  262. //拆分代领取人
  263. String receiveUserIdStr = wfTextbookClaimPageVo.getReceiveUserId();
  264. if (ObjectUtils.isNotEmpty(receiveUserIdStr) && !receiveUserIdStr.isEmpty()) {
  265. String[] receiveUserIdStrs = receiveUserIdStr.split(",");
  266. List<Long> receiveUserIdList = new ArrayList<>();
  267. for (String str : receiveUserIdStrs) {
  268. receiveUserIdList.add(Long.parseLong(str));
  269. }
  270. LambdaQueryWrapper<XjrUser> queryWrapper = new LambdaQueryWrapper<>();
  271. queryWrapper
  272. .in(XjrUser::getId, receiveUserIdList);
  273. List<XjrUser> xjrUserList = xjrUserMapper.selectList(queryWrapper);
  274. if (ObjectUtils.isNotEmpty(xjrUserList) && !xjrUserList.isEmpty()) {
  275. StringBuilder sb = new StringBuilder();
  276. for (int i = 0; i < xjrUserList.size(); i++) {
  277. if (i == 0) {
  278. sb.append(xjrUserList.get(i).getName());
  279. } else {
  280. sb.append(",").append(xjrUserList.get(i).getName());
  281. }
  282. }
  283. wfTextbookClaimPageVo.setReceiveUserIdCN(sb.toString());
  284. }
  285. }
  286. //加上申领项
  287. List<WfTextbookClaimItemVo> wfTextbookClaimItemVoList = wfTextbookClaimWfTextbookClaimItemMapper.getListByWfTextbookClaimId(Long.parseLong(wfTextbookClaimPageVo.getId()));
  288. if (ObjectUtils.isNotEmpty(wfTextbookClaimItemVoList) && !wfTextbookClaimItemVoList.isEmpty()) {
  289. wfTextbookClaimPageVo.setWfTextbookClaimItemList(wfTextbookClaimItemVoList);
  290. }
  291. }
  292. return page;
  293. }
  294. @Override
  295. public WfTextbookClaimVo infoDistribute(Long id) {
  296. WfTextbookClaimVo wfTextbookClaimVo = wfTextbookClaimWfTextbookClaimMapper.infoDistribute(id);
  297. if (ObjectUtils.isNotEmpty(wfTextbookClaimVo)) {
  298. //拆分代领人
  299. String receiveUserIdStr = wfTextbookClaimVo.getReceiveUserId();
  300. if (ObjectUtils.isNotEmpty(receiveUserIdStr) && !receiveUserIdStr.isEmpty()) {
  301. String[] receiveUserIdStrs = receiveUserIdStr.split(",");
  302. List<Long> receiveUserIdList = new ArrayList<>();
  303. for (String str : receiveUserIdStrs) {
  304. receiveUserIdList.add(Long.parseLong(str));
  305. }
  306. LambdaQueryWrapper<XjrUser> queryWrapper = new LambdaQueryWrapper<>();
  307. queryWrapper
  308. .in(XjrUser::getId, receiveUserIdList);
  309. List<XjrUser> xjrUserList = xjrUserMapper.selectList(queryWrapper);
  310. if (ObjectUtils.isNotEmpty(xjrUserList) && !xjrUserList.isEmpty()) {
  311. StringBuilder sb = new StringBuilder();
  312. for (XjrUser xjrUser : xjrUserList) {
  313. sb.append(",").append(xjrUser.getName());
  314. }
  315. wfTextbookClaimVo.setReceiveUserIdCN(sb.toString());
  316. }
  317. }
  318. //加上申领项
  319. List<WfTextbookClaimItemVo> wfTextbookClaimItemVoList = wfTextbookClaimWfTextbookClaimItemMapper.getListByWfTextbookClaimId(Long.parseLong(wfTextbookClaimVo.getId()));
  320. if (ObjectUtils.isNotEmpty(wfTextbookClaimItemVoList) && !wfTextbookClaimItemVoList.isEmpty()) {
  321. wfTextbookClaimVo.setWfTextbookClaimItemList(wfTextbookClaimItemVoList);
  322. }
  323. }
  324. return wfTextbookClaimVo;
  325. }
  326. @Override
  327. public List<DistributeRecordVo> distributeRecord(Long id) {
  328. MPJLambdaWrapper<TextbookIssueRecord> textbookIssueRecordMPJLambdaWrapper = new MPJLambdaWrapper<>();
  329. textbookIssueRecordMPJLambdaWrapper
  330. .disableSubLogicDel()
  331. .selectAs(TextbookIssueRecord::getCreateDate, DistributeRecordVo::getIssueDate)
  332. .selectAs(TextbookIssueRecord::getIssueNumber, DistributeRecordVo::getIssueNumber)
  333. .selectAs(TextbookIssueRecord::getOrderNumber, DistributeRecordVo::getOrderNumber)
  334. .selectAs(TextbookIssueRecord::getRemark, DistributeRecordVo::getRemark)
  335. .leftJoin(Textbook.class, Textbook::getId, TextbookIssueRecord::getTextbookId,
  336. wrapper -> wrapper
  337. .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn)
  338. )
  339. .leftJoin(XjrUser.class, XjrUser::getId, TextbookIssueRecord::getIssueUserId,
  340. wrapper -> wrapper
  341. .selectAs(XjrUser::getName, DistributeRecordVo::getIssueUser)
  342. )
  343. .eq(TextbookIssueRecord::getDataId, id)
  344. ;
  345. return textbookIssueRecordMapper.selectJoinList(DistributeRecordVo.class, textbookIssueRecordMPJLambdaWrapper);
  346. }
  347. @Override
  348. @Transactional(rollbackFor = Exception.class)
  349. public Boolean confirmDistribute(ConfirmDistributeDto dto) {
  350. WfTextbookClaim wfTextbookClaim = this.getByIdDeep(dto.getTextbookClaimId());
  351. List<WfTextbookClaimItem> wfTextbookClaimItemList = wfTextbookClaim.getWfTextbookClaimItemList();
  352. int issueTimes = wfTextbookClaim.getIssueTimes() + 1;
  353. Date nowDate = new Date();
  354. int claimTotalNum = 0;
  355. int issueTotalNum = 0;
  356. for (WfTextbookClaimItem wfTextbookClaimItem : wfTextbookClaimItemList) {
  357. claimTotalNum += wfTextbookClaimItem.getApplicantNumber();
  358. issueTotalNum += wfTextbookClaimItem.getIssueNumber();
  359. }
  360. // 获取所有入库记录
  361. List<Long> textbookWarehouseRecordIds = new ArrayList<>();
  362. for (ConfirmDistributeDto.TextbookClaimItem textbookClaimItem : dto.getTextbookClaimItemList()) {
  363. for (ConfirmDistributeDto.TextbookWarehouseRecords textbookWarehouseRecords : textbookClaimItem.getTextbookWarehouseRecords()) {
  364. textbookWarehouseRecordIds.add(textbookWarehouseRecords.getTextbookWarehouseRecordId());
  365. }
  366. }
  367. if (ObjectUtils.isEmpty(textbookWarehouseRecordIds)) {
  368. throw new MyException("当前发放项来源入库单号无效");
  369. }
  370. List<TextbookWarehouseRecord> textbookWarehouseRecordList = textbookWarehouseRecordMapper.selectList(
  371. Wrappers.lambdaQuery(TextbookWarehouseRecord.class)
  372. .in(TextbookWarehouseRecord::getId, textbookWarehouseRecordIds)
  373. .eq(TextbookWarehouseRecord::getDeleteMark, DeleteMark.NODELETE.getCode())
  374. );
  375. Map<Long, TextbookWarehouseRecord> textbookWarehouseRecordMap = textbookWarehouseRecordList.stream()
  376. .collect(Collectors.toMap(TextbookWarehouseRecord::getId, t -> t, (t1, t2) -> t1));
  377. if (ObjectUtils.isEmpty(wfTextbookClaim)
  378. || ObjectUtils.isEmpty(dto.getTextbookClaimItemList())
  379. || dto.getTextbookClaimItemList().isEmpty()
  380. || wfTextbookClaimItemList.isEmpty()
  381. ) {
  382. throw new MyException("未找到申领数据");
  383. }
  384. Map<Long, WfTextbookClaimItem> wfTextbookClaimItemMap = wfTextbookClaimItemList.stream()
  385. .collect(Collectors.toMap(WfTextbookClaimItem::getId, w -> w, (w1, w2) -> w1));
  386. // 根据学期,班级获取学生确认领取记录
  387. LambdaQueryWrapper<TextbookStudentClaim> textbookStudentClaimLambdaQueryWrapper = new LambdaQueryWrapper<>();
  388. textbookStudentClaimLambdaQueryWrapper
  389. .eq(TextbookStudentClaim::getBaseSemesterId, wfTextbookClaim.getBaseSemesterId())
  390. .eq(TextbookStudentClaim::getClassId, wfTextbookClaim.getClassId())
  391. ;
  392. List<TextbookStudentClaim> textbookStudentClaimList = textbookStudentClaimMapper.selectList(textbookStudentClaimLambdaQueryWrapper);
  393. Map<String, TextbookStudentClaim> byUserIdAndTextbookId = textbookStudentClaimList.stream()
  394. .collect(Collectors.toMap(t -> "" + t.getStudentUserId() + t.getTextbookId(), t -> t, (t1, t2) -> t1));
  395. // 处理出库单号
  396. StringBuilder sb = new StringBuilder();
  397. sb.append("CK");
  398. LocalDateTime now = LocalDateTime.now();
  399. DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
  400. String nowStr = now.format(dateTimeFormatter);
  401. sb.append(nowStr);
  402. int oldOrderInteger = 0;
  403. int oldOrderLastInteger = 0;
  404. // 操作每一个申领项
  405. WfTextbookClaimItem updateWfTextbookClaimItem;
  406. // 学生确认处理
  407. List<TextbookStudentClaim> insertList = new ArrayList<>();
  408. List<TextbookStudentClaim> updateList = new ArrayList<>();
  409. TextbookStudentClaim oldTextbookStudentClaim;
  410. TextbookStudentClaim insertTextbookStudentClaim;
  411. TextbookStudentClaim updateTextbookStudentClaim;
  412. Long loginUserId = StpUtil.getLoginIdAsLong();
  413. for (ConfirmDistributeDto.TextbookClaimItem textbookClaimItem : dto.getTextbookClaimItemList()) {
  414. // WfTextbookClaimItem wfTextbookClaimItem = wfTextbookClaimWfTextbookClaimItemMapper.selectById(textbookClaimItem.getTextbookClaimItemId());
  415. WfTextbookClaimItem wfTextbookClaimItem = wfTextbookClaimItemMap.get(textbookClaimItem.getTextbookClaimItemId());
  416. if (ObjectUtils.isEmpty(wfTextbookClaimItem)) {
  417. throw new MyException("申领详细数据发生更改,请刷新页面");
  418. }
  419. //判断总发放数量是否超出该申请项的申请数量
  420. int issueNumber = ObjectUtils.isEmpty(wfTextbookClaimItem.getIssueNumber()) ? 0 : wfTextbookClaimItem.getIssueNumber();//已发放
  421. int applicantNumber = ObjectUtils.isEmpty(wfTextbookClaimItem.getApplicantNumber()) ? 0 : wfTextbookClaimItem.getApplicantNumber();//申领总数量
  422. int confirmNumber = ObjectUtils.isEmpty(textbookClaimItem.getConfirmTotalNumber()) ? 0 : textbookClaimItem.getConfirmTotalNumber();//本次发放
  423. issueTotalNum += confirmNumber;
  424. if (issueNumber + confirmNumber > applicantNumber) {
  425. throw new MyException(textbookClaimItem.getTextbookIdCn() + "发放总数量超出申领数量");
  426. }
  427. TextbookIssueRecord textbookIssueRecord;
  428. // 出库单号前缀
  429. oldOrderInteger += 1;
  430. String newOrder = String.format("%03d", oldOrderInteger); // 补零并格式化为三位数
  431. String oldPrex = sb + newOrder + "-";
  432. for (ConfirmDistributeDto.TextbookWarehouseRecords textbookWarehouseRecords : textbookClaimItem.getTextbookWarehouseRecords()) {
  433. TextbookWarehouseRecord textbookWarehouseRecord = textbookWarehouseRecordMap.get(textbookWarehouseRecords.getTextbookWarehouseRecordId());
  434. if (ObjectUtils.isEmpty(textbookWarehouseRecord)) {
  435. throw new MyException("未找到对应入库详细数据");
  436. }
  437. if (textbookWarehouseRecord.getRemainNumber() < textbookWarehouseRecords.getConfirmNumber()) {
  438. throw new MyException("发放数量大于库存数量");
  439. }
  440. //更新教材入库中的的库存数量
  441. textbookWarehouseRecordMapper.updateById(new TextbookWarehouseRecord() {{
  442. setModifyUserId(StpUtil.getLoginIdAsLong());
  443. setModifyDate(nowDate);
  444. setId(textbookWarehouseRecord.getId());
  445. setIssuedNumber(ObjectUtils.isEmpty(textbookWarehouseRecord.getIssuedNumber()) ? 0 : textbookWarehouseRecord.getIssuedNumber()
  446. + textbookWarehouseRecords.getConfirmNumber());
  447. setRemainNumber(ObjectUtils.isEmpty(textbookWarehouseRecord.getRemainNumber()) ? 0 : textbookWarehouseRecord.getRemainNumber()
  448. - textbookWarehouseRecords.getConfirmNumber()
  449. );
  450. }});
  451. //增加出库记录
  452. textbookIssueRecord = new TextbookIssueRecord();
  453. textbookIssueRecord.setBaseSemesterId(wfTextbookClaim.getBaseSemesterId());
  454. // 处理出库单号
  455. // 根据当前申领项主键id和入库主键id查找时候已经有了出库记录
  456. LambdaQueryWrapper<TextbookIssueRecord> maxOrderNumberLambdaQueryWrapper = new LambdaQueryWrapper<>();
  457. maxOrderNumberLambdaQueryWrapper
  458. .eq(TextbookIssueRecord::getDataItemId, wfTextbookClaimItem.getId())
  459. .eq(TextbookIssueRecord::getTextbookWarehouseRecordId, textbookWarehouseRecord.getId())
  460. .eq(TextbookIssueRecord::getDeleteMark, DeleteMark.NODELETE.getCode())
  461. .orderByDesc(TextbookIssueRecord::getOrderNumber)
  462. .last("limit 1")
  463. ;
  464. TextbookIssueRecord maxOrderNumber = textbookIssueRecordMapper.selectOne(maxOrderNumberLambdaQueryWrapper);
  465. if (ObjectUtils.isNotEmpty(maxOrderNumber)
  466. && ObjectUtils.isNotEmpty(maxOrderNumber.getOrderNumber())
  467. ) {
  468. String oldOrderNumber = maxOrderNumber.getOrderNumber();
  469. oldPrex = oldOrderNumber.substring(0, oldOrderNumber.length() - 3);
  470. oldOrderInteger -= 1;
  471. String oldOrder = oldOrderNumber.substring(oldOrderNumber.length() - 3);
  472. oldOrderLastInteger = Integer.parseInt(oldOrder);
  473. }
  474. oldOrderLastInteger += 1;
  475. String newLastOrder = String.format("%03d", oldOrderLastInteger); // 补零并格式化为三位数
  476. textbookIssueRecord.setOrderNumber(oldPrex + newLastOrder);
  477. if (ObjectUtils.isNotEmpty(wfTextbookClaim.getClaimType())
  478. && wfTextbookClaim.getClaimType().equals(ClaimTypeEnum.ClaimStudent.getCode())
  479. ) {
  480. textbookIssueRecord.setIssueMode(IssueModeEnum.ImStudent.getCode());
  481. }
  482. if (ObjectUtils.isNotEmpty(wfTextbookClaim.getClaimType())
  483. && wfTextbookClaim.getClaimType().equals(ClaimTypeEnum.ClaimClass.getCode())
  484. ) {
  485. textbookIssueRecord.setIssueMode(IssueModeEnum.ImClass.getCode());
  486. }
  487. if (ObjectUtils.isNotEmpty(wfTextbookClaim.getClaimType())
  488. && wfTextbookClaim.getClaimType().equals(ClaimTypeEnum.ClaimTeacher.getCode())
  489. ) {
  490. textbookIssueRecord.setIssueMode(IssueModeEnum.ImTeacher.getCode());
  491. }
  492. textbookIssueRecord.setDataId(wfTextbookClaim.getId());
  493. textbookIssueRecord.setDataItemId(wfTextbookClaimItem.getId());
  494. textbookIssueRecord.setTextbookWarehouseRecordId(textbookWarehouseRecords.getTextbookWarehouseRecordId());
  495. textbookIssueRecord.setTextbookId(wfTextbookClaimItem.getTextbookId());
  496. textbookIssueRecord.setIssueNumber(textbookWarehouseRecords.getConfirmNumber());
  497. textbookIssueRecord.setRecedeNumber(0);
  498. textbookIssueRecord.setActualIssueNumber(textbookWarehouseRecords.getConfirmNumber());
  499. textbookIssueRecord.setActualTotalPrice(textbookWarehouseRecord.getSubtotal().multiply(BigDecimal.valueOf(textbookWarehouseRecords.getConfirmNumber())));
  500. if (ObjectUtils.isNotEmpty(dto.getReceiveUserId())) {
  501. textbookIssueRecord.setReceiveUserId(dto.getReceiveUserId());
  502. } else {
  503. textbookIssueRecord.setReceiveUserId(wfTextbookClaim.getApplicantUserId());
  504. }
  505. textbookIssueRecord.setIssueUserId(StpUtil.getLoginIdAsLong());
  506. textbookIssueRecord.setCreateDate(nowDate);
  507. textbookIssueRecord.setRemark(dto.getRemark());
  508. textbookIssueRecord.setIssueTimes(issueTimes);
  509. textbookIssueRecordMapper.insert(textbookIssueRecord);
  510. // 如果申领项是个人申领,发放的时候应该直接帮助学生确认领取
  511. if (ClaimTypeEnum.ClaimStudent.getCode().equals(wfTextbookClaim.getClaimType())) {
  512. oldTextbookStudentClaim = byUserIdAndTextbookId.get("" + wfTextbookClaim.getApplicantUserId() + wfTextbookClaimItem.getTextbookId());
  513. if (ObjectUtils.isNotEmpty(oldTextbookStudentClaim)
  514. && (ObjectUtils.isEmpty(oldTextbookStudentClaim.getClaimSource())
  515. || oldTextbookStudentClaim.getClaimSource() != 1)
  516. ) {
  517. updateTextbookStudentClaim = new TextbookStudentClaim();
  518. updateTextbookStudentClaim.setId(oldTextbookStudentClaim.getId());
  519. updateTextbookStudentClaim.setIsClaim(1);
  520. updateTextbookStudentClaim.setModifyDate(nowDate);
  521. updateTextbookStudentClaim.setModifyUserId(loginUserId);
  522. updateTextbookStudentClaim.setTextbookWarehouseRecordId(textbookWarehouseRecord.getId());
  523. updateTextbookStudentClaim.setPrice(textbookWarehouseRecord.getSubtotal());
  524. updateTextbookStudentClaim.setClaimSource(2);
  525. updateList.add(updateTextbookStudentClaim);
  526. } else {
  527. insertTextbookStudentClaim = new TextbookStudentClaim();
  528. insertTextbookStudentClaim.setBaseSemesterId(wfTextbookClaim.getBaseSemesterId());
  529. insertTextbookStudentClaim.setClassId(wfTextbookClaim.getClassId());
  530. insertTextbookStudentClaim.setStudentUserId(wfTextbookClaim.getApplicantUserId());
  531. insertTextbookStudentClaim.setTextbookId(wfTextbookClaimItem.getTextbookId());
  532. insertTextbookStudentClaim.setIsClaim(1);
  533. insertTextbookStudentClaim.setCreateDate(nowDate);
  534. insertTextbookStudentClaim.setCreateUserId(loginUserId);
  535. insertTextbookStudentClaim.setTextbookWarehouseRecordId(textbookWarehouseRecord.getId());
  536. insertTextbookStudentClaim.setPrice(textbookWarehouseRecord.getSubtotal());
  537. insertTextbookStudentClaim.setClaimSource(2);
  538. insertList.add(insertTextbookStudentClaim);
  539. }
  540. }
  541. }
  542. // 修改征订项发放数量
  543. updateWfTextbookClaimItem = new WfTextbookClaimItem();
  544. updateWfTextbookClaimItem.setId(wfTextbookClaimItem.getId());
  545. updateWfTextbookClaimItem.setIssueNumber(
  546. ObjectUtils.isEmpty(wfTextbookClaimItem.getIssueNumber()) ? 0 : wfTextbookClaimItem.getIssueNumber()
  547. + textbookClaimItem.getConfirmTotalNumber()
  548. );
  549. wfTextbookClaimWfTextbookClaimItemMapper.updateById(updateWfTextbookClaimItem);
  550. }
  551. if (CollectionUtils.isNotEmpty(insertList)) {
  552. for (TextbookStudentClaim insert : insertList) {
  553. textbookStudentClaimMapper.insert(insert);
  554. }
  555. }
  556. if (CollectionUtils.isNotEmpty(updateList)) {
  557. for (TextbookStudentClaim update : updateList) {
  558. textbookStudentClaimMapper.updateById(update);
  559. }
  560. }
  561. // 查询当前申领所有子项是否已经完成, 发放数量大于申领数量
  562. MPJLambdaWrapper<WfTextbookClaimItem> wfTextbookClaimItemMPJLambdaWrapper = new MPJLambdaWrapper<>();
  563. wfTextbookClaimItemMPJLambdaWrapper
  564. .select(WfTextbookClaimItem::getId)
  565. .innerJoin(WfTextbookClaim.class, WfTextbookClaim::getId, WfTextbookClaimItem::getWfTextbookClaimId)
  566. .lt(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItem::getApplicantNumber)
  567. .eq(WfTextbookClaimItem::getWfTextbookClaimId, wfTextbookClaim.getId())
  568. ;
  569. long count = wfTextbookClaimWfTextbookClaimItemMapper.selectCount(wfTextbookClaimItemMPJLambdaWrapper);
  570. WfTextbookClaim updateWfTextbookClaim = new WfTextbookClaim();
  571. updateWfTextbookClaim.setId(wfTextbookClaim.getId());
  572. if (count > 0) {
  573. updateWfTextbookClaim.setStatus(2);
  574. } else {
  575. updateWfTextbookClaim.setStatus(3);
  576. }
  577. updateWfTextbookClaim.setIssueTimes(issueTimes);
  578. updateWfTextbookClaim.setModifyUserId(StpUtil.getLoginIdAsLong());
  579. updateWfTextbookClaim.setModifyDate(nowDate);
  580. //更新申领项中的已经发放数量
  581. wfTextbookClaimWfTextbookClaimMapper.updateById(updateWfTextbookClaim);
  582. return true;
  583. }
  584. @Override
  585. @Transactional(rollbackFor = Exception.class)
  586. public Boolean nullify(NullifyWfTextbookClaimDto dto) {
  587. // 作废申领流程数据,应该移除领取人记录
  588. LambdaUpdateWrapper<TextbookClaimUser> textbookClaimUserLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
  589. textbookClaimUserLambdaUpdateWrapper
  590. .eq(TextbookClaimUser::getWfTextbookClaimId, dto.getId())
  591. ;
  592. textbookClaimUserMapper.delete(textbookClaimUserLambdaUpdateWrapper);
  593. WfTextbookClaim wfTextbookClaim = new WfTextbookClaim();
  594. wfTextbookClaim.setId(dto.getId());
  595. wfTextbookClaim.setWorkflowStatus(3);
  596. wfTextbookClaim.setModifyDate(new Date());
  597. wfTextbookClaim.setModifyUserId(StpUtil.getLoginIdAsLong());
  598. this.updateById(wfTextbookClaim);
  599. return true;
  600. }
  601. @Override
  602. @Transactional
  603. public Boolean dataHandleAddClaimUserNode(Long id) {
  604. WfTextbookClaim wfTextbookClaim = this.getById(id);
  605. // 根据数据id找到所在流程得状态
  606. WorkflowFormRelation workflowFormRelation = workflowFormRelationMapper.selectOne(
  607. Wrappers.lambdaQuery(WorkflowFormRelation.class)
  608. .eq(WorkflowFormRelation::getFormKeyValue, id)
  609. );
  610. if (ObjectUtils.isNotEmpty(wfTextbookClaim)
  611. && ObjectUtils.isNotEmpty(wfTextbookClaim.getClaimType())
  612. && ObjectUtils.isNotEmpty(workflowFormRelation)
  613. && HistoricProcessInstance.STATE_COMPLETED.equals(workflowFormRelation.getCurrentState())
  614. ) {
  615. //所有需要添加的可领取人ID
  616. List<TextbookClaimUser> textbookClaimUserList = new ArrayList<>();
  617. //申领人自己可以领取
  618. textbookClaimUserList.add(new TextbookClaimUser() {{
  619. setCreateDate(new Date());
  620. setWfTextbookClaimId(wfTextbookClaim.getId());
  621. setUserId(wfTextbookClaim.getApplicantUserId());
  622. if (ClaimTypeEnum.ClaimTeacher.getCode().equals(wfTextbookClaim.getClaimType())
  623. || ClaimTypeEnum.ClaimClass.getCode().equals(wfTextbookClaim.getClaimType())
  624. ) {
  625. setUserType(2);
  626. }
  627. if (ClaimTypeEnum.ClaimStudent.getCode().equals(wfTextbookClaim.getClaimType())) {
  628. setUserType(1);
  629. }
  630. }});
  631. //申领类型是班级申领,学生代表可领取
  632. if (ClaimTypeEnum.ClaimClass.getCode().equals(wfTextbookClaim.getClaimType())
  633. && ObjectUtils.isNotEmpty(wfTextbookClaim.getApplicantUserId())
  634. && ObjectUtils.isNotEmpty(wfTextbookClaim.getStudentUserId())
  635. && !Objects.equals(wfTextbookClaim.getApplicantUserId(), wfTextbookClaim.getStudentUserId())
  636. ) {
  637. textbookClaimUserList.add(new TextbookClaimUser() {{
  638. setCreateDate(new Date());
  639. setWfTextbookClaimId(wfTextbookClaim.getId());
  640. setUserId(wfTextbookClaim.getStudentUserId());
  641. setUserType(1);
  642. }});
  643. }
  644. //申领类型是教师申领,领取人可领取
  645. if (ClaimTypeEnum.ClaimTeacher.getCode().equals(wfTextbookClaim.getClaimType())
  646. && ObjectUtils.isNotEmpty(wfTextbookClaim.getApplicantUserId())
  647. && ObjectUtils.isNotEmpty(wfTextbookClaim.getClaimUserId())
  648. && !Objects.equals(wfTextbookClaim.getApplicantUserId(), wfTextbookClaim.getClaimUserId())
  649. ) {
  650. textbookClaimUserList.add(new TextbookClaimUser() {{
  651. setCreateDate(new Date());
  652. setWfTextbookClaimId(wfTextbookClaim.getId());
  653. setUserId(wfTextbookClaim.getClaimUserId());
  654. setUserType(2);
  655. }});
  656. }
  657. for (TextbookClaimUser textbookClaimUser : textbookClaimUserList) {
  658. textbookClaimUserMapper.insert(textbookClaimUser);
  659. }
  660. // 修改流程结束状态
  661. WfTextbookClaim updateWfTextbookClaim = new WfTextbookClaim();
  662. updateWfTextbookClaim.setId(wfTextbookClaim.getId());
  663. updateWfTextbookClaim.setWorkflowStatus(1);
  664. this.updateById(updateWfTextbookClaim);
  665. }
  666. if (ObjectUtils.isNotEmpty(wfTextbookClaim)
  667. && ObjectUtils.isNotEmpty(workflowFormRelation)
  668. && !HistoricProcessInstance.STATE_COMPLETED.equals(workflowFormRelation.getCurrentState())
  669. && !HistoricProcessInstance.STATE_ACTIVE.equals(workflowFormRelation.getCurrentState())
  670. ) {
  671. // 修改教材申领流程状态为不正常的结束
  672. WfTextbookClaim updateWfTextbookClaim = new WfTextbookClaim();
  673. updateWfTextbookClaim.setId(wfTextbookClaim.getId());
  674. updateWfTextbookClaim.setWorkflowStatus(2);
  675. this.updateById(updateWfTextbookClaim);
  676. }
  677. return true;
  678. }
  679. @Override
  680. public ByteArrayOutputStream claimRecordsExportQuery(ClaimRecordsExportQueryDto dto) throws IOException {
  681. MPJLambdaWrapper<WfTextbookClaim> wfTextbookClaimMPJLambdaWrapper = new MPJLambdaWrapper<>();
  682. wfTextbookClaimMPJLambdaWrapper
  683. .disableSubLogicDel()
  684. .select(WfTextbookClaim::getId)
  685. .select(WfTextbookClaim.class, x -> VoToColumnUtil.fieldsToColumns(ClaimRecordsExportQueryVo.class).contains(x.getProperty()))
  686. .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, WfTextbookClaim::getClaimType,
  687. wrapper -> wrapper
  688. .selectAs(DictionaryDetail::getName, ClaimRecordsExportQueryVo::getClaimTypeCn)
  689. )
  690. .leftJoin(XjrUser.class, XjrUser::getId, WfTextbookClaim::getApplicantUserId,
  691. wrapper -> wrapper
  692. .selectAs(XjrUser::getName, ClaimRecordsExportQueryVo::getApplicantUserIdCn)
  693. )
  694. .leftJoin(BaseClass.class, BaseClass::getId, WfTextbookClaim::getClassId,
  695. wrapper -> wrapper
  696. .selectAs(BaseClass::getName, ClaimRecordsExportQueryVo::getClassIdCn)
  697. )
  698. .leftJoin(BaseSemester.class, BaseSemester::getId, WfTextbookClaim::getBaseSemesterId,
  699. wrapper -> wrapper
  700. .selectAs(BaseSemester::getName, ClaimRecordsExportQueryVo::getBaseSemesterIdCn)
  701. )
  702. .eq(WfTextbookClaim::getWorkflowStatus, 1)
  703. .eq(ObjectUtils.isNotEmpty(dto.getBaseSemesterId()), WfTextbookClaim::getBaseSemesterId, dto.getBaseSemesterId())
  704. ;
  705. List<ClaimRecordsExportQueryVo> dataList = this.selectJoinList(ClaimRecordsExportQueryVo.class, wfTextbookClaimMPJLambdaWrapper);
  706. List<Long> claimIds = dataList.stream()
  707. .map(ClaimRecordsExportQueryVo::getId)
  708. .collect(Collectors.toList());
  709. // 查询统计数据
  710. MPJLambdaWrapper<WfTextbookClaimItem> statsWrapper = new MPJLambdaWrapper<>();
  711. statsWrapper
  712. .selectAs(WfTextbookClaimItem::getWfTextbookClaimId, WfTextbookClaimItem::getWfTextbookClaimId)
  713. .selectSum(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItem::getApplicantNumber)
  714. .selectSum(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItem::getIssueNumber)
  715. .in(WfTextbookClaimItem::getWfTextbookClaimId, claimIds)
  716. .groupBy(WfTextbookClaimItem::getWfTextbookClaimId);
  717. List<WfTextbookClaimItem> statsList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItem.class, statsWrapper);
  718. Map<Long, WfTextbookClaimItem> statsMap = statsList.stream()
  719. .collect(Collectors.toMap(
  720. WfTextbookClaimItem::getWfTextbookClaimId,
  721. Function.identity(),
  722. (w1, w2) -> w1)); // 可视情况记录冲突日志
  723. // 查询子项数据
  724. MPJLambdaWrapper<WfTextbookClaimItem> itemWrapper = new MPJLambdaWrapper<>();
  725. itemWrapper.disableSubLogicDel()
  726. .select(WfTextbookClaimItem::getId)
  727. .selectAs(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItemVo::getApplicantNumber)
  728. .selectAs(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItemVo::getIssueNumber)
  729. .select(WfTextbookClaimItem.class, x -> VoToColumnUtil.fieldsToColumns(WfTextbookClaimItemVo.class).contains(x.getProperty()))
  730. .leftJoin(Textbook.class, Textbook::getId, WfTextbookClaimItem::getTextbookId,
  731. w -> w
  732. .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn)
  733. .selectAs(Textbook::getIssn, DistributeRecordVo::getIssn))
  734. .in(WfTextbookClaimItem::getWfTextbookClaimId, claimIds);
  735. List<WfTextbookClaimItemVo> itemList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItemVo.class, itemWrapper);
  736. Map<Long, List<WfTextbookClaimItemVo>> itemMap = itemList.stream()
  737. .collect(Collectors.groupingBy(WfTextbookClaimItemVo::getWfTextbookClaimId));
  738. // 查询发放记录
  739. MPJLambdaWrapper<TextbookIssueRecord> recordWrapper = new MPJLambdaWrapper<>();
  740. recordWrapper.disableSubLogicDel()
  741. .selectAs(TextbookIssueRecord::getDataId, DistributeRecordVo::getWfTextbookClaimId)
  742. .selectAs(TextbookIssueRecord::getDataItemId, DistributeRecordVo::getWfTextbookClaimItemId)
  743. .selectAs(TextbookIssueRecord::getCreateDate, DistributeRecordVo::getIssueDate)
  744. .selectAs(TextbookIssueRecord::getIssueNumber, DistributeRecordVo::getIssueNumber)
  745. .selectAs(TextbookIssueRecord::getOrderNumber, DistributeRecordVo::getOrderNumber)
  746. .selectAs(TextbookIssueRecord::getRemark, DistributeRecordVo::getRemark)
  747. .leftJoin(Textbook.class, Textbook::getId, TextbookIssueRecord::getTextbookId,
  748. w -> w
  749. .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn)
  750. .selectAs(Textbook::getIssn, DistributeRecordVo::getIssn))
  751. .leftJoin(XjrUser.class, XjrUser::getId, TextbookIssueRecord::getIssueUserId,
  752. w -> w
  753. .selectAs(XjrUser::getName, DistributeRecordVo::getIssueUser))
  754. .in(TextbookIssueRecord::getDataId, claimIds);
  755. List<DistributeRecordVo> recordList = textbookIssueRecordMapper.selectJoinList(DistributeRecordVo.class, recordWrapper);
  756. Map<Long, List<DistributeRecordVo>> recordMap = recordList.stream()
  757. .collect(Collectors.groupingBy(DistributeRecordVo::getWfTextbookClaimItemId));
  758. // 开始写入
  759. Workbook workbook = new XSSFWorkbook();
  760. // 创建一个工作表(sheet)
  761. String sheetName = "sheet1";
  762. Sheet sheet = workbook.createSheet(sheetName);
  763. // 出参vo字段数量
  764. ClaimRecordsExportQueryVo obj = new ClaimRecordsExportQueryVo();
  765. List<ImportConfig> importConfigs = ImportExcelUtil.allFields(obj);
  766. // 写大标题
  767. int rowNumber = 0;
  768. ImportExcelUtil.createBigHead(workbook, sheet, "教材申领情况", rowNumber++, importConfigs.size() - 1);
  769. // 表头
  770. ImportExcelUtil.createHead(workbook, sheet, importConfigs, IndexedColors.YELLOW.getIndex(), IndexedColors.RED.getIndex(), rowNumber++);
  771. // 字体内容格式
  772. Font font = workbook.createFont();
  773. font.setBold(false);// 设置为粗体
  774. font.setFontName("宋体");
  775. font.setFontHeightInPoints((short) 12);
  776. // 单元格样式
  777. CellStyle cellStyle = workbook.createCellStyle();
  778. cellStyle.setFont(font); // 将字体应用到样式
  779. cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  780. cellStyle.setAlignment(HorizontalAlignment.CENTER);
  781. // 设置边框样式为细线
  782. cellStyle.setBorderTop(BorderStyle.THIN);
  783. cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); // 设置顶部边框颜色
  784. cellStyle.setBorderBottom(BorderStyle.THIN);
  785. cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); // 设置底部边框颜色
  786. cellStyle.setBorderLeft(BorderStyle.THIN);
  787. cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); // 设置左边框颜色
  788. cellStyle.setBorderRight(BorderStyle.THIN);
  789. cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); // 设置右边框颜色
  790. // 记录写入
  791. List<String> claimVo;
  792. List<String> claimItemVo;
  793. List<String> claimItemIssueVo;
  794. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  795. for (ClaimRecordsExportQueryVo vo : dataList) {
  796. if (ObjectUtils.isNotEmpty(vo.getClaimType()) && ClaimTypeEnum.ClaimClass.getCode().equals(vo.getClaimType())) {
  797. vo.setReceiver(vo.getClassIdCn());
  798. } else {
  799. vo.setReceiver(vo.getApplicantUserIdCn());
  800. }
  801. // 1:未发放,2:部分发放,3:全部发放)
  802. if (vo.getStatus() == 2) {
  803. vo.setStatusStr("部分发放");
  804. } else if (vo.getStatus() == 3) {
  805. vo.setStatusStr("全部发放");
  806. } else {
  807. vo.setStatusStr("未发放");
  808. }
  809. Long claimId = vo.getId();
  810. // 填充统计信息
  811. if (MapUtils.isNotEmpty(statsMap) && statsMap.containsKey(claimId)) {
  812. WfTextbookClaimItem stat = statsMap.get(claimId);
  813. vo.setApplicantTatolNumber(stat.getApplicantNumber());
  814. vo.setIssueTatolNumber(stat.getIssueNumber());
  815. }
  816. // 申领总记录
  817. claimVo = new ArrayList<>();
  818. claimVo.add(vo.getBaseSemesterIdCn());
  819. claimVo.add(vo.getClaimTypeCn());
  820. claimVo.add(vo.getReceiver());
  821. if (StringUtils.isNotEmpty(vo.getClassIdCn())) {
  822. claimVo.add(vo.getClassIdCn());
  823. } else {
  824. claimVo.add("无");
  825. }
  826. claimVo.add(vo.getApplicantTatolNumber() + "");
  827. claimVo.add(vo.getStatusStr());
  828. claimVo.add(vo.getIssueTatolNumber() + "");
  829. // 填充子项及发放记录
  830. int mergeClaim = 0;
  831. if (MapUtils.isNotEmpty(itemMap) && CollectionUtils.isNotEmpty(itemMap.get(claimId))) {
  832. List<WfTextbookClaimItemVo> items = itemMap.get(claimId);
  833. for (WfTextbookClaimItemVo item : items) {
  834. mergeClaim++;
  835. claimItemVo = new ArrayList<>(claimVo);
  836. claimItemVo.add(item.getTextbookIdCN());
  837. claimItemVo.add(item.getIssn());
  838. claimItemVo.add(item.getApplicantNumber() + "");
  839. claimItemVo.add(item.getIssueNumber() + "");
  840. int mergeClaimItem = 0;
  841. if (recordMap.containsKey(item.getId())) {
  842. List<DistributeRecordVo> issues = recordMap.get(item.getId());
  843. for (DistributeRecordVo issue : issues) {
  844. mergeClaimItem++;
  845. claimItemIssueVo = new ArrayList<>(claimItemVo);
  846. LocalDateTime localDateTime = issue.getIssueDate().toInstant()
  847. .atZone(ZoneId.systemDefault())
  848. .toLocalDateTime();
  849. claimItemIssueVo.add(localDateTime.format(formatter));
  850. claimItemIssueVo.add(issue.getIssueUser());
  851. claimItemIssueVo.add(issue.getOrderNumber());
  852. claimItemIssueVo.add(issue.getIssueNumber() + "");
  853. Row dataRow = sheet.createRow(rowNumber++);
  854. for (int j = 0; j < claimItemIssueVo.size(); j++) {
  855. String content = claimItemIssueVo.get(j);
  856. Cell cell = dataRow.createCell(j);
  857. cell.setCellValue(content);
  858. cell.setCellStyle(cellStyle);
  859. }
  860. }
  861. // 合并申领项
  862. if (mergeClaimItem > 1) {
  863. for (int k = 7; k < 11; k++) {
  864. sheet.addMergedRegion(new CellRangeAddress(rowNumber - mergeClaimItem, rowNumber - 1, k, k));
  865. }
  866. }
  867. } else {
  868. Row dataRow = sheet.createRow(rowNumber++);
  869. for (int j = 0; j < claimItemVo.size(); j++) {
  870. String content = claimItemVo.get(j);
  871. Cell cell = dataRow.createCell(j);
  872. cell.setCellValue(content);
  873. cell.setCellStyle(cellStyle);
  874. }
  875. }
  876. }
  877. // 合并申领
  878. if (mergeClaim > 1) {
  879. for (int k = 0; k < 7; k++) {
  880. sheet.addMergedRegion(new CellRangeAddress(rowNumber - mergeClaim, rowNumber - 1, k, k));
  881. }
  882. }
  883. } else {
  884. Row dataRow = sheet.createRow(rowNumber++);
  885. for (int j = 0; j < claimVo.size(); j++) {
  886. String content = claimVo.get(j);
  887. Cell cell = dataRow.createCell(j);
  888. cell.setCellValue(content);
  889. cell.setCellStyle(cellStyle);
  890. }
  891. }
  892. }
  893. // 自动列宽
  894. for (int i = 0; i < importConfigs.size(); i++) {
  895. sheet.autoSizeColumn(i);
  896. }
  897. ByteArrayOutputStream bot = new ByteArrayOutputStream();
  898. workbook.write(bot);
  899. return bot;
  900. }
  901. }