AttendanceDayStatListHandler.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. package com.kingdee.eas.custom.ats.handler;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.kingdee.bos.BOSException;
  4. import com.kingdee.bos.ctrl.swing.StringUtils;
  5. import com.kingdee.bos.metadata.entity.FilterInfo;
  6. import com.kingdee.bos.metadata.entity.FilterItemCollection;
  7. import com.kingdee.bos.metadata.entity.FilterItemInfo;
  8. import com.kingdee.bos.metadata.query.util.CompareType;
  9. import com.kingdee.jdbc.rowset.IRowSet;
  10. import com.kingdee.shr.base.syssetting.context.SHRContext;
  11. import com.kingdee.shr.base.syssetting.exception.SHRWebException;
  12. import com.kingdee.shr.base.syssetting.json.GridDataEntity;
  13. import com.kingdee.shr.base.syssetting.web.handler.ListHandler;
  14. import com.kingdee.util.DateTimeUtils;
  15. import org.apache.log4j.Logger;
  16. import javax.servlet.http.HttpServletRequest;
  17. import javax.servlet.http.HttpServletResponse;
  18. import java.sql.SQLException;
  19. import java.util.*;
  20. /**
  21. * 类名称: AttendanceDayStatListHandler
  22. * 功能描述: 考勤日统计列表处理器
  23. * 创建日期: 2026-05-26 14:54
  24. * 作 者: 青梧
  25. * 版 本: 1.0
  26. */
  27. public class AttendanceDayStatListHandler extends ListHandler {
  28. private static Logger logger = Logger.getLogger(AttendanceDayStatListHandler.class);
  29. @Override
  30. protected void afterGetListData(HttpServletRequest request, HttpServletResponse response, GridDataEntity gridDataEntity) throws SHRWebException {
  31. List rows = gridDataEntity.getRows();
  32. // 获取过滤条件中的考勤日期
  33. String fastFilterItems = request.getParameter("fastFilterItems");
  34. logger.error("fastFilterItems---" + fastFilterItems);
  35. String attendanceDate = null;
  36. if (!StringUtils.isEmpty(fastFilterItems)) {
  37. try {
  38. JSONObject filterJson = JSONObject.parseObject(fastFilterItems);
  39. // 尝试多种方式获取日期值
  40. if (filterJson.containsKey("attendanceDate")) {
  41. Object attendanceDateObj = filterJson.get("attendanceDate");
  42. // 如果是JSONObject,尝试获取date或values字段
  43. if (attendanceDateObj instanceof JSONObject) {
  44. JSONObject dateObj = (JSONObject) attendanceDateObj;
  45. // 先尝试直接获取date字段
  46. if (dateObj.containsKey("values")) {
  47. Object valuesObj = dateObj.get("values");
  48. if (valuesObj instanceof JSONObject) {
  49. JSONObject values = (JSONObject) valuesObj;
  50. if (values.containsKey("date")) {
  51. attendanceDate = values.getString("date");
  52. }
  53. } else if (valuesObj instanceof String) {
  54. attendanceDate = (String) valuesObj;
  55. }
  56. }
  57. }
  58. // 如果是字符串,直接使用
  59. else if (attendanceDateObj instanceof String) {
  60. attendanceDate = (String) attendanceDateObj;
  61. }
  62. }
  63. } catch (Exception e) {
  64. logger.error("解析考勤日期失败", e);
  65. }
  66. }
  67. if (StringUtils.isEmpty(attendanceDate)) {
  68. // 如果没有传入日期,默认使用当天
  69. attendanceDate = DateTimeUtils.format(new Date(), "yyyy-MM-dd");
  70. }
  71. logger.error("查询考勤日期: " + attendanceDate);
  72. try {
  73. // 查询考勤数据
  74. Map<String, List<Map<String, Object>>> orgDataMap = getAttendanceData(attendanceDate);
  75. // 遍历每一行数据,填充统计信息
  76. for (int i = 0; i < rows.size(); i++) {
  77. Map map = (Map) rows.get(i);
  78. String orgId = map.get("id").toString().trim();
  79. // 获取该组织的考勤人员列表
  80. List<Map<String, Object>> personList = orgDataMap.get(orgId);
  81. int shouldAttendCount = 0; // 应出勤人数
  82. int actualAttendCount = 0; // 实际出勤人数
  83. int absentCount = 0; // 未出勤人数
  84. List<String> shouldAttendNames = new ArrayList<>(); // 应出勤人员名单
  85. List<String> actualAttendNames = new ArrayList<>(); // 实际出勤人员名单
  86. List<String> absentNames = new ArrayList<>(); // 未出勤人员名单
  87. if (personList != null && !personList.isEmpty()) {
  88. for (Map<String, Object> personData : personList) {
  89. Integer s50 = (Integer) personData.get("s50");
  90. Integer s51 = (Integer) personData.get("s51");
  91. String personName = (String) personData.get("personName");
  92. // s50=1 表示应出勤
  93. if (s50 != null && s50 == 1) {
  94. shouldAttendCount++;
  95. if (personName != null) {
  96. shouldAttendNames.add(personName);
  97. }
  98. // s51=1 表示实际出勤
  99. if (s51 != null && s51 == 1) {
  100. actualAttendCount++;
  101. if (personName != null) {
  102. actualAttendNames.add(personName);
  103. }
  104. } else {
  105. // s51=0 或 NULL 表示未出勤
  106. absentCount++;
  107. if (personName != null) {
  108. absentNames.add(personName);
  109. }
  110. }
  111. }
  112. }
  113. }
  114. // 将统计数据放入返回结果中
  115. map.put("shouldAttendCount", shouldAttendCount);
  116. map.put("actualAttendCount", actualAttendCount);
  117. map.put("absentCount", absentCount);
  118. map.put("shouldAttendNames", String.join(",", shouldAttendNames));
  119. map.put("actualAttendNames", String.join(",", actualAttendNames));
  120. map.put("absentNames", String.join(",", absentNames));
  121. }
  122. } catch (Exception e) {
  123. logger.error("查询考勤统计数据失败", e);
  124. throw new SHRWebException("查询考勤统计数据失败: " + e.getMessage());
  125. }
  126. }
  127. /**
  128. * 重写快速过滤方法,处理adminOrg和attendanceDate过滤条件
  129. * 1. 移除 attendanceDate (不用于组织查询)
  130. * 2. 将 adminOrg 转换为 id (用于组织过滤)
  131. */
  132. @Override
  133. protected FilterInfo getFastFilter(HttpServletRequest request) throws SHRWebException {
  134. FilterInfo filterInfo = new FilterInfo();
  135. FilterItemCollection filterItems = filterInfo.getFilterItems();
  136. try {
  137. String fastFilterItems = request.getParameter("fastFilterItems");
  138. if (!StringUtils.isEmpty(fastFilterItems)) {
  139. JSONObject filterJson = JSONObject.parseObject(fastFilterItems);
  140. // 处理adminOrg过滤条件:将 adminOrg 转换为 id
  141. if (filterJson.containsKey("adminOrg")) {
  142. Object adminOrgObj = filterJson.get("adminOrg");
  143. if (adminOrgObj instanceof JSONObject) {
  144. JSONObject adminOrgJson = (JSONObject) adminOrgObj;
  145. String orgId = adminOrgJson.getString("values");
  146. Boolean isIncludeSub = adminOrgJson.getBoolean("isIncludeSub");
  147. isIncludeSub = true;
  148. if (!StringUtils.isEmpty(orgId)) {
  149. logger.info("处理adminOrg过滤条件,组织ID: " + orgId + ", 包含下级: " + isIncludeSub);
  150. // 添加id过滤条件
  151. if (isIncludeSub != null && isIncludeSub) {
  152. // 包含下级:使用 longNumber LIKE 查询当前组织及所有下级组织
  153. // 需要获取该组织的longNumber
  154. try {
  155. String longNumber = getOrgLongNumber(orgId);
  156. if (longNumber != null) {
  157. filterItems.add(new FilterItemInfo("longNumber", longNumber + "%", CompareType.LIKE));
  158. logger.info("包含当前组织及下级组织,使用longNumber: " + longNumber);
  159. } else {
  160. // 如果获取不到longNumber,使用id精确匹配
  161. filterItems.add(new FilterItemInfo("id", orgId));
  162. }
  163. } catch (Exception e) {
  164. logger.error("获取组织longNumber失败", e);
  165. filterItems.add(new FilterItemInfo("id", orgId));
  166. }
  167. } else {
  168. // 不包含下级:精确匹配
  169. filterItems.add(new FilterItemInfo("id", orgId));
  170. }
  171. }
  172. }
  173. }
  174. }
  175. } catch (Exception e) {
  176. logger.error("处理fastFilterItems失败", e);
  177. }
  178. return filterInfo;
  179. }
  180. /**
  181. * 查询考勤数据
  182. *
  183. * @param attendanceDate 考勤日期 yyyy-MM-dd
  184. * @return Map<组织ID, 人员数据列表>
  185. */
  186. public Map<String, List<Map<String, Object>>> getAttendanceData(String attendanceDate) throws SQLException, BOSException {
  187. Map<String, List<Map<String, Object>>> resultMap = new HashMap<>();
  188. StringBuilder sql = new StringBuilder();
  189. sql.append("SELECT result.s50, result.s51, person.fName_l2 AS personName, result.FADMINORGUNITID ");
  190. sql.append("FROM T_HR_ATS_AttendanceResult result ");
  191. sql.append("LEFT JOIN T_BD_PERSON person ON person.fid = result.FPROPOSERID ");
  192. sql.append("WHERE result.fattencedate = {ts '").append(attendanceDate).append(" 00:00:00'} ");
  193. sql.append("AND result.s50 = 1 ");
  194. logger.error("考勤统计SQL: " + sql.toString());
  195. IRowSet rs = com.kingdee.eas.util.app.DbUtil.executeQuery(SHRContext.getInstance().getContext(), sql.toString());
  196. while (rs.next()) {
  197. String orgId = rs.getString("FADMINORGUNITID");
  198. if (orgId == null || orgId.trim().isEmpty()) {
  199. continue;
  200. }
  201. Map<String, Object> personData = new HashMap<>();
  202. personData.put("s50", rs.getInt("s50"));
  203. personData.put("s51", rs.getInt("s51"));
  204. personData.put("personName", rs.getString("personName"));
  205. if (resultMap.containsKey(orgId)) {
  206. resultMap.get(orgId).add(personData);
  207. } else {
  208. List<Map<String, Object>> personList = new ArrayList<>();
  209. personList.add(personData);
  210. resultMap.put(orgId, personList);
  211. }
  212. }
  213. return resultMap;
  214. }
  215. /**
  216. * 获取组织的longNumber
  217. *
  218. * @param orgId 组织ID
  219. * @return longNumber
  220. */
  221. private String getOrgLongNumber(String orgId) throws SQLException, BOSException {
  222. StringBuilder sql = new StringBuilder();
  223. sql.append("SELECT FLONGNUMBER FROM T_ORG_ADMIN WHERE FID = '").append(orgId).append("' ");
  224. logger.info("查询组织longNumber SQL: " + sql.toString());
  225. IRowSet rs = com.kingdee.eas.util.app.DbUtil.executeQuery(SHRContext.getInstance().getContext(), sql.toString());
  226. if (rs.next()) {
  227. return rs.getString("FLONGNUMBER");
  228. }
  229. return null;
  230. }
  231. }