DatadetailController.java 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. package com.xjrsoft.module.databoard.controller;
  2. import cn.dev33.satoken.annotation.SaCheckPermission;
  3. import cn.hutool.core.util.ObjectUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import com.github.yulichang.toolkit.MPJWrappers;
  6. import com.github.yulichang.wrapper.MPJLambdaWrapper;
  7. import com.xjrsoft.common.enums.GenderDictionaryEnum;
  8. import com.xjrsoft.common.enums.StudyStatusEnum;
  9. import com.xjrsoft.common.model.result.RT;
  10. import com.xjrsoft.common.mybatis.SqlRunnerAdapter;
  11. import com.xjrsoft.common.utils.SqlRunnerAdapterUtil;
  12. import com.xjrsoft.common.utils.VoToColumnUtil;
  13. import com.xjrsoft.module.databoard.dto.StatisticsDetailDto;
  14. import com.xjrsoft.module.databoard.vo.CourseCountListVo;
  15. import com.xjrsoft.module.databoard.vo.CourseStatisticsDetailVo;
  16. import com.xjrsoft.module.databoard.vo.DistributionVo;
  17. import com.xjrsoft.module.databoard.vo.DurationVo;
  18. import com.xjrsoft.module.databoard.vo.HealthItemCountVo;
  19. import com.xjrsoft.module.databoard.vo.HealthStatisticsDetailVo;
  20. import com.xjrsoft.module.databoard.vo.ItemCountAmountVo;
  21. import com.xjrsoft.module.databoard.vo.ItemCountRatioVo;
  22. import com.xjrsoft.module.databoard.vo.ItemCountVo;
  23. import com.xjrsoft.module.databoard.vo.ItemDoubleVo;
  24. import com.xjrsoft.module.databoard.vo.ProcessStatisticsDetailVo;
  25. import com.xjrsoft.module.databoard.vo.StudnetStatisticsDetailVo;
  26. import com.xjrsoft.module.databoard.vo.SubscriptionStatisticsDetailVo;
  27. import com.xjrsoft.module.databoard.vo.TeacherStatisticsDetailVo;
  28. import com.xjrsoft.module.oa.entity.WfSubscription;
  29. import com.xjrsoft.module.oa.service.IWfSubscriptionService;
  30. import com.xjrsoft.module.student.dto.BaseStudentUserPageDto;
  31. import com.xjrsoft.module.student.service.IBaseStudentService;
  32. import com.xjrsoft.module.student.vo.BaseStudentUserPageVo;
  33. import com.xjrsoft.module.student.vo.StudentReportRecordItemVo;
  34. import com.xjrsoft.module.system.entity.DictionaryDetail;
  35. import com.xjrsoft.module.teacher.entity.BaseTeacher;
  36. import com.xjrsoft.module.teacher.entity.XjrUser;
  37. import com.xjrsoft.module.teacher.service.ITeacherbaseManagerService;
  38. import com.xjrsoft.module.teacher.vo.XjrUserPageVo;
  39. import com.xjrsoft.module.workflow.constant.WorkflowConstant;
  40. import com.xjrsoft.module.workflow.entity.WorkflowExtra;
  41. import com.xjrsoft.module.workflow.entity.WorkflowFormRelation;
  42. import com.xjrsoft.module.workflow.entity.WorkflowSchema;
  43. import com.xjrsoft.module.workflow.service.IWorkflowExtraService;
  44. import com.xjrsoft.module.workflow.utils.WorkFlowUtil;
  45. import io.swagger.annotations.Api;
  46. import io.swagger.annotations.ApiOperation;
  47. import lombok.AllArgsConstructor;
  48. import org.camunda.bpm.engine.HistoryService;
  49. import org.camunda.bpm.engine.history.HistoricProcessInstance;
  50. import org.camunda.bpm.engine.history.HistoricProcessInstanceQuery;
  51. import org.springframework.web.bind.annotation.GetMapping;
  52. import org.springframework.web.bind.annotation.RequestMapping;
  53. import org.springframework.web.bind.annotation.RestController;
  54. import javax.validation.Valid;
  55. import java.math.BigDecimal;
  56. import java.math.RoundingMode;
  57. import java.text.ParseException;
  58. import java.text.SimpleDateFormat;
  59. import java.time.Duration;
  60. import java.time.LocalDate;
  61. import java.time.LocalDateTime;
  62. import java.time.Period;
  63. import java.time.format.DateTimeFormatter;
  64. import java.util.ArrayList;
  65. import java.util.Collections;
  66. import java.util.Comparator;
  67. import java.util.HashSet;
  68. import java.util.List;
  69. import java.util.Map;
  70. import java.util.Set;
  71. import java.util.stream.Collectors;
  72. /**
  73. * @title: 数据看板代码
  74. * @Date: 2024年8月2日
  75. * @Version 1.0
  76. */
  77. @RestController
  78. @RequestMapping("/datadetail" + "/datadetail")
  79. @Api(value = "/datadetail" + "/datadetail",tags = "数据看板详情代码")
  80. @AllArgsConstructor
  81. public class DatadetailController {
  82. private final HistoryService historyService;
  83. private final IWorkflowExtraService extraService;
  84. private final ITeacherbaseManagerService teacherService;
  85. private final IBaseStudentService studentService;
  86. private final IWfSubscriptionService subscriptionService;
  87. @GetMapping(value = "/process-statistics")
  88. @ApiOperation(value="流程统计详情")
  89. @SaCheckPermission("datadetail:detail")
  90. public RT<ProcessStatisticsDetailVo> processStatistics(@Valid StatisticsDetailDto dto){
  91. HistoricProcessInstanceQuery instanceQuery = historyService.createHistoricProcessInstanceQuery();
  92. if(dto.getUserId() != null){
  93. instanceQuery.variableValueEquals(WorkflowConstant.PROCESS_START_USER_ID_KEY, dto.getUserId());
  94. }
  95. LocalDateTime startTime = null;
  96. LocalDateTime endTime = null;
  97. if(dto.getStartDate() != null){
  98. startTime = dto.getStartDate().atStartOfDay();
  99. }
  100. if(dto.getEndDate() != null){
  101. endTime = dto.getEndDate().atStartOfDay().plusDays(1).plusNanos(-1);
  102. }
  103. if (!ObjectUtil.isNull(dto.getStartDate())) {
  104. instanceQuery.startedAfter(WorkFlowUtil.getStartOfDay(dto.getStartDate()));
  105. }
  106. if (!ObjectUtil.isNull(dto.getEndDate())) {
  107. instanceQuery.startedBefore(WorkFlowUtil.getEndOfDay(dto.getEndDate()));
  108. }
  109. List<WorkflowExtra> workflowExtras = extraService.list(
  110. new MPJLambdaWrapper<WorkflowExtra>()
  111. .between((startTime != null && endTime != null), WorkflowExtra::getLaunchTime, startTime, endTime)
  112. .select(WorkflowExtra::getId)
  113. .select(WorkflowExtra.class, x -> VoToColumnUtil.fieldsToColumns(WorkflowExtra.class).contains(x.getProperty()))
  114. .leftJoin(WorkflowSchema.class, WorkflowSchema::getId, WorkflowExtra::getSchemaId)
  115. .leftJoin(DictionaryDetail.class, DictionaryDetail::getId, WorkflowSchema::getCategory)
  116. );
  117. ProcessStatisticsDetailVo result = new ProcessStatisticsDetailVo();
  118. List<HistoricProcessInstance> list = instanceQuery.list();
  119. List<WorkflowExtra> allCountList = new ArrayList<>();
  120. for (HistoricProcessInstance historicProcessInstance : list) {
  121. workflowExtras.stream()
  122. .filter(e -> e.getProcessId().equals(historicProcessInstance.getId()))
  123. .max(Comparator.comparing(WorkflowExtra::getStartTime))
  124. .ifPresent(e -> {
  125. allCountList.add(e);
  126. });
  127. }
  128. result.setAllCount(Long.parseLong(allCountList.size() + ""));
  129. List<HistoricProcessInstance> finished = historyService.createHistoricProcessInstanceQuery().finished().list();
  130. List<WorkflowExtra> completeCountList = new ArrayList<>();
  131. for (HistoricProcessInstance historicProcessInstance : finished) {
  132. workflowExtras.stream()
  133. .filter(e -> e.getProcessId().equals(historicProcessInstance.getId()) && e.getEndTime() != null)
  134. .max(Comparator.comparing(WorkflowExtra::getStartTime))
  135. .ifPresent(e -> {
  136. completeCountList.add(e);
  137. });
  138. }
  139. result.setCompleteCount(Long.parseLong(completeCountList.size() + ""));
  140. List<HistoricProcessInstance> unfinished = historyService.createHistoricProcessInstanceQuery().unfinished().list();
  141. List<WorkflowExtra> uncompleteCountList = new ArrayList<>();
  142. for (HistoricProcessInstance historicProcessInstance : unfinished) {
  143. workflowExtras.stream()
  144. .filter(e -> e.getProcessId().equals(historicProcessInstance.getId()))
  145. .max(Comparator.comparing(WorkflowExtra::getStartTime))
  146. .ifPresent(e -> {
  147. uncompleteCountList.add(e);
  148. });
  149. }
  150. result.setUncompleteCount(Long.parseLong(uncompleteCountList.size() + ""));
  151. Map<String, Long> finishedMap = completeCountList.stream()
  152. .collect(Collectors.groupingBy(WorkflowExtra::getSchemaName, Collectors.counting()));
  153. Map<String, Long> unfinishedMap = uncompleteCountList.stream()
  154. .collect(Collectors.groupingBy(WorkflowExtra::getSchemaName, Collectors.counting()));
  155. Set<String> itemSet = new HashSet<>();
  156. itemSet.addAll(finishedMap.keySet());
  157. itemSet.addAll(unfinishedMap.keySet());
  158. List<DistributionVo> distributionList = new ArrayList();
  159. for (String item : itemSet) {
  160. Long uncompleteCount = unfinishedMap.get(item) == null?0L:unfinishedMap.get(item);
  161. Long completeCount = finishedMap.get(item) == null?0L:finishedMap.get(item);
  162. distributionList.add(
  163. new DistributionVo(){{
  164. setItem(item);
  165. setCompleteCount(completeCount);
  166. setUncompleteCount(uncompleteCount);
  167. }}
  168. );
  169. }
  170. result.setDistributionList(distributionList);
  171. List<DurationVo> durationList = new ArrayList<>();
  172. List<Long> secondList = new ArrayList<>();
  173. completeCountList.stream().filter(el -> el.getEndTime() != null && el.getStartTime() != null).forEach(el -> {
  174. Duration diff = Duration.between(el.getStartTime(), el.getEndTime());
  175. secondList.add(diff.getSeconds());
  176. });
  177. long zeroHour = secondList.stream().filter(x -> x < 3600L).count();
  178. long oneHour = secondList.stream().filter(x -> x < 14400L && x >= 3600L).count();
  179. long fourHour = secondList.stream().filter(x -> x < 28800L && x >= 14400L).count();
  180. long eightHour = secondList.stream().filter(x -> x >= 28800L).count();
  181. DurationVo zeroVo = new DurationVo();
  182. zeroVo.setDuration("0-1h");
  183. zeroVo.setCount(zeroHour);
  184. durationList.add(zeroVo);
  185. zeroVo = new DurationVo();
  186. zeroVo.setDuration("1-4h");
  187. zeroVo.setCount(oneHour);
  188. durationList.add(zeroVo);
  189. zeroVo = new DurationVo();
  190. zeroVo.setDuration("4-8h");
  191. zeroVo.setCount(fourHour);
  192. durationList.add(zeroVo);
  193. zeroVo = new DurationVo();
  194. zeroVo.setDuration("8h以上");
  195. zeroVo.setCount(eightHour);
  196. durationList.add(zeroVo);
  197. result.setDurationList(durationList);
  198. return RT.ok(result);
  199. }
  200. @GetMapping(value = "/health-statistics")
  201. @ApiOperation(value="学生健康统计")
  202. @SaCheckPermission("datadetail:detail")
  203. public RT<HealthStatisticsDetailVo> healthStatistics(@Valid StatisticsDetailDto dto){
  204. String sql = "SELECT t1.gender,COUNT(t1.*) AS a_count FROM student_infection t1" +
  205. " INNER JOIN xjr_workflow_form_relation t2 ON t1.id = t2.form_key_value" +
  206. " WHERE t2.current_state = 'COMPLETED' GROUP BY t1.gender";
  207. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  208. HealthStatisticsDetailVo result = new HealthStatisticsDetailVo();
  209. for (Map<String, Object> objectMap : list) {
  210. if(objectMap.get("gender") != null && GenderDictionaryEnum.FEMALE.getCode().equals(objectMap.get("gender").toString())){
  211. result.setInfectionFemaleCount(Integer.parseInt(objectMap.get("a_count").toString()));
  212. }if(objectMap.get("gender") != null && GenderDictionaryEnum.MALE.getCode().equals(objectMap.get("gender").toString())){
  213. result.setInfectionMaleCount(Integer.parseInt(objectMap.get("a_count").toString()));
  214. }
  215. }
  216. sql = "SELECT t1.gender,COUNT(t1.*) AS a_count FROM student_psychological t1" +
  217. " INNER JOIN xjr_workflow_form_relation t2 ON t1.id = t2.form_key_value" +
  218. " WHERE t2.current_state = 'COMPLETED' GROUP BY t1.gender";
  219. list = SqlRunnerAdapter.db().selectList(sql);
  220. for (Map<String, Object> objectMap : list) {
  221. if(objectMap.get("gender") != null && GenderDictionaryEnum.FEMALE.getCode().equals(objectMap.get("gender").toString())){
  222. result.setInfectionFemaleCount(Integer.parseInt(objectMap.get("a_count").toString()));
  223. }if(objectMap.get("gender") != null && GenderDictionaryEnum.MALE.getCode().equals(objectMap.get("gender").toString())){
  224. result.setPsychologicalMaleCount(Integer.parseInt(objectMap.get("a_count").toString()));
  225. }
  226. }
  227. List<HealthItemCountVo> gradeList = new ArrayList<>();
  228. sql = "SELECT t1.name as item,COUNT(t3.student_id) AS count FROM base_grade t1" +
  229. " INNER JOIN base_student_school_roll t2 ON t1.id= t2.grade_id" +
  230. " INNER JOIN student_infection t3 ON t3.student_id = t2.user_id" +
  231. " INNER JOIN xjr_workflow_form_relation t4 ON t3.id = t4.form_key_value" +
  232. " WHERE t4.current_state = 'COMPLETED' AND t1.delete_mark = 0" +
  233. " GROUP BY t1.name";
  234. list = SqlRunnerAdapter.db().selectList(sql);
  235. for (Map<String, Object> objectMap : list) {
  236. gradeList.add(
  237. new HealthItemCountVo(){{
  238. setItem(objectMap.get("item").toString());
  239. setInfectionCount(Long.parseLong(objectMap.get("count").toString()));
  240. }}
  241. );
  242. }
  243. sql = "SELECT t1.name as item,COUNT(t3.student_id) AS count FROM base_grade t1" +
  244. " INNER JOIN base_student_school_roll t2 ON t1.id= t2.grade_id" +
  245. " INNER JOIN student_psychological t3 ON t3.student_id = t2.user_id" +
  246. " INNER JOIN xjr_workflow_form_relation t4 ON t3.id = t4.form_key_value" +
  247. " WHERE t4.current_state = 'COMPLETED' AND t1.delete_mark = 0" +
  248. " GROUP BY t1.name";
  249. list = SqlRunnerAdapter.db().selectList(sql);
  250. for (Map<String, Object> objectMap : list) {
  251. for (HealthItemCountVo itemCountVo : gradeList) {
  252. if(objectMap.get("item").toString().equals(itemCountVo.getItem())){
  253. itemCountVo.setPsychologicalCount(Long.parseLong(objectMap.get("count").toString()));
  254. }
  255. }
  256. }
  257. result.setGradeList(gradeList);
  258. List<HealthItemCountVo> classList = new ArrayList<>();
  259. sql = "SELECT t1.name as item,COUNT(t3.student_id) AS count FROM base_class t1" +
  260. " INNER JOIN base_student_school_roll t2 ON t1.id= t2.grade_id" +
  261. " INNER JOIN student_infection t3 ON t3.student_id = t2.user_id" +
  262. " INNER JOIN xjr_workflow_form_relation t4 ON t3.id = t4.form_key_value" +
  263. " WHERE t4.current_state = 'COMPLETED' AND t1.delete_mark = 0" +
  264. " GROUP BY t1.name";
  265. list = SqlRunnerAdapter.db().selectList(sql);
  266. for (Map<String, Object> objectMap : list) {
  267. classList.add(
  268. new HealthItemCountVo(){{
  269. setItem(objectMap.get("item").toString());
  270. setInfectionCount(Long.parseLong(objectMap.get("count").toString()));
  271. }}
  272. );
  273. }
  274. sql = "SELECT t1.name as item,COUNT(t3.student_id) AS count FROM base_class t1" +
  275. " INNER JOIN base_student_school_roll t2 ON t1.id= t2.grade_id" +
  276. " INNER JOIN student_psychological t3 ON t3.student_id = t2.user_id" +
  277. " INNER JOIN xjr_workflow_form_relation t4 ON t3.id = t4.form_key_value" +
  278. " WHERE t4.current_state = 'COMPLETED' AND t1.delete_mark = 0" +
  279. " GROUP BY t1.name";
  280. list = SqlRunnerAdapter.db().selectList(sql);
  281. for (Map<String, Object> objectMap : list) {
  282. for (HealthItemCountVo itemCountVo : classList) {
  283. if(objectMap.get("item").toString().equals(itemCountVo.getItem())){
  284. itemCountVo.setPsychologicalCount(Long.parseLong(objectMap.get("count").toString()));
  285. }
  286. }
  287. }
  288. result.setClassList(classList);
  289. return RT.ok(result);
  290. }
  291. @GetMapping(value = "/person-statistics")
  292. @ApiOperation(value="教职工详情数据统计")
  293. @SaCheckPermission("datadetail:detail")
  294. public RT<TeacherStatisticsDetailVo> teahcerStatistics(@Valid StatisticsDetailDto dto) throws ParseException {
  295. String sql = "SELECT IFNULL(t2.name,'未填写') AS item ,ifnull(COUNT(*), 0) AS a_count FROM base_teacher_education t1" +
  296. " LEFT JOIN xjr_dictionary_detail t2 ON t1.education = t2.code" +
  297. " WHERE t1.delete_mark = 0 GROUP BY t2.name";
  298. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  299. TeacherStatisticsDetailVo result = new TeacherStatisticsDetailVo();
  300. List<ItemCountVo> educationList = new ArrayList<>();
  301. for (Map<String, Object> objectMap : list) {
  302. educationList.add(
  303. new ItemCountVo(){{
  304. setItem(objectMap.get("item").toString());
  305. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  306. }}
  307. );
  308. }
  309. result.setEducationList(educationList);
  310. sql = "SELECT IFNULL(t3.name,'未填写') AS item ,ifnull(COUNT(*), 0) AS a_count FROM xjr_user t1" +
  311. " INNER JOIN base_teacher t2 ON t1.id = t2.user_id" +
  312. " LEFT JOIN xjr_dictionary_detail t3 ON t1.gender = t3.code AND t3.item_id = 2023000000000000004" +
  313. " WHERE t1.delete_mark = 0 GROUP BY t3.name";
  314. list = SqlRunnerAdapter.db().selectList(sql);
  315. List<ItemCountVo> genderList = new ArrayList<>();
  316. for (Map<String, Object> objectMap : list) {
  317. genderList.add(
  318. new ItemCountVo(){{
  319. setItem(objectMap.get("item").toString());
  320. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  321. }}
  322. );
  323. }
  324. result.setGenderList(genderList);
  325. sql = "SELECT IFNULL(t3.name,'未填写') AS item ,ifnull(COUNT(*), 0) AS a_count FROM xjr_user t1" +
  326. " INNER JOIN base_teacher t2 ON t1.id = t2.user_id" +
  327. " LEFT JOIN xjr_dictionary_detail t3 ON t2.employ_way = t3.code AND t3.item_id = 2023000000000000016" +
  328. " WHERE t1.delete_mark = 0 GROUP BY t3.name";
  329. list = SqlRunnerAdapter.db().selectList(sql);
  330. List<ItemCountVo> employList = new ArrayList<>();
  331. for (Map<String, Object> objectMap : list) {
  332. employList.add(
  333. new ItemCountVo(){{
  334. setItem(objectMap.get("item").toString());
  335. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  336. }}
  337. );
  338. }
  339. result.setEmployList(employList);
  340. sql = "SELECT IFNULL(t4.name,'未填写') AS item ,ifnull(COUNT(*), 0) AS a_count FROM xjr_user t1" +
  341. " INNER JOIN base_teacher t2 ON t1.id = t2.user_id" +
  342. " LEFT JOIN xjr_user_dept_relation t3 ON t1.id = t3.user_id" +
  343. " LEFT JOIN xjr_department t4 ON t3.dept_id = t4.id" +
  344. " WHERE t1.delete_mark = 0 AND t4.is_major = 1 GROUP BY t4.name";
  345. list = SqlRunnerAdapter.db().selectList(sql);
  346. List<ItemCountVo> deptList = new ArrayList<>();
  347. for (Map<String, Object> objectMap : list) {
  348. deptList.add(
  349. new ItemCountVo(){{
  350. setItem(objectMap.get("item").toString());
  351. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  352. }}
  353. );
  354. }
  355. result.setDeptList(deptList);
  356. MPJLambdaWrapper<XjrUser> queryWrapper = MPJWrappers.<XjrUser>lambdaJoin()
  357. .disableSubLogicDel()
  358. .orderByDesc(XjrUser::getId)
  359. .select(XjrUser::getId)
  360. .select(XjrUser.class,x -> VoToColumnUtil.fieldsToColumns(XjrUserPageVo.class).contains(x.getProperty()))
  361. .innerJoin(BaseTeacher.class,BaseTeacher::getUserId,XjrUser::getId)
  362. .leftJoin(DictionaryDetail.class,DictionaryDetail::getCode,BaseTeacher::getJobState, ext->ext.selectAs(DictionaryDetail::getName, XjrUserPageVo::getJobState))
  363. .leftJoin(DictionaryDetail.class,DictionaryDetail::getCode,XjrUser::getCredentialType,ext->ext.selectAs(DictionaryDetail::getName, XjrUserPageVo::getCredentialType))
  364. .leftJoin(DictionaryDetail.class,DictionaryDetail::getCode,BaseTeacher::getEmployWay,ext->ext.selectAs(DictionaryDetail::getName, XjrUserPageVo::getEmployWay))
  365. .selectAsClass(BaseTeacher.class, XjrUserPageVo.class);
  366. List<XjrUserPageVo> teacherList = teacherService.selectJoinList(XjrUserPageVo.class, queryWrapper);
  367. List<String> idCardList = teacherList.stream().map(XjrUserPageVo::getCredentialNumber).collect(Collectors.toList());
  368. SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
  369. LocalDate currentDate = LocalDate.now();
  370. int age20 = 0;
  371. int age30 = 0;
  372. int age40 = 0;
  373. int age50 = 0;
  374. int age60 = 0;
  375. for (String idCard : idCardList) {
  376. if(StrUtil.isEmpty(idCard) || idCard.length() < 18){
  377. continue;
  378. }
  379. String birthdayStr = idCard.substring(6, 14);
  380. java.util.Date date = sdf.parse(birthdayStr);
  381. // 将Date对象转换为LocalDate对象
  382. LocalDate birthDate = date.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
  383. Period ageObj = Period.between(birthDate, currentDate);
  384. int age = ageObj.getYears();
  385. if(age >= 20 && age <= 29){
  386. age20 ++;
  387. }else if(age >= 30 && age <= 39){
  388. age30 ++;
  389. }else if(age >= 40 && age <= 49){
  390. age40 ++;
  391. }else if(age >= 50 && age <= 59){
  392. age50 ++;
  393. }else if(age >= 60){
  394. age60 ++;
  395. }
  396. }
  397. List<ItemCountVo> ageList = new ArrayList<>();
  398. ItemCountVo itemCountVo = new ItemCountVo();
  399. itemCountVo.setItem("20-29岁");
  400. itemCountVo.setCount(age20);
  401. ageList.add(itemCountVo);
  402. itemCountVo = new ItemCountVo();
  403. itemCountVo.setItem("30-39岁");
  404. itemCountVo.setCount(age30);
  405. ageList.add(itemCountVo);
  406. itemCountVo = new ItemCountVo();
  407. itemCountVo.setItem("40-49岁");
  408. itemCountVo.setCount(age40);
  409. ageList.add(itemCountVo);
  410. itemCountVo = new ItemCountVo();
  411. itemCountVo.setItem("50-59岁");
  412. itemCountVo.setCount(age50);
  413. ageList.add(itemCountVo);
  414. itemCountVo = new ItemCountVo();
  415. itemCountVo.setItem("60岁以上");
  416. itemCountVo.setCount(age60);
  417. ageList.add(itemCountVo);
  418. result.setAgeList(ageList);
  419. return RT.ok(result);
  420. }
  421. @GetMapping(value = "/student-statistics")
  422. @ApiOperation(value="学生详情数据统计")
  423. @SaCheckPermission("datadetail:detail")
  424. public RT<StudnetStatisticsDetailVo> studentStatistics(@Valid StatisticsDetailDto dto){
  425. StudnetStatisticsDetailVo result = new StudnetStatisticsDetailVo();
  426. String sql = "SELECT IFNULL(t3.name,'未填写') AS item ,COUNT(*) AS a_count FROM xjr_user t1" +
  427. " INNER JOIN base_student t2 ON t1.id = t2.user_id" +
  428. " INNER JOIN base_student_school_roll t4 ON t1.id = t4.user_id" +
  429. " LEFT JOIN xjr_dictionary_detail t3 ON t1.gender = t3.code" +
  430. " AND t3.item_id = 2023000000000000004 and t3.delete_mark = 0" +
  431. " WHERE t1.delete_mark = 0" +
  432. " and t4.archives_status = 'FB2901'" +
  433. " GROUP BY t3.name";
  434. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  435. List<ItemCountVo> genderList = new ArrayList<>();
  436. for (Map<String, Object> objectMap : list) {
  437. genderList.add(
  438. new ItemCountVo(){{
  439. setItem(objectMap.get("item").toString());
  440. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  441. }}
  442. );
  443. }
  444. result.setGenderList(genderList);
  445. sql = "SELECT IFNULL(t3.name,'未填写') AS item ,COUNT(*) AS a_count FROM xjr_user t1" +
  446. " INNER JOIN base_student_school_roll t2 ON t1.id = t2.user_id" +
  447. " LEFT JOIN xjr_dictionary_detail t3 ON t2.student_type = t3.code" +
  448. " AND t3.item_id = 2023000000000000028 and t3.delete_mark = 0" +
  449. " WHERE t1.delete_mark = 0" +
  450. " and t2.archives_status = 'FB2901'" +
  451. " GROUP BY t3.name";
  452. list = SqlRunnerAdapter.db().selectList(sql);
  453. List<ItemCountVo> studentTypeList = new ArrayList<>();
  454. for (Map<String, Object> objectMap : list) {
  455. studentTypeList.add(
  456. new ItemCountVo(){{
  457. setItem(objectMap.get("item").toString());
  458. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  459. }}
  460. );
  461. }
  462. result.setStudentTypeList(studentTypeList);
  463. List<BaseStudentUserPageVo> studentList = studentService.getStudentList(new BaseStudentUserPageDto());
  464. Set<String> studentStayMaleSet = studentList.stream()
  465. .filter(x -> (
  466. x.getGenderCn() != null
  467. && x.getGenderCn().equals(GenderDictionaryEnum.MALE.getCode())
  468. && x.getStduyStatusCn() != null
  469. && x.getStduyStatusCn().equals(StudyStatusEnum.InResidence.getCode())
  470. ))
  471. .map(BaseStudentUserPageVo::getId).collect(Collectors.toSet());
  472. result.setStudentStayMaleCount(studentStayMaleSet.size());
  473. Set<String> studentNotStayMaleSet = studentList.stream()
  474. .filter(x -> (
  475. x.getGenderCn() != null
  476. && x.getGenderCn().equals(GenderDictionaryEnum.MALE.getCode())
  477. && x.getStduyStatusCn() != null
  478. && x.getStduyStatusCn().equals(StudyStatusEnum.AttendDaySchool.getCode())
  479. ))
  480. .map(BaseStudentUserPageVo::getId).collect(Collectors.toSet());
  481. result.setStudentNotStayMaleCount(studentNotStayMaleSet.size());
  482. Set<String> studentStayFemaleSet = studentList.stream()
  483. .filter(x -> (
  484. x.getGenderCn() != null
  485. && x.getGenderCn().equals(GenderDictionaryEnum.FEMALE.getCode())
  486. && x.getStduyStatusCn() != null
  487. && x.getStduyStatusCn().equals(StudyStatusEnum.InResidence.getCode())
  488. ))
  489. .map(BaseStudentUserPageVo::getId).collect(Collectors.toSet());
  490. result.setStudentStayFemaleCount(studentStayFemaleSet.size());
  491. Set<String> studentNotStayFemaleSet = studentList.stream()
  492. .filter(x -> (
  493. x.getGenderCn() != null
  494. && x.getGenderCn().equals(GenderDictionaryEnum.FEMALE.getCode())
  495. && x.getStduyStatusCn() != null
  496. && x.getStduyStatusCn().equals(StudyStatusEnum.AttendDaySchool.getCode())
  497. ))
  498. .map(BaseStudentUserPageVo::getId).collect(Collectors.toSet());
  499. result.setStudentNotStayFemaleCount(studentNotStayFemaleSet.size());
  500. sql = "SELECT name AS item,(" +
  501. " SELECT COUNT(*) FROM xjr_user t1" +
  502. " INNER JOIN base_student_school_roll t2 ON t1.id = t2.user_id" +
  503. " WHERE t1.delete_mark = 0 AND t2.grade_id = base_grade.id" +
  504. " and t2.archives_status = 'FB2901') AS a_count FROM base_grade" +
  505. " WHERE delete_mark = 0 AND status = 1";
  506. if(dto.getGradeId() != null){
  507. sql += " id = " + dto.getGradeId();
  508. }
  509. sql += " ORDER BY name DESC LIMIT 4";
  510. list = SqlRunnerAdapter.db().selectList(sql);
  511. Collections.reverse(list);
  512. List<ItemCountVo> gradeList = new ArrayList<>();
  513. for (Map<String, Object> objectMap : list) {
  514. int aCount = Integer.parseInt(objectMap.get("a_count").toString());
  515. if(aCount == 0){
  516. continue;
  517. }
  518. gradeList.add(
  519. new ItemCountVo(){{
  520. setItem(objectMap.get("item").toString());
  521. setCount(aCount);
  522. }}
  523. );
  524. }
  525. result.setGradeList(gradeList);
  526. sql = "SELECT NAME AS item,(\n" +
  527. "SELECT COUNT(*) FROM xjr_user t1\n" +
  528. "INNER JOIN base_student_school_roll t2 ON t1.id = t2.user_id\n" +
  529. "INNER JOIN base_class t3 ON t2.class_id = t3.id\n" +
  530. "WHERE t1.delete_mark = 0 AND t3.org_id = xjr_department.id\n" +
  531. "AND t2.archives_status = 'FB2901' AND t1.gender = 'SB10001') AS a_count,\n" +
  532. "(\n" +
  533. "SELECT COUNT(*) FROM xjr_user t1\n" +
  534. "INNER JOIN base_student_school_roll t2 ON t1.id = t2.user_id\n" +
  535. "INNER JOIN base_class t3 ON t2.class_id = t3.id\n" +
  536. "WHERE t1.delete_mark = 0 AND t3.org_id = xjr_department.id\n" +
  537. "AND t2.archives_status = 'FB2901' AND t1.gender = 'SB10002') AS b_count FROM xjr_department\n" +
  538. "WHERE delete_mark = 0 AND is_major = 1 ORDER BY NAME DESC";
  539. list = SqlRunnerAdapter.db().selectList(sql);
  540. Collections.reverse(list);
  541. List<StudentReportRecordItemVo> deptList = new ArrayList<>();
  542. for (Map<String, Object> objectMap : list) {
  543. deptList.add(
  544. new StudentReportRecordItemVo(){{
  545. setItem(objectMap.get("item").toString());
  546. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  547. setCount2(Integer.parseInt(objectMap.get("b_count").toString()));
  548. }}
  549. );
  550. }
  551. result.setDeptList(deptList);
  552. return RT.ok(result);
  553. }
  554. @GetMapping(value = "/subscription-statistics")
  555. @ApiOperation(value="物品申购详情数据统计")
  556. @SaCheckPermission("datadetail:detail")
  557. public RT<SubscriptionStatisticsDetailVo> subscriptionStatistics(@Valid StatisticsDetailDto dto) {
  558. SubscriptionStatisticsDetailVo result = new SubscriptionStatisticsDetailVo();
  559. LocalDateTime startTime = null;
  560. LocalDateTime endTime = null;
  561. if(dto.getStartDate() != null){
  562. startTime = dto.getStartDate().atStartOfDay();
  563. }
  564. if(dto.getEndDate() != null){
  565. endTime = dto.getEndDate().atStartOfDay().plusDays(1).plusNanos(-1);
  566. }
  567. List<WfSubscription> list = subscriptionService.list(
  568. new MPJLambdaWrapper<WfSubscription>()
  569. .select(WfSubscription::getId)
  570. .select(WfSubscription.class, x -> VoToColumnUtil.fieldsToColumns(WfSubscription.class).contains(x.getProperty()))
  571. .innerJoin(WorkflowFormRelation.class, WorkflowFormRelation::getFormKeyValue, WfSubscription::getId)
  572. .eq(WorkflowFormRelation::getCurrentState, HistoricProcessInstance.STATE_COMPLETED)
  573. .between((startTime != null && endTime != null), WfSubscription::getShenQingRiQi4752, startTime, endTime)
  574. );
  575. result.setAllCount(list.size());
  576. double totalAmount = list.stream().filter(x -> x.getTotalAmount() != null && x.getStatus() == 1).mapToDouble(WfSubscription::getTotalAmount).sum();
  577. result.setTotalAmount(totalAmount);
  578. int adoptCount = list.stream().filter(x -> x.getStatus() == 1).collect(Collectors.toList()).size();
  579. result.setAdoptCount(adoptCount);
  580. int pendingCount = list.stream().filter(x -> x.getStatus() == null || x.getStatus() == 0).collect(Collectors.toList()).size();
  581. result.setPendingCount(pendingCount);
  582. String sql = "SELECT IFNULL(t3.name, '未填写') AS item,COUNT(t1.id) AS a_count,SUM(t1.estimated_unit_price * t1.amount) as a_sum FROM wf_subscription_list t1" +
  583. " INNER JOIN wf_subscription t2 ON t1.parent_id = t2.id" +
  584. " INNER JOIN xjr_workflow_form_relation t4 ON t1.id = t4.form_key_value" +
  585. " LEFT JOIN xjr_dictionary_detail t3 ON t1.item_type = t3.code" +
  586. " AND t3.item_id = 1752140413593518081" +
  587. " WHERE t4.current_state = 'COMPLETED'";
  588. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  589. if(startTime != null && endTime != null){
  590. sql += " and t2.shen_qing_ri_qi4752 between '" + startTime.format(formatter) + "' and '" + endTime.format(formatter) + "'";
  591. }
  592. sql += " GROUP BY t3.name";
  593. List<Map<String, Object>> datalist = SqlRunnerAdapter.db().selectList(sql);
  594. List<ItemCountVo> categoryCountList = new ArrayList<>();
  595. List<ItemDoubleVo> categoryAmountList = new ArrayList<>();
  596. for (Map<String, Object> objectMap : datalist) {
  597. categoryCountList.add(
  598. new ItemCountVo(){{
  599. setItem(objectMap.get("item").toString());
  600. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  601. }}
  602. );
  603. categoryAmountList.add(
  604. new ItemDoubleVo(){{
  605. setItem(objectMap.get("item").toString());
  606. setAmount(Double.parseDouble(objectMap.get("a_sum").toString()));
  607. }}
  608. );
  609. }
  610. result.setCategoryCountList(categoryCountList);
  611. result.setCategoryAmountList(categoryAmountList);
  612. sql = "SELECT IFNULL(t3.name, '未填写') AS item,COUNT(t1.id) AS a_count,SUM(t1.estimated_unit_price * t1.amount) as a_sum FROM wf_subscription_list t1" +
  613. " INNER JOIN wf_subscription t2 ON t1.parent_id = t2.id" +
  614. " INNER JOIN xjr_workflow_form_relation t4 ON t1.id = t4.form_key_value" +
  615. " LEFT JOIN xjr_department t3 ON t2.application_department = t3.id" +
  616. " WHERE t4.current_state = 'COMPLETED'";
  617. if(startTime != null && endTime != null){
  618. sql += " and t2.shen_qing_ri_qi4752 between '" + startTime.format(formatter) + "' and '" + endTime.format(formatter) + "'";
  619. }
  620. sql += " GROUP BY t3.name";
  621. datalist = SqlRunnerAdapter.db().selectList(sql);
  622. List<ItemCountAmountVo> deptList = new ArrayList<>();
  623. for (Map<String, Object> objectMap : datalist) {
  624. deptList.add(
  625. new ItemCountAmountVo(){{
  626. setItem(objectMap.get("item").toString());
  627. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  628. setAmount(Double.parseDouble(objectMap.get("a_sum").toString()));
  629. }}
  630. );
  631. }
  632. result.setDeptList(deptList);
  633. return RT.ok(result);
  634. }
  635. @GetMapping(value = "/course-statistics")
  636. @ApiOperation(value="课表详情数据统计")
  637. @SaCheckPermission("datadetail:detail")
  638. public RT<CourseStatisticsDetailVo> courseStatistics(@Valid StatisticsDetailDto dto) {
  639. CourseStatisticsDetailVo result = new CourseStatisticsDetailVo();
  640. String sql = "SELECT t1.id, t1.name,t4.name AS dept_name," +
  641. " (SELECT GROUP_CONCAT(DISTINCT(course_name)) FROM course_table WHERE teacher_id like concat('%', t1.id,'%') ) AS course_names," +
  642. " (SELECT COUNT(*) FROM course_table WHERE teacher_id like concat('%', t1.id,'%')) AS course_count FROM xjr_user t1" +
  643. " INNER JOIN base_teacher t2 ON t1.id = t2.user_id" +
  644. " INNER JOIN xjr_user_dept_relation t3 ON t1.id = t3.user_id" +
  645. " INNER JOIN xjr_department t4 ON t3.dept_id = t4.id" +
  646. " WHERE t1.delete_mark = 0 AND t4.is_major = 1" +
  647. " ORDER BY course_count DESC LIMIT 5";
  648. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  649. List<CourseCountListVo> courseCountList = new ArrayList<>();
  650. for (Map<String, Object> objectMap : list) {
  651. CourseCountListVo listVo = SqlRunnerAdapterUtil.convertMapToEntity(objectMap, CourseCountListVo.class);
  652. courseCountList.add(listVo);
  653. }
  654. result.setCourseCountList(courseCountList);
  655. sql = "SELECT count(*) FROM course_table t1" +
  656. " INNER JOIN base_teacher t2 ON t1.teacher_id like concat('%', t2.user_id,'%')" +
  657. " INNER JOIN xjr_user_dept_relation t3 ON t2.user_id = t3.user_id" +
  658. " INNER JOIN xjr_department t4 ON t4.id = t3.dept_id" +
  659. " WHERE t4.delete_mark = 0 AND t2.delete_mark = 0" +
  660. " AND t4.is_major = 1";
  661. long allCourseCount = SqlRunnerAdapter.db().selectCount(sql);
  662. sql = "SELECT name,(" +
  663. " SELECT COUNT(*) FROM course_table t1" +
  664. " INNER JOIN base_teacher t2 ON t1.teacher_id like concat('%', t2.user_id,'%')" +
  665. " INNER JOIN xjr_user_dept_relation t3 ON t2.user_id = t3.user_id" +
  666. " WHERE t3.dept_id = xjr_department.id" +
  667. " ) AS course_count FROM xjr_department WHERE is_major = 1";
  668. list = SqlRunnerAdapter.db().selectList(sql);
  669. List<ItemCountRatioVo> deptCourseList = new ArrayList<>();
  670. for (Map<String, Object> objectMap : list) {
  671. int courseCount = Integer.parseInt(objectMap.get("course_count").toString());
  672. //计算出勤率
  673. BigDecimal divide = BigDecimal.valueOf(courseCount).divide(BigDecimal.valueOf(allCourseCount), 4, RoundingMode.HALF_UP);
  674. deptCourseList.add(
  675. new ItemCountRatioVo() {{
  676. setItem(objectMap.get("name").toString());
  677. setCount(courseCount);
  678. setRatio(divide.doubleValue());
  679. }}
  680. );
  681. }
  682. result.setDeptCourseList(deptCourseList);
  683. return RT.ok(result);
  684. }
  685. }