LedgerStatisticsController.java 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. package com.xjrsoft.module.ledger.controller;
  2. import cn.dev33.satoken.annotation.SaCheckPermission;
  3. import cn.hutool.core.bean.BeanUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import com.alibaba.excel.EasyExcel;
  6. import com.alibaba.excel.support.ExcelTypeEnum;
  7. import com.baomidou.mybatisplus.core.metadata.IPage;
  8. import com.github.yulichang.wrapper.MPJLambdaWrapper;
  9. import com.xjrsoft.common.model.result.RT;
  10. import com.xjrsoft.common.mybatis.SqlRunnerAdapter;
  11. import com.xjrsoft.common.page.ConventPage;
  12. import com.xjrsoft.common.page.PageOutput;
  13. import com.xjrsoft.common.utils.VoToColumnUtil;
  14. import com.xjrsoft.module.ledger.dto.LedgerStatisticsPageDto;
  15. import com.xjrsoft.module.ledger.vo.LedgerStatisticsLeaveExcelVo;
  16. import com.xjrsoft.module.ledger.vo.LedgerStatisticsLeaveVo;
  17. import com.xjrsoft.module.ledger.vo.LedgerStatisticsListenExcelVo;
  18. import com.xjrsoft.module.ledger.vo.LedgerStatisticsListenVo;
  19. import com.xjrsoft.module.ledger.vo.LedgerStatisticsOvertimeExcelVo;
  20. import com.xjrsoft.module.ledger.vo.LedgerStatisticsOvertimeVo;
  21. import com.xjrsoft.module.organization.entity.Department;
  22. import com.xjrsoft.module.organization.entity.User;
  23. import com.xjrsoft.module.organization.entity.UserDeptRelation;
  24. import com.xjrsoft.module.organization.service.IUserDeptRelationService;
  25. import com.xjrsoft.module.organization.service.IUserService;
  26. import com.xjrsoft.module.organization.vo.UserPageVo;
  27. import com.xjrsoft.module.teacher.entity.BaseTeacher;
  28. import com.xjrsoft.module.teacher.entity.WfTeacherleave;
  29. import com.xjrsoft.module.teacher.service.IWfTeacherleaveService;
  30. import io.swagger.annotations.Api;
  31. import io.swagger.annotations.ApiOperation;
  32. import lombok.AllArgsConstructor;
  33. import org.springframework.http.ResponseEntity;
  34. import org.springframework.web.bind.annotation.GetMapping;
  35. import org.springframework.web.bind.annotation.PostMapping;
  36. import org.springframework.web.bind.annotation.RequestBody;
  37. import org.springframework.web.bind.annotation.RequestMapping;
  38. import org.springframework.web.bind.annotation.RestController;
  39. import javax.validation.Valid;
  40. import java.io.ByteArrayOutputStream;
  41. import java.text.DecimalFormat;
  42. import java.time.LocalDateTime;
  43. import java.time.format.DateTimeFormatter;
  44. import java.util.ArrayList;
  45. import java.util.List;
  46. import java.util.Map;
  47. import java.util.stream.Collectors;
  48. /**
  49. * @title: 台账统计
  50. * @Author dzx
  51. * @Date: 2024年11月29日
  52. * @Version 1.0
  53. */
  54. @RestController
  55. @RequestMapping("/ledger" + "/ledgerStatistics")
  56. @Api(value = "/ledger" + "/ledgerStatistics",tags = "台账统计代码")
  57. @AllArgsConstructor
  58. public class LedgerStatisticsController {
  59. private final IUserService userService;
  60. private final IWfTeacherleaveService teacherleaveService;
  61. private final IUserDeptRelationService deptRelationService;
  62. @GetMapping(value = "/teacher-leave-page")
  63. @ApiOperation(value="教师请假统计(分页)")
  64. @SaCheckPermission("ledgerstatistics:detail")
  65. public RT<PageOutput<LedgerStatisticsLeaveVo>> teacherLeavePage(@Valid LedgerStatisticsPageDto dto){
  66. List<Long> userIdList = new ArrayList<>();
  67. if(StrUtil.isNotEmpty(dto.getDeptName())){
  68. List<UserDeptRelation> userList = deptRelationService.list(
  69. new MPJLambdaWrapper<UserDeptRelation>()
  70. .select(UserDeptRelation::getId)
  71. .select(UserDeptRelation::getDeptId)
  72. .select(UserDeptRelation::getUserId)
  73. .innerJoin(Department.class, Department::getId, UserDeptRelation::getDeptId)
  74. .like(StrUtil.isNotEmpty(dto.getDeptName()), Department::getName, dto.getDeptName())
  75. );
  76. userIdList.addAll(userList.stream().map(UserDeptRelation::getUserId).collect(Collectors.toList()));
  77. }
  78. LocalDateTime startTime = null;
  79. LocalDateTime endTime = null;
  80. if(dto.getStartDate() != null && dto.getEndDate() != null){
  81. startTime = dto.getStartDate().atTime(0,0,0);
  82. endTime = dto.getEndDate().atTime(23,59,59);
  83. }
  84. Map<String, List<WfTeacherleave>> userLeaveMap = teacherleaveService.getUserLeaveList(startTime, endTime, userIdList);
  85. List<String> userIds = new ArrayList<>(userLeaveMap.keySet());
  86. if(userIds.isEmpty()){
  87. return RT.ok(new PageOutput<>());
  88. }
  89. IPage<LedgerStatisticsLeaveVo> userPage = userService.selectJoinListPage(ConventPage.getPage(dto), LedgerStatisticsLeaveVo.class,
  90. new MPJLambdaWrapper<User>()
  91. .disableSubLogicDel()
  92. .select(User::getId)
  93. .select(User.class, x -> VoToColumnUtil.fieldsToColumns(UserPageVo.class).contains(x.getProperty()))
  94. .select(" (SELECT GROUP_CONCAT(t1.name) FROM xjr_department t1" +
  95. " INNER JOIN xjr_user_dept_relation t2 ON t1.id = t2.dept_id" +
  96. " WHERE t1.delete_mark = 0 AND t2.user_id = t.id) as dept_name")
  97. .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, User::getId)
  98. .like(StrUtil.isNotEmpty(dto.getName()), User::getName, dto.getName())
  99. .like(StrUtil.isNotEmpty(dto.getUserName()), User::getUserName, dto.getUserName())
  100. .in(User::getId, userIds)
  101. .orderByAsc(User::getId)
  102. );
  103. for (LedgerStatisticsLeaveVo record : userPage.getRecords()) {
  104. List<WfTeacherleave> wfTeacherleaves = userLeaveMap.get(record.getId().toString());
  105. if(wfTeacherleaves == null || wfTeacherleaves.isEmpty()){
  106. continue;
  107. }
  108. double value = wfTeacherleaves.stream().mapToDouble(WfTeacherleave::getLeaveDays).sum();
  109. boolean isInteger = (value % 1) == 0;
  110. DecimalFormat df = new DecimalFormat(isInteger ? "0" : "#.##");
  111. String formattedValue = df.format(value);
  112. record.setLeaveDays(formattedValue);
  113. }
  114. PageOutput<LedgerStatisticsLeaveVo> pageOutput = ConventPage.getPageOutput(userPage, LedgerStatisticsLeaveVo.class);
  115. return RT.ok(pageOutput);
  116. }
  117. @PostMapping(value = "/teacher-leave-export-query")
  118. @ApiOperation(value="教师请假统计-导出")
  119. @SaCheckPermission("ledgerstatistics:detail")
  120. public ResponseEntity<byte[]> teacherLeaveExportQuery(@Valid @RequestBody LedgerStatisticsPageDto dto){
  121. List<Long> userIdList = new ArrayList<>();
  122. if(StrUtil.isNotEmpty(dto.getDeptName())){
  123. List<UserDeptRelation> userList = deptRelationService.list(
  124. new MPJLambdaWrapper<UserDeptRelation>()
  125. .select(UserDeptRelation::getId)
  126. .select(UserDeptRelation::getDeptId)
  127. .select(UserDeptRelation::getUserId)
  128. .innerJoin(Department.class, Department::getId, UserDeptRelation::getDeptId)
  129. .like(StrUtil.isNotEmpty(dto.getDeptName()), Department::getName, dto.getDeptName())
  130. );
  131. userIdList.addAll(userList.stream().map(UserDeptRelation::getUserId).collect(Collectors.toList()));
  132. }
  133. LocalDateTime startTime = null;
  134. LocalDateTime endTime = null;
  135. if(dto.getStartDate() != null && dto.getEndDate() != null){
  136. startTime = dto.getStartDate().atTime(0,0,0);
  137. endTime = dto.getEndDate().atTime(23,59,59);
  138. }
  139. Map<String, List<WfTeacherleave>> userLeaveMap = teacherleaveService.getUserLeaveList(startTime, endTime, userIdList);
  140. List<String> userIds = new ArrayList<>(userLeaveMap.keySet());
  141. if(userIds.isEmpty()){
  142. List<LedgerStatisticsLeaveExcelVo> list = new ArrayList<>();
  143. ByteArrayOutputStream bot = new ByteArrayOutputStream();
  144. EasyExcel.write(bot, LedgerStatisticsLeaveExcelVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(list);
  145. return RT.fileStream(bot.toByteArray(), "teacher-leave" + ExcelTypeEnum.XLSX.getValue());
  146. }
  147. List<LedgerStatisticsLeaveVo> list = userService.selectJoinList(LedgerStatisticsLeaveVo.class,
  148. new MPJLambdaWrapper<User>()
  149. .disableSubLogicDel()
  150. .select(User::getId)
  151. .select(User.class, x -> VoToColumnUtil.fieldsToColumns(UserPageVo.class).contains(x.getProperty()))
  152. .select(" (SELECT GROUP_CONCAT(t1.name) FROM xjr_department t1" +
  153. " INNER JOIN xjr_user_dept_relation t2 ON t1.id = t2.dept_id" +
  154. " WHERE t1.delete_mark = 0 AND t2.user_id = t.id) as dept_name")
  155. .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, User::getId)
  156. .like(StrUtil.isNotEmpty(dto.getName()), User::getName, dto.getName())
  157. .like(StrUtil.isNotEmpty(dto.getUserName()), User::getUserName, dto.getUserName())
  158. .in(User::getId, userIds)
  159. .orderByAsc(User::getId)
  160. );
  161. List<LedgerStatisticsLeaveExcelVo> dataList = new ArrayList<>();
  162. int sortCode = 1;
  163. for (LedgerStatisticsLeaveVo record : list) {
  164. List<WfTeacherleave> wfTeacherleaves = userLeaveMap.get(record.getId().toString());
  165. if(wfTeacherleaves == null || wfTeacherleaves.isEmpty()){
  166. continue;
  167. }
  168. double value = wfTeacherleaves.stream().mapToDouble(WfTeacherleave::getLeaveDays).sum();
  169. boolean isInteger = (value % 1) == 0;
  170. DecimalFormat df = new DecimalFormat(isInteger ? "0" : "#.##");
  171. String formattedValue = df.format(value);
  172. record.setLeaveDays(formattedValue);
  173. record.setSortCode(sortCode);
  174. LedgerStatisticsLeaveExcelVo bean = BeanUtil.toBean(record, LedgerStatisticsLeaveExcelVo.class);
  175. dataList.add(bean);
  176. sortCode ++;
  177. }
  178. ByteArrayOutputStream bot = new ByteArrayOutputStream();
  179. EasyExcel.write(bot, LedgerStatisticsLeaveExcelVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(dataList);
  180. return RT.fileStream(bot.toByteArray(), "teacher-leave" + ExcelTypeEnum.XLSX.getValue());
  181. }
  182. @GetMapping(value = "/teacher-overtime-page")
  183. @ApiOperation(value="教师加班统计(分页)")
  184. @SaCheckPermission("ledgerstatistics:detail")
  185. public RT<PageOutput<LedgerStatisticsOvertimeVo>> teacherOvertimePage(@Valid LedgerStatisticsPageDto dto){
  186. List<Long> userIdList = new ArrayList<>();
  187. if(StrUtil.isNotEmpty(dto.getDeptName())){
  188. List<UserDeptRelation> list = deptRelationService.list(
  189. new MPJLambdaWrapper<UserDeptRelation>()
  190. .select(UserDeptRelation::getId)
  191. .select(UserDeptRelation::getDeptId)
  192. .select(UserDeptRelation::getUserId)
  193. .innerJoin(Department.class, Department::getId, UserDeptRelation::getDeptId)
  194. .like(StrUtil.isNotEmpty(dto.getDeptName()), Department::getName, dto.getDeptName())
  195. );
  196. userIdList.addAll(list.stream().map(UserDeptRelation::getUserId).collect(Collectors.toList()));
  197. }
  198. DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  199. String sql = "SELECT t4.teacher_user_id,SUM(t.total_days) as total_days FROM wf_overtime t" +
  200. " LEFT JOIN xjr_user t1 ON t1.id = t.user_id" +
  201. " LEFT JOIN xjr_user t3 ON t3.id = t.leader_in_charge" +
  202. " LEFT JOIN xjr_workflow_form_relation t2 ON t.id = t2.form_key_value" +
  203. " LEFT JOIN wf_overtime_teacher t4 ON t.id = t4.wf_overtime_id" +
  204. " WHERE t2.current_state = 'COMPLETED'";
  205. if(dto.getStartDate() != null && dto.getEndDate() != null){
  206. String startTime = dto.getStartDate().atTime(0,0,0).format(dtf);
  207. String endTime = dto.getEndDate().atTime(23,59,59).format(dtf);
  208. sql += " AND (" +
  209. " (t.overtime_start_time BETWEEN '" + startTime + "' and '" + endTime + "')" +
  210. " OR (t.overtime_end_time BETWEEN '" + startTime + "' and '" + endTime + "')" +
  211. " OR (t.overtime_start_time > '" + startTime + "' and '" + endTime + "' > t.overtime_end_time)" +
  212. " OR ('" + startTime + "' > t.overtime_start_time and t.overtime_end_time > '" + endTime + "')" +
  213. ")";
  214. }
  215. if(!userIdList.isEmpty()){
  216. sql = " AND t.teacher_user_id in (" + userIdList.toString().replace("[", "").replace("]", "") + ")";
  217. }
  218. sql += " GROUP BY t4.teacher_user_id";
  219. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  220. Map<Long, String> userLeaveMap = list.stream().filter(x -> x.get("total_days") != null && x.get("teacher_user_id") != null).collect(
  221. Collectors.toMap(x -> Long.parseLong(x.get("teacher_user_id").toString()), x -> x.get("total_days").toString())
  222. );
  223. List<Long> userIds = new ArrayList<>(userLeaveMap.keySet());
  224. if(userIds.isEmpty()){
  225. return RT.ok(new PageOutput<>());
  226. }
  227. IPage<LedgerStatisticsOvertimeVo> userPage = userService.selectJoinListPage(ConventPage.getPage(dto), LedgerStatisticsOvertimeVo.class,
  228. new MPJLambdaWrapper<User>()
  229. .disableSubLogicDel()
  230. .select(User::getId)
  231. .select(User.class, x -> VoToColumnUtil.fieldsToColumns(UserPageVo.class).contains(x.getProperty()))
  232. .select(" (SELECT GROUP_CONCAT(t1.name) FROM xjr_department t1" +
  233. " INNER JOIN xjr_user_dept_relation t2 ON t1.id = t2.dept_id" +
  234. " WHERE t1.delete_mark = 0 AND t2.user_id = t.id) as dept_name")
  235. .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, User::getId)
  236. .like(StrUtil.isNotEmpty(dto.getName()), User::getName, dto.getName())
  237. .like(StrUtil.isNotEmpty(dto.getUserName()), User::getUserName, dto.getUserName())
  238. .in(User::getId, userIds)
  239. .orderByAsc(User::getId)
  240. );
  241. for (LedgerStatisticsOvertimeVo record : userPage.getRecords()) {
  242. if(!userLeaveMap.containsKey(record.getId())){
  243. continue;
  244. }
  245. double value = Double.parseDouble(userLeaveMap.get(record.getId()));
  246. boolean isInteger = (value % 1) == 0;
  247. DecimalFormat df = new DecimalFormat(isInteger ? "0" : "#.##");
  248. String formattedValue = df.format(value);
  249. record.setTotalDays(formattedValue);
  250. }
  251. PageOutput<LedgerStatisticsOvertimeVo> pageOutput = ConventPage.getPageOutput(userPage, LedgerStatisticsOvertimeVo.class);
  252. return RT.ok(pageOutput);
  253. }
  254. @PostMapping(value = "/teacher-overtime-export-query")
  255. @ApiOperation(value="教师加班统计-导出")
  256. @SaCheckPermission("ledgerstatistics:detail")
  257. public ResponseEntity<byte[]> teacherOvertimeExportQuery(@Valid @RequestBody LedgerStatisticsPageDto dto){
  258. List<Long> userIdList = new ArrayList<>();
  259. if(StrUtil.isNotEmpty(dto.getDeptName())){
  260. List<UserDeptRelation> list = deptRelationService.list(
  261. new MPJLambdaWrapper<UserDeptRelation>()
  262. .select(UserDeptRelation::getId)
  263. .select(UserDeptRelation::getDeptId)
  264. .select(UserDeptRelation::getUserId)
  265. .innerJoin(Department.class, Department::getId, UserDeptRelation::getDeptId)
  266. .like(StrUtil.isNotEmpty(dto.getDeptName()), Department::getName, dto.getDeptName())
  267. );
  268. userIdList.addAll(list.stream().map(UserDeptRelation::getUserId).collect(Collectors.toList()));
  269. }
  270. DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  271. String sql = "SELECT t4.teacher_user_id,SUM(t.total_days) as total_days FROM wf_overtime t" +
  272. " LEFT JOIN xjr_user t1 ON t1.id = t.user_id" +
  273. " LEFT JOIN xjr_user t3 ON t3.id = t.leader_in_charge" +
  274. " LEFT JOIN xjr_workflow_form_relation t2 ON t.id = t2.form_key_value" +
  275. " LEFT JOIN wf_overtime_teacher t4 ON t.id = t4.wf_overtime_id" +
  276. " WHERE t2.current_state = 'COMPLETED'";
  277. if(dto.getStartDate() != null && dto.getEndDate() != null){
  278. String startTime = dto.getStartDate().atTime(0,0,0).format(dtf);
  279. String endTime = dto.getEndDate().atTime(23,59,59).format(dtf);
  280. sql += " AND (" +
  281. " (t.overtime_start_time BETWEEN '" + startTime + "' and '" + endTime + "')" +
  282. " OR (t.overtime_end_time BETWEEN '" + startTime + "' and '" + endTime + "')" +
  283. " OR (t.overtime_start_time > '" + startTime + "' and '" + endTime + "' > t.overtime_end_time)" +
  284. " OR ('" + startTime + "' > t.overtime_start_time and t.overtime_end_time > '" + endTime + "')" +
  285. ")";
  286. }
  287. if(!userIdList.isEmpty()){
  288. sql = " AND t.teacher_user_id in (" + userIdList.toString().replace("[", "").replace("]", "") + ")";
  289. }
  290. sql += " GROUP BY t4.teacher_user_id";
  291. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  292. Map<Long, String> userLeaveMap = list.stream().filter(x -> x.get("total_days") != null && x.get("teacher_user_id") != null).collect(
  293. Collectors.toMap(x -> Long.parseLong(x.get("teacher_user_id").toString()), x -> x.get("total_days").toString())
  294. );
  295. List<Long> userIds = new ArrayList<>(userLeaveMap.keySet());
  296. if(userIds.isEmpty()){
  297. List<LedgerStatisticsOvertimeExcelVo> dataList = new ArrayList<>();
  298. ByteArrayOutputStream bot = new ByteArrayOutputStream();
  299. EasyExcel.write(bot, LedgerStatisticsOvertimeExcelVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(dataList);
  300. return RT.fileStream(bot.toByteArray(), "teacher-leave" + ExcelTypeEnum.XLSX.getValue());
  301. }
  302. List<LedgerStatisticsOvertimeVo> userPage = userService.selectJoinList(LedgerStatisticsOvertimeVo.class,
  303. new MPJLambdaWrapper<User>()
  304. .disableSubLogicDel()
  305. .select(User::getId)
  306. .select(User.class, x -> VoToColumnUtil.fieldsToColumns(UserPageVo.class).contains(x.getProperty()))
  307. .select(" (SELECT GROUP_CONCAT(t1.name) FROM xjr_department t1" +
  308. " INNER JOIN xjr_user_dept_relation t2 ON t1.id = t2.dept_id" +
  309. " WHERE t1.delete_mark = 0 AND t2.user_id = t.id) as dept_name")
  310. .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, User::getId)
  311. .like(StrUtil.isNotEmpty(dto.getName()), User::getName, dto.getName())
  312. .like(StrUtil.isNotEmpty(dto.getUserName()), User::getUserName, dto.getUserName())
  313. .in(User::getId, userIds)
  314. .orderByAsc(User::getId)
  315. );
  316. List<LedgerStatisticsOvertimeExcelVo> dataList = new ArrayList<>();
  317. int sortCode = 1;
  318. for (LedgerStatisticsOvertimeVo record : userPage) {
  319. if(!userLeaveMap.containsKey(record.getId())){
  320. continue;
  321. }
  322. double value = Double.parseDouble(userLeaveMap.get(record.getId()));
  323. boolean isInteger = (value % 1) == 0;
  324. DecimalFormat df = new DecimalFormat(isInteger ? "0" : "#.##");
  325. String formattedValue = df.format(value);
  326. record.setTotalDays(formattedValue);
  327. LedgerStatisticsOvertimeExcelVo bean = BeanUtil.toBean(record, LedgerStatisticsOvertimeExcelVo.class);
  328. bean.setSortCode(sortCode);
  329. dataList.add(bean);
  330. sortCode ++;
  331. }
  332. ByteArrayOutputStream bot = new ByteArrayOutputStream();
  333. EasyExcel.write(bot, LedgerStatisticsOvertimeExcelVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(dataList);
  334. return RT.fileStream(bot.toByteArray(), "teacher-overtime" + ExcelTypeEnum.XLSX.getValue());
  335. }
  336. @GetMapping(value = "/teacher-listen-page")
  337. @ApiOperation(value="教师听课统计(分页)")
  338. @SaCheckPermission("ledgerstatistics:detail")
  339. public RT<PageOutput<LedgerStatisticsListenVo>> teacherListenPage(@Valid LedgerStatisticsPageDto dto){
  340. List<Long> userIdList = new ArrayList<>();
  341. if(StrUtil.isNotEmpty(dto.getDeptName())){
  342. List<UserDeptRelation> userList = deptRelationService.list(
  343. new MPJLambdaWrapper<UserDeptRelation>()
  344. .select(UserDeptRelation::getId)
  345. .select(UserDeptRelation::getDeptId)
  346. .select(UserDeptRelation::getUserId)
  347. .innerJoin(Department.class, Department::getId, UserDeptRelation::getDeptId)
  348. .like(StrUtil.isNotEmpty(dto.getDeptName()), Department::getName, dto.getDeptName())
  349. );
  350. userIdList.addAll(userList.stream().map(UserDeptRelation::getUserId).collect(Collectors.toList()));
  351. }
  352. DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  353. String sql = "SELECT t1.user_id,count(t1.course_name) as course_count FROM wf_teacher_listen t1" +
  354. " LEFT JOIN xjr_workflow_form_relation t2 ON t1.id = t2.form_key_value" +
  355. " WHERE t2.current_state = 'COMPLETED'";
  356. if(dto.getStartDate() != null && dto.getEndDate() != null){
  357. String startTime = dto.getStartDate().format(dtf);
  358. String endTime = dto.getEndDate().format(dtf);
  359. sql += " AND t1.schedule_date BETWEEN '" + startTime + "' and '" + endTime + "'";
  360. }
  361. if(!userIdList.isEmpty()){
  362. sql = " AND t1.user_id in (" + userIdList.toString().replace("[", "").replace("]", "") + ")";
  363. }
  364. sql += " GROUP BY t1.user_id";
  365. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  366. Map<Long, String> userLeaveMap = list.stream().filter(x -> x.get("user_id") != null && x.get("course_count") != null).collect(
  367. Collectors.toMap(x -> Long.parseLong(x.get("user_id").toString()), x -> x.get("course_count").toString())
  368. );
  369. List<Long> userIds = new ArrayList<>(userLeaveMap.keySet());
  370. if(userIds.isEmpty()){
  371. return RT.ok(new PageOutput<>());
  372. }
  373. IPage<LedgerStatisticsListenVo> userPage = userService.selectJoinListPage(ConventPage.getPage(dto), LedgerStatisticsListenVo.class,
  374. new MPJLambdaWrapper<User>()
  375. .disableSubLogicDel()
  376. .select(User::getId)
  377. .select(User.class, x -> VoToColumnUtil.fieldsToColumns(UserPageVo.class).contains(x.getProperty()))
  378. .select(" (SELECT GROUP_CONCAT(t1.name) FROM xjr_department t1" +
  379. " INNER JOIN xjr_user_dept_relation t2 ON t1.id = t2.dept_id" +
  380. " WHERE t1.delete_mark = 0 AND t2.user_id = t.id) as dept_name")
  381. .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, User::getId)
  382. .like(StrUtil.isNotEmpty(dto.getName()), User::getName, dto.getName())
  383. .like(StrUtil.isNotEmpty(dto.getUserName()), User::getUserName, dto.getUserName())
  384. .in(User::getId, userIds)
  385. .orderByAsc(User::getId)
  386. );
  387. for (LedgerStatisticsListenVo record : userPage.getRecords()) {
  388. if(!userLeaveMap.containsKey(record.getId())){
  389. continue;
  390. }
  391. double value = Double.parseDouble(userLeaveMap.get(record.getId()));
  392. boolean isInteger = (value % 1) == 0;
  393. DecimalFormat df = new DecimalFormat(isInteger ? "0" : "#.##");
  394. String formattedValue = df.format(value);
  395. record.setCourseCount(formattedValue);
  396. }
  397. PageOutput<LedgerStatisticsListenVo> pageOutput = ConventPage.getPageOutput(userPage, LedgerStatisticsListenVo.class);
  398. return RT.ok(pageOutput);
  399. }
  400. @PostMapping(value = "/teacher-listen-export-query")
  401. @ApiOperation(value="教师听课统计-导出")
  402. @SaCheckPermission("ledgerstatistics:detail")
  403. public ResponseEntity<byte[]> teacherListenExportQuery(@Valid @RequestBody LedgerStatisticsPageDto dto){
  404. List<Long> userIdList = new ArrayList<>();
  405. if(StrUtil.isNotEmpty(dto.getDeptName())){
  406. List<UserDeptRelation> userList = deptRelationService.list(
  407. new MPJLambdaWrapper<UserDeptRelation>()
  408. .select(UserDeptRelation::getId)
  409. .select(UserDeptRelation::getDeptId)
  410. .select(UserDeptRelation::getUserId)
  411. .innerJoin(Department.class, Department::getId, UserDeptRelation::getDeptId)
  412. .like(StrUtil.isNotEmpty(dto.getDeptName()), Department::getName, dto.getDeptName())
  413. );
  414. userIdList.addAll(userList.stream().map(UserDeptRelation::getUserId).collect(Collectors.toList()));
  415. }
  416. DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  417. String sql = "SELECT t1.user_id,count(t1.course_name) as course_count FROM wf_teacher_listen t1" +
  418. " LEFT JOIN xjr_workflow_form_relation t2 ON t1.id = t2.form_key_value" +
  419. " WHERE t2.current_state = 'COMPLETED'";
  420. if(dto.getStartDate() != null && dto.getEndDate() != null){
  421. String startTime = dto.getStartDate().format(dtf);
  422. String endTime = dto.getEndDate().format(dtf);
  423. sql += " AND t1.schedule_date BETWEEN '" + startTime + "' and '" + endTime + "'";
  424. }
  425. if(!userIdList.isEmpty()){
  426. sql = " AND t1.user_id in (" + userIdList.toString().replace("[", "").replace("]", "") + ")";
  427. }
  428. sql += " GROUP BY t1.user_id";
  429. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  430. Map<Long, String> userLeaveMap = list.stream().filter(x -> x.get("user_id") != null && x.get("course_count") != null).collect(
  431. Collectors.toMap(x -> Long.parseLong(x.get("user_id").toString()), x -> x.get("course_count").toString())
  432. );
  433. List<Long> userIds = new ArrayList<>(userLeaveMap.keySet());
  434. if(userIds.isEmpty()){
  435. List<LedgerStatisticsListenExcelVo> dataList = new ArrayList<>();
  436. ByteArrayOutputStream bot = new ByteArrayOutputStream();
  437. EasyExcel.write(bot, LedgerStatisticsListenExcelVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(dataList);
  438. return RT.fileStream(bot.toByteArray(), "teacher-leave" + ExcelTypeEnum.XLSX.getValue());
  439. }
  440. List<LedgerStatisticsListenVo> userPage = userService.selectJoinList(LedgerStatisticsListenVo.class,
  441. new MPJLambdaWrapper<User>()
  442. .disableSubLogicDel()
  443. .select(User::getId)
  444. .select(User.class, x -> VoToColumnUtil.fieldsToColumns(UserPageVo.class).contains(x.getProperty()))
  445. .select(" (SELECT GROUP_CONCAT(t1.name) FROM xjr_department t1" +
  446. " INNER JOIN xjr_user_dept_relation t2 ON t1.id = t2.dept_id" +
  447. " WHERE t1.delete_mark = 0 AND t2.user_id = t.id) as dept_name")
  448. .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, User::getId)
  449. .like(StrUtil.isNotEmpty(dto.getName()), User::getName, dto.getName())
  450. .like(StrUtil.isNotEmpty(dto.getUserName()), User::getUserName, dto.getUserName())
  451. .in(User::getId, userIds)
  452. .orderByAsc(User::getId)
  453. );
  454. List<LedgerStatisticsListenExcelVo> dataList = new ArrayList<>();
  455. int sortCode = 1;
  456. for (LedgerStatisticsListenVo record : userPage) {
  457. if(!userLeaveMap.containsKey(record.getId())){
  458. continue;
  459. }
  460. double value = Double.parseDouble(userLeaveMap.get(record.getId()));
  461. boolean isInteger = (value % 1) == 0;
  462. DecimalFormat df = new DecimalFormat(isInteger ? "0" : "#.##");
  463. String formattedValue = df.format(value);
  464. record.setCourseCount(formattedValue);
  465. LedgerStatisticsListenExcelVo bean = BeanUtil.toBean(record, LedgerStatisticsListenExcelVo.class);
  466. bean.setSortCode(sortCode);
  467. dataList.add(bean);
  468. sortCode ++;
  469. }
  470. ByteArrayOutputStream bot = new ByteArrayOutputStream();
  471. EasyExcel.write(bot, LedgerStatisticsListenExcelVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(dataList);
  472. return RT.fileStream(bot.toByteArray(), "teacher-listen" + ExcelTypeEnum.XLSX.getValue());
  473. }
  474. }