DatadetailController.java 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  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.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  6. import com.github.yulichang.toolkit.MPJWrappers;
  7. import com.github.yulichang.wrapper.MPJLambdaWrapper;
  8. import com.xjrsoft.common.annotation.XjrLog;
  9. import com.xjrsoft.common.enums.DeleteMark;
  10. import com.xjrsoft.common.enums.GenderDictionaryEnum;
  11. import com.xjrsoft.common.enums.StudyStatusEnum;
  12. import com.xjrsoft.common.model.result.RT;
  13. import com.xjrsoft.common.mybatis.SqlRunnerAdapter;
  14. import com.xjrsoft.common.utils.SqlRunnerAdapterUtil;
  15. import com.xjrsoft.common.utils.VoToColumnUtil;
  16. import com.xjrsoft.module.base.entity.BaseSemester;
  17. import com.xjrsoft.module.base.mapper.BaseSemesterMapper;
  18. import com.xjrsoft.module.databoard.dto.StatisticsDetailDto;
  19. import com.xjrsoft.module.databoard.dto.TeacherChangeStatisticsDetailDto;
  20. import com.xjrsoft.module.databoard.vo.CourseCountListVo;
  21. import com.xjrsoft.module.databoard.vo.CourseStatisticsDetailVo;
  22. import com.xjrsoft.module.databoard.vo.DistributionVo;
  23. import com.xjrsoft.module.databoard.vo.DurationVo;
  24. import com.xjrsoft.module.databoard.vo.HealthItemCountVo;
  25. import com.xjrsoft.module.databoard.vo.HealthStatisticsDetailVo;
  26. import com.xjrsoft.module.databoard.vo.ItemCount2Vo;
  27. import com.xjrsoft.module.databoard.vo.ItemCountAmountVo;
  28. import com.xjrsoft.module.databoard.vo.ItemCountRatioVo;
  29. import com.xjrsoft.module.databoard.vo.ItemCountVo;
  30. import com.xjrsoft.module.databoard.vo.ItemDoubleVo;
  31. import com.xjrsoft.module.databoard.vo.ProcessStatisticsDetailVo;
  32. import com.xjrsoft.module.databoard.vo.RoomStatisticsDetailVo;
  33. import com.xjrsoft.module.databoard.vo.StudnetStatisticsDetailVo;
  34. import com.xjrsoft.module.databoard.vo.SubscriptionStatisticsDetailVo;
  35. import com.xjrsoft.module.databoard.vo.TeacherChangeStatisticsDetailVo;
  36. import com.xjrsoft.module.databoard.vo.TeacherStatisticsDetailVo;
  37. import com.xjrsoft.module.oa.entity.WfSubscription;
  38. import com.xjrsoft.module.oa.service.IWfSubscriptionService;
  39. import com.xjrsoft.module.student.dto.BaseStudentUserPageDto;
  40. import com.xjrsoft.module.student.service.IBaseStudentService;
  41. import com.xjrsoft.module.student.vo.BaseStudentUserPageVo;
  42. import com.xjrsoft.module.student.vo.StudentReportRecordItemVo;
  43. import com.xjrsoft.module.system.entity.DictionaryDetail;
  44. import com.xjrsoft.module.teacher.entity.BaseTeacher;
  45. import com.xjrsoft.module.teacher.entity.XjrUser;
  46. import com.xjrsoft.module.teacher.service.IBaseTeacherService;
  47. import com.xjrsoft.module.teacher.service.ITeacherbaseManagerService;
  48. import com.xjrsoft.module.teacher.vo.XjrUserPageVo;
  49. import com.xjrsoft.module.workflow.entity.WorkflowFormRelation;
  50. import io.swagger.annotations.Api;
  51. import io.swagger.annotations.ApiOperation;
  52. import lombok.AllArgsConstructor;
  53. import org.apache.commons.collections.CollectionUtils;
  54. import org.apache.commons.lang3.ObjectUtils;
  55. import org.apache.commons.lang3.StringUtils;
  56. import org.camunda.bpm.engine.history.HistoricProcessInstance;
  57. import org.springframework.web.bind.annotation.GetMapping;
  58. import org.springframework.web.bind.annotation.RequestMapping;
  59. import org.springframework.web.bind.annotation.RestController;
  60. import javax.validation.Valid;
  61. import java.math.BigDecimal;
  62. import java.math.RoundingMode;
  63. import java.text.ParseException;
  64. import java.text.SimpleDateFormat;
  65. import java.time.Duration;
  66. import java.time.LocalDate;
  67. import java.time.LocalDateTime;
  68. import java.time.Period;
  69. import java.time.ZoneId;
  70. import java.time.format.DateTimeFormatter;
  71. import java.time.temporal.TemporalAdjusters;
  72. import java.util.ArrayList;
  73. import java.util.Collections;
  74. import java.util.Comparator;
  75. import java.util.LinkedHashMap;
  76. import java.util.List;
  77. import java.util.Map;
  78. import java.util.Set;
  79. import java.util.stream.Collectors;
  80. /**
  81. * @title: 数据看板代码
  82. * @Date: 2024年8月2日
  83. * @Version 1.0
  84. */
  85. @RestController
  86. @RequestMapping("/datadetail" + "/datadetail")
  87. @Api(value = "/datadetail" + "/datadetail", tags = "数据看板详情代码")
  88. @AllArgsConstructor
  89. public class DatadetailController {
  90. private final ITeacherbaseManagerService teacherService;
  91. private final IBaseTeacherService baseTeacherService;
  92. private final IBaseStudentService studentService;
  93. private final IWfSubscriptionService subscriptionService;
  94. private final BaseSemesterMapper baseSemesterMapper;
  95. @GetMapping(value = "/process-statistics")
  96. @ApiOperation(value = "流程统计详情")
  97. @SaCheckPermission("datadetail:detail")
  98. @XjrLog(value = "流程统计详情", saveResponseData = true)
  99. public RT<ProcessStatisticsDetailVo> processStatistics(@Valid StatisticsDetailDto dto) {
  100. ProcessStatisticsDetailVo result = new ProcessStatisticsDetailVo();
  101. String sql = "SELECT DISTINCT t1.id,t2.schema_name,t1.start_time,t1.end_time,t1.current_state FROM xjr_workflow_form_relation t1" +
  102. " INNER JOIN xjr_workflow_extra t2 ON t1.process_id = t2.process_id" +
  103. " WHERE 1 = 1";
  104. if (dto.getStartDate() != null && dto.getEndDate() != null) {
  105. sql += " and DATE_FORMAT(t1.start_time, '%Y-%m-%d') BETWEEN '" + dto.getStartDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "'"
  106. + " and '" + dto.getEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "'";
  107. }
  108. List<Map<String, Object>> dataList = SqlRunnerAdapter.db().selectList(sql);
  109. result.setAllCount(dataList.stream().count());
  110. Long uncompleteCount = 0L;
  111. Long completeCount = 0L;
  112. for (Map<String, Object> objectMap : dataList) {
  113. String currentState = objectMap.get("current_state").toString();
  114. if(HistoricProcessInstance.STATE_ACTIVE.equals(currentState)){
  115. uncompleteCount ++;
  116. }else{
  117. completeCount ++;
  118. }
  119. }
  120. result.setCompleteCount(completeCount);
  121. result.setUncompleteCount(uncompleteCount);
  122. Set<String> itemSet = dataList.stream().map(x -> x.get("schema_name").toString()).collect(Collectors.toSet());
  123. Map<String, Long> finishedMap = dataList.stream()
  124. .filter(x -> !HistoricProcessInstance.STATE_ACTIVE.equals(x.get("current_state").toString()))
  125. .collect(Collectors.groupingBy(x -> x.get("schema_name").toString(), Collectors.counting()));
  126. Map<String, Long> unfinishedMap = dataList.stream()
  127. .filter(x -> HistoricProcessInstance.STATE_ACTIVE.equals(x.get("current_state").toString()))
  128. .collect(Collectors.groupingBy(x -> x.get("schema_name").toString(), Collectors.counting()));
  129. List<DistributionVo> distributionList = new ArrayList<>();
  130. for (String item : itemSet) {
  131. Long unfinishedCount = unfinishedMap.get(item) == null ? 0L : unfinishedMap.get(item);
  132. Long finishedCount = finishedMap.get(item) == null ? 0L : finishedMap.get(item);
  133. distributionList.add(
  134. new DistributionVo() {{
  135. setItem(item);
  136. setCompleteCount(finishedCount);
  137. setUncompleteCount(unfinishedCount);
  138. setAllCount(unfinishedCount + finishedCount);
  139. }}
  140. );
  141. }
  142. distributionList.sort(Comparator.comparingLong(DistributionVo::getAllCount).reversed());
  143. result.setDistributionList(distributionList);
  144. List<DurationVo> durationList = new ArrayList<>();
  145. List<Long> secondList = new ArrayList<>();
  146. List<Map<String, Object>> completeCountList = dataList.stream()
  147. .filter(x -> HistoricProcessInstance.STATE_COMPLETED.equals(x.get("current_state").toString()))
  148. .collect(Collectors.toList());
  149. completeCountList.stream().forEach(el -> {
  150. Duration diff = Duration.between((LocalDateTime)el.get("start_time"), (LocalDateTime)el.get("end_time"));
  151. secondList.add(diff.getSeconds());
  152. });
  153. long zeroHour = secondList.stream().filter(x -> x < 3600L).count();
  154. long oneHour = secondList.stream().filter(x -> x < 14400L && x >= 3600L).count();
  155. long fourHour = secondList.stream().filter(x -> x < 28800L && x >= 14400L).count();
  156. long eightHour = secondList.stream().filter(x -> x >= 28800L).count();
  157. DurationVo zeroVo = new DurationVo();
  158. zeroVo.setDuration("0-1h");
  159. zeroVo.setCount(zeroHour);
  160. durationList.add(zeroVo);
  161. zeroVo = new DurationVo();
  162. zeroVo.setDuration("1-4h");
  163. zeroVo.setCount(oneHour);
  164. durationList.add(zeroVo);
  165. zeroVo = new DurationVo();
  166. zeroVo.setDuration("4-8h");
  167. zeroVo.setCount(fourHour);
  168. durationList.add(zeroVo);
  169. zeroVo = new DurationVo();
  170. zeroVo.setDuration("8h以上");
  171. zeroVo.setCount(eightHour);
  172. durationList.add(zeroVo);
  173. result.setDurationList(durationList);
  174. return RT.ok(result);
  175. }
  176. @GetMapping(value = "/health-statistics")
  177. @ApiOperation(value = "学生健康统计")
  178. @SaCheckPermission("datadetail:detail")
  179. @XjrLog(value = "学生健康统计", saveResponseData = true)
  180. public RT<HealthStatisticsDetailVo> healthStatistics(@Valid StatisticsDetailDto dto) {
  181. String sql = "SELECT t1.gender,COUNT(t1.*) AS a_count FROM student_infection t1" +
  182. " INNER JOIN xjr_workflow_form_relation t2 ON t1.id = t2.form_key_value" +
  183. " WHERE t2.current_state = 'COMPLETED' GROUP BY t1.gender";
  184. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  185. HealthStatisticsDetailVo result = new HealthStatisticsDetailVo();
  186. for (Map<String, Object> objectMap : list) {
  187. if (objectMap.get("gender") != null && GenderDictionaryEnum.FEMALE.getCode().equals(objectMap.get("gender").toString())) {
  188. result.setInfectionFemaleCount(Integer.parseInt(objectMap.get("a_count").toString()));
  189. }
  190. if (objectMap.get("gender") != null && GenderDictionaryEnum.MALE.getCode().equals(objectMap.get("gender").toString())) {
  191. result.setInfectionMaleCount(Integer.parseInt(objectMap.get("a_count").toString()));
  192. }
  193. }
  194. sql = "SELECT t1.gender,COUNT(t1.*) AS a_count FROM student_psychological t1" +
  195. " INNER JOIN xjr_workflow_form_relation t2 ON t1.id = t2.form_key_value" +
  196. " WHERE t2.current_state = 'COMPLETED' GROUP BY t1.gender";
  197. list = SqlRunnerAdapter.db().selectList(sql);
  198. for (Map<String, Object> objectMap : list) {
  199. if (objectMap.get("gender") != null && GenderDictionaryEnum.FEMALE.getCode().equals(objectMap.get("gender").toString())) {
  200. result.setInfectionFemaleCount(Integer.parseInt(objectMap.get("a_count").toString()));
  201. }
  202. if (objectMap.get("gender") != null && GenderDictionaryEnum.MALE.getCode().equals(objectMap.get("gender").toString())) {
  203. result.setPsychologicalMaleCount(Integer.parseInt(objectMap.get("a_count").toString()));
  204. }
  205. }
  206. List<HealthItemCountVo> gradeList = new ArrayList<>();
  207. sql = "SELECT t1.name as item,COUNT(t3.student_id) AS count FROM base_grade t1" +
  208. " INNER JOIN base_student_school_roll t2 ON t1.id= t2.grade_id" +
  209. " INNER JOIN student_infection t3 ON t3.student_id = t2.user_id" +
  210. " INNER JOIN xjr_workflow_form_relation t4 ON t3.id = t4.form_key_value" +
  211. " WHERE t4.current_state = 'COMPLETED' AND t1.delete_mark = 0" +
  212. " GROUP BY t1.name";
  213. list = SqlRunnerAdapter.db().selectList(sql);
  214. for (Map<String, Object> objectMap : list) {
  215. gradeList.add(
  216. new HealthItemCountVo() {{
  217. setItem(objectMap.get("item").toString());
  218. setInfectionCount(Long.parseLong(objectMap.get("count").toString()));
  219. }}
  220. );
  221. }
  222. sql = "SELECT t1.name as item,COUNT(t3.student_id) AS count FROM base_grade t1" +
  223. " INNER JOIN base_student_school_roll t2 ON t1.id= t2.grade_id" +
  224. " INNER JOIN student_psychological t3 ON t3.student_id = t2.user_id" +
  225. " INNER JOIN xjr_workflow_form_relation t4 ON t3.id = t4.form_key_value" +
  226. " WHERE t4.current_state = 'COMPLETED' AND t1.delete_mark = 0" +
  227. " GROUP BY t1.name";
  228. list = SqlRunnerAdapter.db().selectList(sql);
  229. for (Map<String, Object> objectMap : list) {
  230. for (HealthItemCountVo itemCountVo : gradeList) {
  231. if (objectMap.get("item").toString().equals(itemCountVo.getItem())) {
  232. itemCountVo.setPsychologicalCount(Long.parseLong(objectMap.get("count").toString()));
  233. }
  234. }
  235. }
  236. result.setGradeList(gradeList);
  237. List<HealthItemCountVo> classList = new ArrayList<>();
  238. sql = "SELECT t1.name as item,COUNT(t3.student_id) AS count FROM base_class t1" +
  239. " INNER JOIN base_student_school_roll t2 ON t1.id= t2.grade_id" +
  240. " INNER JOIN student_infection t3 ON t3.student_id = t2.user_id" +
  241. " INNER JOIN xjr_workflow_form_relation t4 ON t3.id = t4.form_key_value" +
  242. " WHERE t4.current_state = 'COMPLETED' AND t1.delete_mark = 0" +
  243. " GROUP BY t1.name";
  244. list = SqlRunnerAdapter.db().selectList(sql);
  245. for (Map<String, Object> objectMap : list) {
  246. classList.add(
  247. new HealthItemCountVo() {{
  248. setItem(objectMap.get("item").toString());
  249. setInfectionCount(Long.parseLong(objectMap.get("count").toString()));
  250. }}
  251. );
  252. }
  253. sql = "SELECT t1.name as item,COUNT(t3.student_id) AS count FROM base_class t1" +
  254. " INNER JOIN base_student_school_roll t2 ON t1.id= t2.grade_id" +
  255. " INNER JOIN student_psychological t3 ON t3.student_id = t2.user_id" +
  256. " INNER JOIN xjr_workflow_form_relation t4 ON t3.id = t4.form_key_value" +
  257. " WHERE t4.current_state = 'COMPLETED' AND t1.delete_mark = 0" +
  258. " GROUP BY t1.name";
  259. list = SqlRunnerAdapter.db().selectList(sql);
  260. for (Map<String, Object> objectMap : list) {
  261. for (HealthItemCountVo itemCountVo : classList) {
  262. if (objectMap.get("item").toString().equals(itemCountVo.getItem())) {
  263. itemCountVo.setPsychologicalCount(Long.parseLong(objectMap.get("count").toString()));
  264. }
  265. }
  266. }
  267. result.setClassList(classList);
  268. return RT.ok(result);
  269. }
  270. @GetMapping(value = "/person-statistics")
  271. @ApiOperation(value = "教职工详情数据统计")
  272. @SaCheckPermission("datadetail:detail")
  273. @XjrLog(value = "教职工详情数据统计", saveResponseData = true)
  274. public RT<TeacherStatisticsDetailVo> teahcerStatistics(@Valid StatisticsDetailDto dto) throws ParseException {
  275. String sql = "SELECT IFNULL(t2.name,'未填写') AS item ,ifnull(COUNT(*), 0) AS a_count FROM base_teacher_education t1" +
  276. " left join base_teacher t3 on t1.user_id = t3.user_id" +
  277. " LEFT JOIN xjr_dictionary_detail t2 ON t1.education = t2.code" +
  278. " WHERE t1.delete_mark = 0 and t3.job_state in ('ZZZT10004','ZZZT10009','JOB_WCPX','JOB_DDSX')" +
  279. " GROUP BY t2.name";
  280. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  281. TeacherStatisticsDetailVo result = new TeacherStatisticsDetailVo();
  282. List<ItemCountVo> educationList = new ArrayList<>();
  283. for (Map<String, Object> objectMap : list) {
  284. educationList.add(
  285. new ItemCountVo() {{
  286. setItem(objectMap.get("item").toString());
  287. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  288. }}
  289. );
  290. }
  291. result.setEducationList(educationList);
  292. sql = "SELECT IFNULL(t3.name,'未填写') AS item ,ifnull(COUNT(*), 0) AS a_count FROM xjr_user t1" +
  293. " INNER JOIN base_teacher t2 ON t1.id = t2.user_id" +
  294. " LEFT JOIN xjr_dictionary_detail t3 ON t1.gender = t3.code AND t3.item_id = 2023000000000000004" +
  295. " WHERE t1.delete_mark = 0 and t2.job_state in ('ZZZT10004','ZZZT10009','JOB_WCPX','JOB_DDSX') GROUP BY t3.name";
  296. list = SqlRunnerAdapter.db().selectList(sql);
  297. List<ItemCountVo> genderList = new ArrayList<>();
  298. for (Map<String, Object> objectMap : list) {
  299. genderList.add(
  300. new ItemCountVo() {{
  301. setItem(objectMap.get("item").toString());
  302. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  303. }}
  304. );
  305. }
  306. result.setGenderList(genderList);
  307. sql = "SELECT IFNULL(t3.name,'未填写') AS item ,ifnull(COUNT(*), 0) AS a_count FROM xjr_user t1" +
  308. " INNER JOIN base_teacher t2 ON t1.id = t2.user_id" +
  309. " LEFT JOIN xjr_dictionary_detail t3 ON t2.employ_type = t3.code AND t3.item_id = 2023000000000000016" +
  310. " WHERE t1.delete_mark = 0 and t2.job_state in ('ZZZT10004','ZZZT10009','JOB_WCPX','JOB_DDSX') GROUP BY t3.name";
  311. list = SqlRunnerAdapter.db().selectList(sql);
  312. List<ItemCountVo> employList = new ArrayList<>();
  313. for (Map<String, Object> objectMap : list) {
  314. employList.add(
  315. new ItemCountVo() {{
  316. setItem(objectMap.get("item").toString());
  317. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  318. }}
  319. );
  320. }
  321. result.setEmployList(employList);
  322. sql = "SELECT IFNULL(t4.name,'未填写') AS item ,ifnull(COUNT(*), 0) AS a_count FROM xjr_user t1" +
  323. " INNER JOIN base_teacher t2 ON t1.id = t2.user_id" +
  324. " LEFT JOIN xjr_user_dept_relation t3 ON t1.id = t3.user_id" +
  325. " LEFT JOIN xjr_department t4 ON t3.dept_id = t4.id" +
  326. " WHERE t1.delete_mark = 0 AND t4.is_major = 1 and t2.job_state in ('ZZZT10004','ZZZT10009','JOB_WCPX','JOB_DDSX') GROUP BY t4.name";
  327. list = SqlRunnerAdapter.db().selectList(sql);
  328. List<ItemCountVo> deptList = new ArrayList<>();
  329. for (Map<String, Object> objectMap : list) {
  330. deptList.add(
  331. new ItemCountVo() {{
  332. setItem(objectMap.get("item").toString());
  333. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  334. }}
  335. );
  336. }
  337. result.setDeptList(deptList);
  338. MPJLambdaWrapper<XjrUser> queryWrapper = MPJWrappers.<XjrUser>lambdaJoin()
  339. .disableSubLogicDel()
  340. .orderByDesc(XjrUser::getId)
  341. .select(XjrUser::getId)
  342. .select(XjrUser.class, x -> VoToColumnUtil.fieldsToColumns(XjrUserPageVo.class).contains(x.getProperty()))
  343. .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, XjrUser::getId)
  344. .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseTeacher::getJobState, ext -> ext.selectAs(DictionaryDetail::getName, XjrUserPageVo::getJobState))
  345. .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, XjrUser::getCredentialType, ext -> ext.selectAs(DictionaryDetail::getName, XjrUserPageVo::getCredentialType))
  346. .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseTeacher::getEmployWay, ext -> ext.selectAs(DictionaryDetail::getName, XjrUserPageVo::getEmployWay))
  347. .selectAsClass(BaseTeacher.class, XjrUserPageVo.class);
  348. List<XjrUserPageVo> teacherList = teacherService.selectJoinList(XjrUserPageVo.class, queryWrapper);
  349. List<String> idCardList = teacherList.stream().map(XjrUserPageVo::getCredentialNumber).collect(Collectors.toList());
  350. SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
  351. LocalDate currentDate = LocalDate.now();
  352. int age20 = 0;
  353. int age30 = 0;
  354. int age40 = 0;
  355. int age50 = 0;
  356. int age60 = 0;
  357. for (String idCard : idCardList) {
  358. if (StrUtil.isEmpty(idCard) || idCard.length() < 18) {
  359. continue;
  360. }
  361. String birthdayStr = idCard.substring(6, 14);
  362. java.util.Date date = sdf.parse(birthdayStr);
  363. // 将Date对象转换为LocalDate对象
  364. LocalDate birthDate = date.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
  365. Period ageObj = Period.between(birthDate, currentDate);
  366. int age = ageObj.getYears();
  367. if (age >= 20 && age <= 29) {
  368. age20++;
  369. } else if (age >= 30 && age <= 39) {
  370. age30++;
  371. } else if (age >= 40 && age <= 49) {
  372. age40++;
  373. } else if (age >= 50 && age <= 59) {
  374. age50++;
  375. } else if (age >= 60) {
  376. age60++;
  377. }
  378. }
  379. List<ItemCountVo> ageList = new ArrayList<>();
  380. ItemCountVo itemCountVo = new ItemCountVo();
  381. itemCountVo.setItem("20-29岁");
  382. itemCountVo.setCount(age20);
  383. ageList.add(itemCountVo);
  384. itemCountVo = new ItemCountVo();
  385. itemCountVo.setItem("30-39岁");
  386. itemCountVo.setCount(age30);
  387. ageList.add(itemCountVo);
  388. itemCountVo = new ItemCountVo();
  389. itemCountVo.setItem("40-49岁");
  390. itemCountVo.setCount(age40);
  391. ageList.add(itemCountVo);
  392. itemCountVo = new ItemCountVo();
  393. itemCountVo.setItem("50-59岁");
  394. itemCountVo.setCount(age50);
  395. ageList.add(itemCountVo);
  396. itemCountVo = new ItemCountVo();
  397. itemCountVo.setItem("60岁以上");
  398. itemCountVo.setCount(age60);
  399. ageList.add(itemCountVo);
  400. result.setAgeList(ageList);
  401. return RT.ok(result);
  402. }
  403. @GetMapping(value = "/person-statistics-tea-change")
  404. @ApiOperation(value = "教职工详情数据统计之教职工变动情况")
  405. @SaCheckPermission("datadetail:detail")
  406. @XjrLog(value = "教职工详情数据统计之教职工变动情况", saveResponseData = true)
  407. public RT<TeacherChangeStatisticsDetailVo> teacherChangeStatisticsDetail(@Valid TeacherChangeStatisticsDetailDto dto){
  408. TeacherChangeStatisticsDetailVo teacherChangeStatisticsDetailVo = new TeacherChangeStatisticsDetailVo();
  409. // 处理时间范围
  410. if(ObjectUtils.isNotEmpty(dto.getStatus()) && dto.getStatus() == 1 && StringUtils.isNotEmpty(dto.getYearMonth())){
  411. String yearMonthStr = dto.getYearMonth() + "-01";
  412. LocalDate yearMonthLocalDate = LocalDate.parse(yearMonthStr);
  413. // 上个月的最后一天
  414. LocalDate lastDayOfPreviousMonth = yearMonthLocalDate.minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
  415. LocalDateTime startTime = lastDayOfPreviousMonth.atTime(23, 59, 59);
  416. // 下个月的第一天
  417. LocalDate firstDayOfNextMonth = yearMonthLocalDate.plusMonths(1).with(TemporalAdjusters.firstDayOfMonth());
  418. LocalDateTime endTime = firstDayOfNextMonth.atStartOfDay();
  419. dto.setStartTime(startTime);
  420. dto.setEndTime(endTime);
  421. }
  422. if(ObjectUtils.isNotEmpty(dto.getStatus()) && dto.getStatus() == 2 && ObjectUtils.isNotEmpty(dto.getBaseSemesterId())){
  423. // 获取学期
  424. BaseSemester baseSemester = baseSemesterMapper.selectById(dto.getBaseSemesterId());
  425. LocalDateTime startTime = baseSemester.getStartDate().toInstant()
  426. .atZone(ZoneId.systemDefault()) // 使用系统默认时区
  427. .toLocalDateTime();
  428. LocalDateTime endTime = baseSemester.getEndDate().toInstant()
  429. .atZone(ZoneId.systemDefault()) // 使用系统默认时区
  430. .toLocalDateTime();
  431. dto.setStartTime(startTime);
  432. dto.setEndTime(endTime);
  433. }
  434. if(ObjectUtils.isNotEmpty(dto.getStatus()) && dto.getStatus() == 3 && ObjectUtils.isNotEmpty(dto.getYear())){
  435. LocalDate yearLocalDate = LocalDate.of(dto.getYear(), 1, 1);
  436. LocalDate lastDayOfLastYear = yearLocalDate.minusYears(1).with(TemporalAdjusters.lastDayOfYear());
  437. LocalDateTime startTime = lastDayOfLastYear.atTime(23, 59, 59);
  438. LocalDate firstDayOfNextYear = yearLocalDate.plusYears(1).with(TemporalAdjusters.firstDayOfYear());
  439. LocalDateTime endTime = firstDayOfNextYear.atStartOfDay();
  440. dto.setStartTime(startTime);
  441. dto.setEndTime(endTime);
  442. }
  443. if(ObjectUtils.isEmpty(dto.getStatus())){
  444. LocalDate yearLocalDate = LocalDate.now();
  445. LocalDate lastDayOfLastYear = yearLocalDate.minusYears(1).with(TemporalAdjusters.lastDayOfYear());
  446. LocalDateTime startTime = lastDayOfLastYear.atTime(23, 59, 59);
  447. LocalDate firstDayOfNextYear = yearLocalDate.plusYears(1).with(TemporalAdjusters.firstDayOfYear());
  448. LocalDateTime endTime = firstDayOfNextYear.atStartOfDay();
  449. dto.setStartTime(startTime);
  450. dto.setEndTime(endTime);
  451. }
  452. // 教职工异动统计数据
  453. // 获取每个教职工异动最后一条数据
  454. String sql = "select t.user_id,\n" +
  455. " t.new_job_state,\n" +
  456. " t1.employ_type\n" +
  457. "from base_teacher_change_record t\n" +
  458. " inner join (SELECT user_id,\n" +
  459. " MAX(id) AS max_id\n" +
  460. " FROM base_teacher_change_record a\n" +
  461. " where a.delete_mark = 0\n" +
  462. " and a.create_date between '" + dto.getStartTime() + "' and '" + dto.getEndTime()+ "'\n" +
  463. " GROUP BY user_id) t2 on t2.max_id = t.id\n" +
  464. " left join base_teacher t1 on t1.user_id = t.user_id\n" +
  465. "where t.delete_mark = 0\n" +
  466. " and t1.delete_mark = 0"
  467. ;
  468. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  469. Map<String, Map<String, Object>> statics = new LinkedHashMap<>();
  470. for (Map<String, Object> oneRecord : list){
  471. String jobState = oneRecord.get("new_job_state").toString();
  472. if(jobState.equals("在职")){
  473. continue;
  474. }
  475. String employType = oneRecord.get("employ_type").toString();
  476. if(!employType.equals("FB1601") && !employType.equals("FB1605")){
  477. continue;
  478. }
  479. if(statics.containsKey(jobState)){
  480. Map<String, Object> oneMap = statics.get(jobState);
  481. if(employType.equals("FB1601")){
  482. oneMap.put("count", (int)oneMap.get("count") + 1);
  483. }
  484. if(employType.equals("FB1605")){
  485. oneMap.put("count1", (int)oneMap.get("count1") + 1);
  486. }
  487. }else {
  488. Map<String, Object> oneMap = new LinkedHashMap<>();
  489. oneMap.put("item", jobState);
  490. oneMap.put("count", 0);
  491. oneMap.put("count1", 0);
  492. if(employType.equals("FB1601")){
  493. oneMap.put("count", (int)oneMap.get("count") + 1);
  494. }
  495. if(employType.equals("FB1605")){
  496. oneMap.put("count1", (int)oneMap.get("count1") + 1);
  497. }
  498. statics.put(jobState, oneMap);
  499. }
  500. }
  501. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  502. // 处理入职人数
  503. LambdaQueryWrapper<BaseTeacher> baseTeacherLambdaQueryWrapper = new LambdaQueryWrapper<>();
  504. baseTeacherLambdaQueryWrapper
  505. .ge(BaseTeacher::getJoinTime, formatter.format(dto.getStartTime()))
  506. .le(BaseTeacher::getJoinTime, formatter.format(dto.getEndTime()))
  507. .eq(BaseTeacher::getDeleteMark, DeleteMark.NODELETE.getCode())
  508. ;
  509. List<BaseTeacher> baseTeacherList = baseTeacherService.list(baseTeacherLambdaQueryWrapper);
  510. if(CollectionUtils.isNotEmpty(baseTeacherList)){
  511. for (BaseTeacher baseTeacher : baseTeacherList){
  512. Map<String, Object> oneMap = new LinkedHashMap<>();
  513. oneMap.put("item", "入职人数");
  514. oneMap.put("count", 0);
  515. oneMap.put("count1", 0);
  516. if("FB1601".equals(baseTeacher.getEmployType())){
  517. oneMap.put("count", (int)oneMap.get("count") + 1);
  518. }
  519. if("FB1605".equals(baseTeacher.getEmployType())){
  520. oneMap.put("count1", (int)oneMap.get("count1") + 1);
  521. }
  522. statics.put("入职人数", oneMap);
  523. }
  524. }
  525. teacherChangeStatisticsDetailVo.setTeacherChangeItemVoList(new ArrayList<>(statics.values()));
  526. return RT.ok(teacherChangeStatisticsDetailVo);
  527. }
  528. @GetMapping(value = "/student-statistics")
  529. @ApiOperation(value = "学生详情数据统计")
  530. @SaCheckPermission("datadetail:detail")
  531. @XjrLog(value = "学生详情数据统计", saveResponseData = true)
  532. public RT<StudnetStatisticsDetailVo> studentStatistics(@Valid StatisticsDetailDto dto) {
  533. StudnetStatisticsDetailVo result = new StudnetStatisticsDetailVo();
  534. String sql = "SELECT IFNULL(t3.name,'未填写') AS item ,COUNT(*) AS a_count FROM xjr_user t1" +
  535. " INNER JOIN base_student t2 ON t1.id = t2.user_id" +
  536. " INNER JOIN base_student_school_roll t4 ON t1.id = t4.user_id" +
  537. " LEFT JOIN xjr_dictionary_detail t3 ON t1.gender = t3.code" +
  538. " AND t3.item_id = 2023000000000000004 and t3.delete_mark = 0" +
  539. " WHERE t1.delete_mark = 0" +
  540. " and t4.archives_status = 'FB2901'" +
  541. " GROUP BY t3.name";
  542. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  543. List<ItemCountVo> genderList = new ArrayList<>();
  544. for (Map<String, Object> objectMap : list) {
  545. genderList.add(
  546. new ItemCountVo() {{
  547. setItem(objectMap.get("item").toString());
  548. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  549. }}
  550. );
  551. }
  552. result.setGenderList(genderList);
  553. sql = "SELECT IFNULL(t3.name,'未填写') AS item ,COUNT(*) AS a_count FROM xjr_user t1" +
  554. " INNER JOIN base_student_school_roll t2 ON t1.id = t2.user_id" +
  555. " LEFT JOIN xjr_dictionary_detail t3 ON t2.student_type = t3.code" +
  556. " AND t3.item_id = 2023000000000000028 and t3.delete_mark = 0" +
  557. " WHERE t1.delete_mark = 0" +
  558. " and t2.archives_status = 'FB2901'" +
  559. " GROUP BY t3.name";
  560. list = SqlRunnerAdapter.db().selectList(sql);
  561. List<ItemCountVo> studentTypeList = new ArrayList<>();
  562. for (Map<String, Object> objectMap : list) {
  563. studentTypeList.add(
  564. new ItemCountVo() {{
  565. setItem(objectMap.get("item").toString());
  566. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  567. }}
  568. );
  569. }
  570. result.setStudentTypeList(studentTypeList);
  571. List<BaseStudentUserPageVo> studentList = studentService.getStudentList(new BaseStudentUserPageDto());
  572. Set<String> studentStayMaleSet = studentList.stream()
  573. .filter(x -> (
  574. x.getGenderCn() != null
  575. && x.getGenderCn().equals(GenderDictionaryEnum.MALE.getCode())
  576. && x.getStduyStatusCn() != null
  577. && x.getStduyStatusCn().equals(StudyStatusEnum.InResidence.getCode())
  578. ))
  579. .map(BaseStudentUserPageVo::getId).collect(Collectors.toSet());
  580. result.setStudentStayMaleCount(studentStayMaleSet.size());
  581. Set<String> studentNotStayMaleSet = studentList.stream()
  582. .filter(x -> (
  583. x.getGenderCn() != null
  584. && x.getGenderCn().equals(GenderDictionaryEnum.MALE.getCode())
  585. && x.getStduyStatusCn() != null
  586. && x.getStduyStatusCn().equals(StudyStatusEnum.AttendDaySchool.getCode())
  587. ))
  588. .map(BaseStudentUserPageVo::getId).collect(Collectors.toSet());
  589. result.setStudentNotStayMaleCount(studentNotStayMaleSet.size());
  590. Set<String> studentStayFemaleSet = studentList.stream()
  591. .filter(x -> (
  592. x.getGenderCn() != null
  593. && x.getGenderCn().equals(GenderDictionaryEnum.FEMALE.getCode())
  594. && x.getStduyStatusCn() != null
  595. && x.getStduyStatusCn().equals(StudyStatusEnum.InResidence.getCode())
  596. ))
  597. .map(BaseStudentUserPageVo::getId).collect(Collectors.toSet());
  598. result.setStudentStayFemaleCount(studentStayFemaleSet.size());
  599. Set<String> studentNotStayFemaleSet = studentList.stream()
  600. .filter(x -> (
  601. x.getGenderCn() != null
  602. && x.getGenderCn().equals(GenderDictionaryEnum.FEMALE.getCode())
  603. && x.getStduyStatusCn() != null
  604. && x.getStduyStatusCn().equals(StudyStatusEnum.AttendDaySchool.getCode())
  605. ))
  606. .map(BaseStudentUserPageVo::getId).collect(Collectors.toSet());
  607. result.setStudentNotStayFemaleCount(studentNotStayFemaleSet.size());
  608. sql = "SELECT name AS item,(" +
  609. " SELECT COUNT(*) FROM xjr_user t1" +
  610. " INNER JOIN base_student_school_roll t2 ON t1.id = t2.user_id" +
  611. " WHERE t1.delete_mark = 0 AND t2.grade_id = base_grade.id" +
  612. " and t2.archives_status = 'FB2901') AS a_count FROM base_grade" +
  613. " WHERE delete_mark = 0 AND status = 1";
  614. if (dto.getGradeId() != null) {
  615. sql += " id = " + dto.getGradeId();
  616. }
  617. sql += " ORDER BY name DESC LIMIT 4";
  618. list = SqlRunnerAdapter.db().selectList(sql);
  619. Collections.reverse(list);
  620. List<ItemCountVo> gradeList = new ArrayList<>();
  621. for (Map<String, Object> objectMap : list) {
  622. int aCount = Integer.parseInt(objectMap.get("a_count").toString());
  623. if (aCount == 0) {
  624. continue;
  625. }
  626. gradeList.add(
  627. new ItemCountVo() {{
  628. setItem(objectMap.get("item").toString());
  629. setCount(aCount);
  630. }}
  631. );
  632. }
  633. result.setGradeList(gradeList);
  634. sql = "SELECT NAME AS item,(\n" +
  635. "SELECT COUNT(*) FROM xjr_user t1\n" +
  636. "INNER JOIN base_student_school_roll t2 ON t1.id = t2.user_id\n" +
  637. "INNER JOIN base_class t3 ON t2.class_id = t3.id\n" +
  638. "WHERE t1.delete_mark = 0 AND t3.org_id = xjr_department.id\n" +
  639. "AND t2.archives_status = 'FB2901' AND t1.gender = 'SB10001') AS a_count,\n" +
  640. "(\n" +
  641. "SELECT COUNT(*) FROM xjr_user t1\n" +
  642. "INNER JOIN base_student_school_roll t2 ON t1.id = t2.user_id\n" +
  643. "INNER JOIN base_class t3 ON t2.class_id = t3.id\n" +
  644. "WHERE t1.delete_mark = 0 AND t3.org_id = xjr_department.id\n" +
  645. "AND t2.archives_status = 'FB2901' AND t1.gender = 'SB10002') AS b_count FROM xjr_department\n" +
  646. "WHERE delete_mark = 0 AND is_major = 1 ORDER BY NAME DESC";
  647. list = SqlRunnerAdapter.db().selectList(sql);
  648. Collections.reverse(list);
  649. List<StudentReportRecordItemVo> deptList = new ArrayList<>();
  650. for (Map<String, Object> objectMap : list) {
  651. deptList.add(
  652. new StudentReportRecordItemVo() {{
  653. setItem(objectMap.get("item").toString());
  654. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  655. setCount2(Integer.parseInt(objectMap.get("b_count").toString()));
  656. }}
  657. );
  658. }
  659. result.setDeptList(deptList);
  660. return RT.ok(result);
  661. }
  662. @GetMapping(value = "/subscription-statistics")
  663. @ApiOperation(value = "物品申购详情数据统计")
  664. @SaCheckPermission("datadetail:detail")
  665. @XjrLog(value = "物品申购详情数据统计", saveResponseData = true)
  666. public RT<SubscriptionStatisticsDetailVo> subscriptionStatistics(@Valid StatisticsDetailDto dto) {
  667. SubscriptionStatisticsDetailVo result = new SubscriptionStatisticsDetailVo();
  668. LocalDateTime startTime = null;
  669. LocalDateTime endTime = null;
  670. if (dto.getStartDate() != null) {
  671. startTime = dto.getStartDate().atStartOfDay();
  672. }
  673. if (dto.getEndDate() != null) {
  674. endTime = dto.getEndDate().atStartOfDay().plusDays(1).plusNanos(-1);
  675. }
  676. List<WfSubscription> list = subscriptionService.list(
  677. new MPJLambdaWrapper<WfSubscription>()
  678. .select(WfSubscription::getId)
  679. .select(WfSubscription.class, x -> VoToColumnUtil.fieldsToColumns(WfSubscription.class).contains(x.getProperty()))
  680. .innerJoin(WorkflowFormRelation.class, WorkflowFormRelation::getFormKeyValue, WfSubscription::getId)
  681. .eq(WorkflowFormRelation::getCurrentState, HistoricProcessInstance.STATE_COMPLETED)
  682. .between((startTime != null && endTime != null), WfSubscription::getShenQingRiQi4752, startTime, endTime)
  683. );
  684. result.setAllCount(list.size());
  685. double totalAmount = list.stream().filter(x -> x.getTotalAmount() != null && x.getStatus() == 1).mapToDouble(WfSubscription::getTotalAmount).sum();
  686. result.setTotalAmount(totalAmount);
  687. int adoptCount = list.stream().filter(x -> x.getStatus() == 1).collect(Collectors.toList()).size();
  688. result.setAdoptCount(adoptCount);
  689. int pendingCount = list.stream().filter(x -> x.getStatus() == null || x.getStatus() == 0).collect(Collectors.toList()).size();
  690. result.setPendingCount(pendingCount);
  691. 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" +
  692. " INNER JOIN wf_subscription t2 ON t1.parent_id = t2.id" +
  693. " INNER JOIN xjr_workflow_form_relation t4 ON t1.id = t4.form_key_value" +
  694. " LEFT JOIN xjr_dictionary_detail t3 ON t1.item_type = t3.code" +
  695. " AND t3.item_id = 1752140413593518081" +
  696. " WHERE t4.current_state = 'COMPLETED'";
  697. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  698. if (startTime != null && endTime != null) {
  699. sql += " and t2.shen_qing_ri_qi4752 between '" + startTime.format(formatter) + "' and '" + endTime.format(formatter) + "'";
  700. }
  701. sql += " GROUP BY t3.name";
  702. List<Map<String, Object>> datalist = SqlRunnerAdapter.db().selectList(sql);
  703. List<ItemCountVo> categoryCountList = new ArrayList<>();
  704. List<ItemDoubleVo> categoryAmountList = new ArrayList<>();
  705. for (Map<String, Object> objectMap : datalist) {
  706. categoryCountList.add(
  707. new ItemCountVo() {{
  708. setItem(objectMap.get("item").toString());
  709. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  710. }}
  711. );
  712. categoryAmountList.add(
  713. new ItemDoubleVo() {{
  714. setItem(objectMap.get("item").toString());
  715. setAmount(Double.parseDouble(objectMap.get("a_sum").toString()));
  716. }}
  717. );
  718. }
  719. result.setCategoryCountList(categoryCountList);
  720. result.setCategoryAmountList(categoryAmountList);
  721. 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" +
  722. " INNER JOIN wf_subscription t2 ON t1.parent_id = t2.id" +
  723. " INNER JOIN xjr_workflow_form_relation t4 ON t1.id = t4.form_key_value" +
  724. " LEFT JOIN xjr_department t3 ON t2.application_department = t3.id" +
  725. " WHERE t4.current_state = 'COMPLETED'";
  726. if (startTime != null && endTime != null) {
  727. sql += " and t2.shen_qing_ri_qi4752 between '" + startTime.format(formatter) + "' and '" + endTime.format(formatter) + "'";
  728. }
  729. sql += " GROUP BY t3.name";
  730. datalist = SqlRunnerAdapter.db().selectList(sql);
  731. List<ItemCountAmountVo> deptList = new ArrayList<>();
  732. for (Map<String, Object> objectMap : datalist) {
  733. deptList.add(
  734. new ItemCountAmountVo() {{
  735. setItem(objectMap.get("item").toString());
  736. setCount(Integer.parseInt(objectMap.get("a_count").toString()));
  737. setAmount(Double.parseDouble(objectMap.get("a_sum").toString()));
  738. }}
  739. );
  740. }
  741. result.setDeptList(deptList);
  742. return RT.ok(result);
  743. }
  744. @GetMapping(value = "/course-statistics")
  745. @ApiOperation(value = "课表详情数据统计")
  746. @SaCheckPermission("datadetail:detail")
  747. @XjrLog(value = "课表详情数据统计", saveResponseData = true)
  748. public RT<CourseStatisticsDetailVo> courseStatistics(@Valid StatisticsDetailDto dto) {
  749. String startDate = null;
  750. String endDate = null;
  751. if(dto.getStartDate() != null && dto.getEndDate() != null){
  752. startDate = dto.getStartDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
  753. endDate = dto.getEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
  754. }
  755. CourseStatisticsDetailVo result = new CourseStatisticsDetailVo();
  756. String sql = "SELECT t1.id, t1.name,t4.name AS dept_name,( " +
  757. " SELECT GROUP_CONCAT(DISTINCT(course_name)) FROM course_table WHERE FIND_IN_SET(t1.id, teacher_id) > 0 ";
  758. if(startDate != null){
  759. sql += " and schedule_date between '" + startDate + "' and '" + endDate + "'";
  760. }
  761. sql += " ) AS course_names,(" +
  762. "SELECT COUNT(*) FROM course_table WHERE FIND_IN_SET(t1.id, teacher_id) > 0 ";
  763. if(startDate != null){
  764. sql += " and schedule_date between '" + startDate + "' and '" + endDate + "'";
  765. }
  766. sql += " ) AS course_count FROM xjr_user t1" +
  767. " INNER JOIN base_teacher t2 ON t1.id = t2.user_id" +
  768. " INNER JOIN xjr_user_dept_relation t3 ON t1.id = t3.user_id" +
  769. " INNER JOIN xjr_department t4 ON t3.dept_id = t4.id" +
  770. " WHERE t1.delete_mark = 0 AND t4.is_major = 1";
  771. sql += " ORDER BY course_count DESC LIMIT 5";
  772. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  773. List<CourseCountListVo> courseCountList = new ArrayList<>();
  774. for (Map<String, Object> objectMap : list) {
  775. CourseCountListVo listVo = SqlRunnerAdapterUtil.convertMapToEntity(objectMap, CourseCountListVo.class);
  776. courseCountList.add(listVo);
  777. }
  778. result.setCourseCountList(courseCountList);
  779. sql = "SELECT count(*) FROM course_table t1" +
  780. " INNER JOIN base_teacher t2 ON FIND_IN_SET(t2.user_id, t1.teacher_id) > 0" +
  781. " INNER JOIN xjr_user_dept_relation t3 ON t2.user_id = t3.user_id" +
  782. " INNER JOIN xjr_department t4 ON t4.id = t3.dept_id" +
  783. " WHERE t4.delete_mark = 0 AND t2.delete_mark = 0" +
  784. " AND t4.is_major = 1";
  785. if(startDate != null){
  786. sql += " and t1.schedule_date between '" + startDate + "' and '" + endDate + "'";
  787. }
  788. long allCourseCount = SqlRunnerAdapter.db().selectCount(sql);
  789. sql = "SELECT name,(" +
  790. " SELECT COUNT(*) FROM course_table t1" +
  791. " INNER JOIN base_teacher t2 ON FIND_IN_SET(t2.user_id, t1.teacher_id) > 0" +
  792. " INNER JOIN xjr_user_dept_relation t3 ON t2.user_id = t3.user_id" +
  793. " WHERE t3.dept_id = xjr_department.id";
  794. if(startDate != null){
  795. sql += " and t1.schedule_date between '" + startDate + "' and '" + endDate + "'";
  796. }
  797. sql += " ) AS course_count FROM xjr_department WHERE is_major = 1";
  798. list = SqlRunnerAdapter.db().selectList(sql);
  799. List<ItemCountRatioVo> deptCourseList = new ArrayList<>();
  800. for (Map<String, Object> objectMap : list) {
  801. int courseCount = Integer.parseInt(objectMap.get("course_count").toString());
  802. //计算出勤率
  803. BigDecimal divide = BigDecimal.valueOf(courseCount).divide(BigDecimal.valueOf(allCourseCount), 4, RoundingMode.HALF_UP);
  804. deptCourseList.add(
  805. new ItemCountRatioVo() {{
  806. setItem(objectMap.get("name").toString());
  807. setCount(courseCount);
  808. setRatio(divide.doubleValue());
  809. }}
  810. );
  811. }
  812. result.setDeptCourseList(deptCourseList);
  813. return RT.ok(result);
  814. }
  815. @GetMapping(value = "/room-statistics")
  816. @ApiOperation(value = "寝室统计")
  817. @SaCheckPermission("databoard:detail")
  818. @XjrLog(value = "寝室统计", saveResponseData = true)
  819. public RT<RoomStatisticsDetailVo> roomStatistics(@Valid StatisticsDetailDto dto) {
  820. RoomStatisticsDetailVo result = new RoomStatisticsDetailVo();
  821. String sql = "SELECT t2.id, t3.user_id,t4.name AS grade_name, t6.name AS dept_name,t7.gender FROM room t1" +
  822. " INNER JOIN room_bed t2 ON t1.id = t2.room_id" +
  823. " LEFT JOIN base_student_school_roll t3 ON t2.student_user_id = t3.user_id" +
  824. " LEFT JOIN base_grade t4 ON t3.grade_id = t4.id AND t4.status = 1" +
  825. " LEFT JOIN base_class t5 ON t3.class_id = t5.id" +
  826. " LEFT JOIN xjr_department t6 ON t5.org_id = t6.id" +
  827. " LEFT JOIN xjr_user t7 ON t3.user_id = t7.id" +
  828. " WHERE t1.delete_mark = 0 AND t2.delete_mark = 0";
  829. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  830. Integer allCount = list.size();
  831. long emptyCount = list.stream().filter(x -> ObjectUtil.isNull(x.get("user_id"))).count();
  832. BigDecimal emptyRatio = BigDecimal.valueOf(emptyCount).divide(BigDecimal.valueOf(allCount), 4, RoundingMode.HALF_UP);
  833. result.setEmptyRatio(emptyRatio.doubleValue() + "");
  834. long notEmptyCount = list.stream().filter(x -> ObjectUtil.isNotNull(x.get("user_id"))).count();
  835. BigDecimal notEmptyRatio = BigDecimal.valueOf(notEmptyCount).divide(BigDecimal.valueOf(allCount), 4, RoundingMode.HALF_UP);
  836. result.setNotEmptyRatio(notEmptyRatio.doubleValue() + "");
  837. Map<String, List<Map<String, Object>>> gradeMap = list.stream().filter(x -> ObjectUtil.isNotNull(x.get("grade_name"))).collect(Collectors.groupingBy(x -> x.get("grade_name").toString()));
  838. List<ItemCount2Vo> gradeList = new ArrayList<>();
  839. for (String gradeName : gradeMap.keySet()) {
  840. List<Map<String, Object>> gradeDataList = gradeMap.get(gradeName);
  841. Map<String, Long> genderMap = gradeDataList.stream().filter(x -> ObjectUtil.isNotNull(x.get("gender"))).collect(Collectors.groupingBy(x -> x.get("gender").toString(), Collectors.counting()));
  842. ItemCount2Vo gradeVo = new ItemCount2Vo();
  843. gradeVo.setItem(gradeName);
  844. if(genderMap.get(GenderDictionaryEnum.MALE.getCode()) != null){
  845. gradeVo.setCount(genderMap.get(GenderDictionaryEnum.MALE.getCode()).intValue());
  846. }
  847. if(genderMap.get(GenderDictionaryEnum.FEMALE.getCode()) != null){
  848. gradeVo.setCount2(genderMap.get(GenderDictionaryEnum.FEMALE.getCode()).intValue());
  849. }
  850. gradeList.add(gradeVo);
  851. }
  852. Collections.reverse(gradeList);
  853. result.setGradeList(gradeList);
  854. Map<String, List<Map<String, Object>>> deptMap = list.stream().filter(x -> ObjectUtil.isNotNull(x.get("dept_name"))).collect(Collectors.groupingBy(x -> x.get("dept_name").toString()));
  855. List<ItemCount2Vo> deptList = new ArrayList<>();
  856. for (String deptName : deptMap.keySet()) {
  857. List<Map<String, Object>> deptDataList = deptMap.get(deptName);
  858. Map<String, Long> genderMap = deptDataList.stream().filter(x -> ObjectUtil.isNotNull(x.get("gender"))).collect(Collectors.groupingBy(x -> x.get("gender").toString(), Collectors.counting()));
  859. ItemCount2Vo deptVo = new ItemCount2Vo();
  860. deptVo.setItem(deptName);
  861. if(genderMap.get(GenderDictionaryEnum.MALE.getCode()) != null){
  862. deptVo.setCount(genderMap.get(GenderDictionaryEnum.MALE.getCode()).intValue());
  863. }
  864. if(genderMap.get(GenderDictionaryEnum.FEMALE.getCode()) != null){
  865. deptVo.setCount2(genderMap.get(GenderDictionaryEnum.FEMALE.getCode()).intValue());
  866. }
  867. deptList.add(deptVo);
  868. }
  869. result.setDeptList(deptList);
  870. return RT.ok(result);
  871. }
  872. }