| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- package com.kingdee.eas.custom.szpgm.osf.service;
- import com.kingdee.bos.BOSException;
- import com.kingdee.bos.Context;
- import com.kingdee.bos.bsf.service.app.IHRMsfService;
- import com.kingdee.eas.common.EASBizException;
- import com.kingdee.eas.util.app.DbUtil;
- import com.kingdee.jdbc.rowset.IRowSet;
- import org.apache.commons.lang3.StringUtils;
- import java.text.SimpleDateFormat;
- import java.util.*;
- /**
- * 员工兼职信息查询OSF服务
- * <p>
- * 实现 {@link IHRMsfService} 接口,提供员工兼职信息的分页查询功能。
- * 支持按员工编号(精确)、最后修改时间进行过滤筛选。
- * 同一员工存在多个上级时,会将上级ID合并到一个列表中返回。
- * </p>
- *
- * <h3>关联数据表</h3>
- * <ul>
- * <li><b>T_HR_PluralityAddBizBillEntry</b>(pae)—— 员工加入兼职单分录表,主表</li>
- * <li><b>T_HR_PluralityAddBizBill</b>(pa)—— 员工加入兼职单表,获取审批状态</li>
- * <li><b>T_HR_PluralityDelBizBillentry</b>(pde)—— 员工移除兼职单分录表,获取结束日期</li>
- * <li><b>T_HR_PluralityDelBizBill</b>(pd)—— 员工移除兼职单表,获取移除审批状态</li>
- * <li><b>t_org_position</b>(pos)—— 组织岗位表,用于关联上级</li>
- * <li><b>T_HR_EMPPOSTEXPERIENCEHIS</b>(phis)—— 岗位任职历史表,取当前上级</li>
- * </ul>
- *
- * <h3>入参说明</h3>
- * <ul>
- * <li><b>modifyDate</b>(String,可选)—— 最后修改日期(格式yyyy-MM-dd),筛选该日期之后修改的兼职记录</li>
- * <li><b>personid</b>(String,可选)—— 员工编号/ID,精确匹配</li>
- * <li><b>page</b>(int/String,可选,默认1)—— 页码</li>
- * <li><b>size</b>(int/String,可选,默认100,上限1000)—— 每页条数</li>
- * </ul>
- *
- * <h3>返回结果</h3>
- * <pre>{@code
- * {
- * "msg": "成功",
- * "code": "200",
- * "page": 1,
- * "size": 100,
- * "data": [{
- * "personid": "员工ID",
- * "startDate": "兼职开始日期(yyyy-MM-dd)",
- * "endDate": "兼职结束日期(yyyy-MM-dd),未结束则为2199-12-31",
- * "orgid": "兼职组织ID",
- * "posid": "兼职岗位ID",
- * "leader": ["上级ID列表"],
- * "description": "兼职备注"
- * }]
- * }
- * }</pre>
- *
- * <h3>业务规则</h3>
- * <ul>
- * <li>只查询加入兼职单审批通过的记录(pa.fbillstate=3)</li>
- * <li>兼职结束日期:只有移除兼职单审批通过(pd.fbillstate=3)时才取实际结束日期,否则返回"2199-12-31"表示未结束</li>
- * </ul>
- *
- * @author szpgm
- * @since 2026/07/02
- */
- public class GetPluralityInfoOsfService implements IHRMsfService {
- /**
- * 处理员工兼职信息查询请求
- *
- * @param context EAS上下文对象,用于执行数据库查询
- * @param map 入参Map,包含过滤条件和分页参数
- * @return Map 包含查询结果、状态码和分页信息
- * @throws EASBizException 业务异常
- * @throws BOSException 平台异常
- */
- @Override
- public Object process(Context context, Map map) throws EASBizException, BOSException {
- // 返回结果容器
- Map<String, Object> result = new HashMap<String, Object>();
- List<Map<String, Object>> list = new ArrayList<>();
- // ==================== 入参解析 ====================
- // 最后修改日期(格式:yyyy-MM-dd),同时检查加入兼职表和移除兼职表
- String modifyDate = (String) map.get("modifyDate");
- // 员工ID(精确匹配)
- String code = (String) map.get("personid");
- // 每页条数(默认100,上限1000)
- int maxSize = 1000;
- int size = 100;
- if (map.get("size") != null) {
- if (map.get("size") instanceof Integer) {
- size = (int) map.get("size");
- } else if (map.get("size") instanceof String) {
- size = Integer.parseInt((String) map.get("size"));
- }
- size = Math.min(maxSize, size);
- }
- // 页码(默认1)
- int page = 1;
- if (map.get("page") != null) {
- if (map.get("page") instanceof Integer) {
- page = (int) map.get("page");
- } else if (map.get("page") instanceof String) {
- page = Integer.parseInt((String) map.get("page"));
- }
- }
- // ==================== 查询数据 ====================
- try {
- // 初始化成功响应
- result.put("msg", "成功");
- result.put("code", "200");
- result.put("page", page);
- result.put("size", size);
- result.put("data", list);
- // 构建基础SQL,动态追加过滤条件
- StringBuilder sql = getSql();
- // SQL参数列表(与?占位符一一对应)
- List<Object> paramArr = new ArrayList<>();
- // 修改日期过滤:加入兼职单或移除兼职单的最后修改时间 >= 指定日期
- if (StringUtils.isNotBlank(modifyDate)) {
- sql.append(" and (pa.flastupdatetime >= ? or pd.flastupdatetime >= ?) ");
- paramArr.add(modifyDate);
- paramArr.add(modifyDate);
- }
- // 员工编号/ID精确匹配
- if (StringUtils.isNotBlank(code)) {
- sql.append(" and pae.fpersonid = ? ");
- paramArr.add(code);
- }
- // 分页:LIMIT 返回条数 OFFSET 跳过条数
- sql.append(" LIMIT ? OFFSET ? ");
- paramArr.add(size);
- paramArr.add(((page - 1) * size));
- // 执行SQL查询
- IRowSet rs = DbUtil.executeQuery(context, sql.toString(), paramArr.toArray());
- // 以员工ID为key的Map,用于合并同一员工的多条记录(一个员工可能有多个上级)
- Map<String, Map<String, Object>> maps = new HashMap<>();
- // 日期格式化器(yyyy-MM-dd)
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
- // 遍历结果集,将同一员工的多行数据合并为一条记录
- while (rs.next()) {
- String id = rs.getString("personid");
- Map<String, Object> param = maps.get(id);
- // 首次遇到该员工时,初始化记录并创建上级ID列表
- if (null == param) {
- param = new HashMap<>();
- List<String> leaderIds = new ArrayList<>();
- param.put("leader", leaderIds);
- maps.put(id, param);
- }
- // 收集该员工的所有上级ID(多行数据的共同字段会覆盖,但值相同)
- List<String> leader = (List<String>) param.get("leader");
- leader.add(rs.getString("leader"));
- // ---- 员工基本信息 ----
- // 员工ID
- param.put("personid", id);
- // ---- 兼职日期(Date -> String 格式化) ----
- // 兼职开始日期
- Date startDate = rs.getDate("startDate");
- param.put("startDate", (null != startDate ? sdf.format(startDate) : null));
- // 移除兼职单审批状态(3表示审批通过)
- int pdbillstate = rs.getInt("pdbillstate");
- // 兼职结束日期:只有移除兼职单审批通过时才取实际结束日期,否则返回"2199-12-31"表示兼职未结束
- Date endDate = rs.getDate("endDate");
- param.put("endDate", (null != endDate && 3 == pdbillstate ? sdf.format(endDate) : "2199-12-31"));
- // ---- 组织与岗位 ----
- // 兼职所属组织ID
- param.put("orgid", rs.getString("orgid"));
- // 兼职岗位ID
- param.put("posid", rs.getString("posid"));
- // ---- 备注 ----
- // 兼职备注(来自加入兼职单分录)
- param.put("description", rs.getString("description"));
- }
- // 将合并后的员工列表写入返回结果
- result.put("data", maps.values());
- } catch (Exception e) {
- // 异常时返回错误信息
- e.printStackTrace();
- result.put("msg", e.getMessage());
- result.put("code", "500");
- }
- return result;
- }
- /**
- * 构建员工兼职信息查询的基础SQL
- * <p>
- * 从员工加入兼职单分录表(T_HR_PluralityAddBizBillEntry)出发,
- * LEFT JOIN 加入兼职单表获取审批状态,
- * LEFT JOIN 移除兼职单分录表和移除兼职单表获取结束日期和移除审批状态,
- * LEFT JOIN 组织岗位表和岗位任职历史表获取当前上级信息。
- * 只查询加入兼职单审批通过(pa.fbillstate=3)的记录。
- * </p>
- *
- * <h3>核心关联逻辑</h3>
- * <ol>
- * <li>pae → pa:关联加入兼职单,获取审批状态,WHERE条件限定 fbillstate=3(审批通过)</li>
- * <li>pae → pde:通过 fpersonid 关联移除兼职单分录,获取兼职结束日期</li>
- * <li>pde → pd:关联移除兼职单,获取移除审批状态,用于判断结束日期是否有效</li>
- * <li>pae → pos:通过 fpositionid 关联岗位表</li>
- * <li>pos → phis:通过 pos.fparentid(上级岗位ID)关联任职历史,取当前有效上级(fpositionenddate >= 2199-12-31)</li>
- * </ol>
- *
- * @return 包含完整SELECT语句的StringBuilder(以 WHERE pa.fbillstate=3 结尾,便于后续追加AND条件)
- */
- private static StringBuilder getSql() {
- StringBuilder sql = new StringBuilder();
- // /*dialect*/ 标记用于EAS平台识别SQL方言
- sql.append(" /*dialect*/ select ");
- // ===== SELECT 字段列表 =====
- sql.append(" pae.fpersonid personid, "); // 员工ID
- sql.append(" pae.fbizdate startDate, "); // 兼职开始日期
- sql.append(" pae.fpositionid posid, "); // 兼职岗位ID
- sql.append(" pae.fadminorgid orgid, "); // 兼职所属组织ID
- sql.append(" phis.fpersonid leader, "); // 上级员工ID(通过岗位任职历史关联)
- sql.append(" pae.fdescription description, "); // 加入兼职单备注
- sql.append(" pde.fdescription description2, "); // 移除兼职单备注(查询用,未返回给调用方)
- sql.append(" pde.fbizdate endDate, "); // 兼职结束日期(来自移除兼职单)
- sql.append(" pd.fbillstate pdbillstate "); // 移除兼职单审批状态(3:审批通过)
- // ===== FROM 子句及关联表 =====
- sql.append(" from ");
- sql.append(" T_HR_PluralityAddBizBillEntry pae "); // 员工加入兼职单分录表(主表)
- sql.append(" left join T_HR_PluralityAddBizBill pa on pae.fbillid = pa.fid "); // 加入兼职单表(获取审批状态)
- sql.append(" left join T_HR_PluralityDelBizBillentry pde on pde.FPERSONID = pae.fpersonid "); // 移除兼职单分录表(获取结束日期)
- sql.append(" left join T_HR_PluralityDelBizBill pd on pd.fid = pde.fbillid "); // 移除兼职单表(获取移除审批状态)
- sql.append(" left join t_org_position pos on pos.fid = pae.fpositionid "); // 组织岗位表(用于关联上级)
- sql.append(" left join T_HR_EMPPOSTEXPERIENCEHIS phis on phis.fpositionid = pos.fparentid "); // 岗位任职历史表(获取当前上级)
- sql.append(" and phis.fpositionenddate >= '2199-12-31 00:00:00'"); // 只取当前有效的任职记录
- // WHERE 条件:只查加入兼职单审批通过的记录,后续可动态追加 AND 条件
- sql.append(" where pa.fbillstate=3 ");
- return sql;
- }
- }
|