|
|
@@ -0,0 +1,279 @@
|
|
|
+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} 接口,提供员工综合信息的分页查询功能。
|
|
|
+ * 支持按员工名称(左模糊)、员工编号(精确)、最后修改时间进行过滤筛选。
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * <h3>关联数据表</h3>
|
|
|
+ * <ul>
|
|
|
+ * <li><b>t_bd_person</b>(pe)—— 员工基础信息表,主表</li>
|
|
|
+ * <li><b>T_HR_BDEmployeeType</b>(ty)—— 用工关系类型表</li>
|
|
|
+ * <li><b>T_HR_PERSONCONTACTMETHOD</b>(pm)—— 员工联系方式表</li>
|
|
|
+ * <li><b>t_hr_personposition</b>(ppos)—— 员工岗位关联表</li>
|
|
|
+ * <li><b>t_org_position</b>(pos)—— 组织岗位表</li>
|
|
|
+ * <li><b>T_HR_EMPPOSTEXPERIENCEHIS</b>(phis)—— 岗位任职历史表,取当前上级</li>
|
|
|
+ * <li><b>t_pm_user</b>(puser)—— 用户账号表</li>
|
|
|
+ * </ul>
|
|
|
+ *
|
|
|
+ * <h3>入参说明</h3>
|
|
|
+ * <ul>
|
|
|
+ * <li><b>modifyDate</b>(String,可选)—— 最后修改日期(格式yyyy-MM-dd),筛选该日期之后修改的记录</li>
|
|
|
+ * <li><b>name</b>(String,可选)—— 员工名称,左模糊匹配</li>
|
|
|
+ * <li><b>code</b>(String,可选)—— 员工编号,精确匹配</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": [{
|
|
|
+ * "id": "员工FID",
|
|
|
+ * "code": "员工编码",
|
|
|
+ * "name": "员工名称",
|
|
|
+ * "idcardno": "身份证号",
|
|
|
+ * "tyname": "用工关系类型",
|
|
|
+ * "inservice": "是否在职(1或4为在职)",
|
|
|
+ * "gender": "性别(1男,2女)",
|
|
|
+ * "globalroaming": "区号",
|
|
|
+ * "ncell": "电话号码",
|
|
|
+ * "joindate": "入司日期",
|
|
|
+ * "orgid": "组织ID",
|
|
|
+ * "posid": "岗位ID",
|
|
|
+ * "leader": ["上级ID列表"],
|
|
|
+ * "userAccount": "登录账号",
|
|
|
+ * "officephone": "办公电话",
|
|
|
+ * "passportno": "护照号码"
|
|
|
+ * }]
|
|
|
+ * }
|
|
|
+ * }</pre>
|
|
|
+ *
|
|
|
+ * @author szpgm
|
|
|
+ * @since 2026/07/02
|
|
|
+ */
|
|
|
+public class GetEmpInfoOsfService 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");
|
|
|
+ // 员工名称(左模糊匹配)
|
|
|
+ String name = (String) map.get("name");
|
|
|
+ // 员工编号(精确匹配)
|
|
|
+ String code = (String) map.get("code");
|
|
|
+
|
|
|
+ // 每页条数(默认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 (pe.flastupdatetime >= ? or pm.flastupdatetime >= ?) ");
|
|
|
+ paramArr.add(modifyDate);
|
|
|
+ paramArr.add(modifyDate);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 员工名称左模糊匹配
|
|
|
+ if (StringUtils.isNotBlank(name)) {
|
|
|
+ sql.append(" and pe.fname_l2 like ? ");
|
|
|
+ paramArr.add(name + "%");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 员工编号精确匹配
|
|
|
+ if (StringUtils.isNotBlank(code)) {
|
|
|
+ sql.append(" and pe.fnumber = ? ");
|
|
|
+ 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("id");
|
|
|
+ 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("id", id);
|
|
|
+ // 员工编码
|
|
|
+ param.put("code", rs.getString("code"));
|
|
|
+ // 员工名称
|
|
|
+ param.put("name", rs.getString("name"));
|
|
|
+ // 身份证号码
|
|
|
+ param.put("idcardno", rs.getString("idcardno"));
|
|
|
+ // 用工关系类型名称
|
|
|
+ param.put("tyname", rs.getString("tyname"));
|
|
|
+ // 是否在职(1或4表示在职,其他值表示不在职)
|
|
|
+ param.put("inservice", rs.getString("inservice"));
|
|
|
+ // 性别(1:男,2:女)
|
|
|
+ param.put("gender", rs.getString("gender"));
|
|
|
+ // 国际区号
|
|
|
+ param.put("globalroaming", rs.getString("globalroaming"));
|
|
|
+ // 手机号码
|
|
|
+ param.put("ncell", rs.getString("ncell"));
|
|
|
+
|
|
|
+ // ---- 入司日期(Date -> String 格式化) ----
|
|
|
+ Date joindate = rs.getDate("joindate");
|
|
|
+ param.put("joindate", (null != joindate ? sdf.format(joindate) : null));
|
|
|
+
|
|
|
+ // ---- 组织与岗位 ----
|
|
|
+ // 所属组织ID
|
|
|
+ param.put("orgid", rs.getString("orgid"));
|
|
|
+ // 主岗位ID
|
|
|
+ param.put("posid", rs.getString("posid"));
|
|
|
+
|
|
|
+ // ---- 账号与联系方式 ----
|
|
|
+ // 员工登录账号
|
|
|
+ param.put("userAccount", rs.getString("userAccount"));
|
|
|
+ // 办公电话
|
|
|
+ param.put("officephone", rs.getString("officephone"));
|
|
|
+ // 护照号码
|
|
|
+ param.put("passportno", rs.getString("passportno"));
|
|
|
+ }
|
|
|
+ // 将合并后的员工列表写入返回结果
|
|
|
+ result.put("data", maps.values());
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 异常时返回错误信息
|
|
|
+ e.printStackTrace();
|
|
|
+ result.put("msg", e.getMessage());
|
|
|
+ result.put("code", "500");
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建员工信息查询的基础SQL
|
|
|
+ * <p>
|
|
|
+ * 从员工基础信息表出发,LEFT JOIN 用工关系类型、联系方式、岗位信息、
|
|
|
+ * 岗位任职历史、用户账号等关联表,获取员工的综合信息。
|
|
|
+ * 其中岗位任职历史通过 {@code fpositionenddate >= '2199-12-31'} 条件
|
|
|
+ * 取当前有效的上级记录。
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @return 包含完整SELECT语句的StringBuilder(以 WHERE 1=1 结尾,便于后续追加AND条件)
|
|
|
+ */
|
|
|
+ private static StringBuilder getSql() {
|
|
|
+ StringBuilder sql = new StringBuilder();
|
|
|
+ // /*dialect*/ 标记用于EAS平台识别SQL方言
|
|
|
+ sql.append(" /*dialect*/ select ");
|
|
|
+
|
|
|
+ // ===== SELECT 字段列表 =====
|
|
|
+ sql.append(" pe.fid id, "); // 员工FID
|
|
|
+ sql.append(" pe.fname_l2 \"name\", "); // 员工名称
|
|
|
+ sql.append(" pe.fnumber code, "); // 员工编码
|
|
|
+ sql.append(" pe.fidcardno idcardno, "); // 身份证号
|
|
|
+ sql.append(" ty.fname_l2 tyname, "); // 用工关系类型名称
|
|
|
+ sql.append(" ty.finservice inservice, "); // 是否在职标识
|
|
|
+ sql.append(" pe.fgender gender, "); // 性别
|
|
|
+ sql.append(" pm.fglobalroaming globalroaming, "); // 国际区号
|
|
|
+ sql.append(" pm.fncell ncell, "); // 手机号码
|
|
|
+ sql.append(" ppos.fjoindate joindate, "); // 入司日期
|
|
|
+ sql.append(" ppos.fpersondep orgid, "); // 所属组织ID
|
|
|
+ sql.append(" ppos.fprimarypositionid posid, "); // 主岗位ID
|
|
|
+ sql.append(" phis.fpersonid leader, "); // 上级员工ID
|
|
|
+ sql.append(" puser.fnumber userAccount, "); // 登录账号
|
|
|
+ sql.append(" pm.fofficephone officephone, "); // 办公电话
|
|
|
+ sql.append(" pe.fpassportno passportno "); // 护照号码
|
|
|
+
|
|
|
+ // ===== FROM 子句及关联表 =====
|
|
|
+ sql.append(" from ");
|
|
|
+ sql.append(" t_bd_person pe "); // 员工基础信息表(主表)
|
|
|
+ sql.append(" left join T_HR_BDEmployeeType ty on pe.femployeetypeid = ty.fid "); // 用工关系类型
|
|
|
+ sql.append(" left join T_HR_PERSONCONTACTMETHOD pm on pm.fpersonid = pe.fid "); // 联系方式
|
|
|
+ sql.append(" left join t_hr_personposition ppos on ppos.FPERSONID = pe.fid "); // 岗位关联
|
|
|
+ sql.append(" left join t_org_position pos on pos.fid = ppos.fprimarypositionid "); // 组织岗位(用于关联上级)
|
|
|
+ sql.append(" left join T_HR_EMPPOSTEXPERIENCEHIS phis on phis.fpositionid = pos.fparentid "); // 岗位任职历史
|
|
|
+ sql.append(" and phis.fpositionenddate >= '2199-12-31 00:00:00' "); // 只取当前有效的任职记录
|
|
|
+ sql.append(" left join t_pm_user puser on puser.FPERSONID = pe.fid "); // 用户登录账号
|
|
|
+
|
|
|
+ // WHERE 1=1 便于后续动态追加 AND 条件
|
|
|
+ sql.append(" where 1=1 ");
|
|
|
+
|
|
|
+ return sql;
|
|
|
+ }
|
|
|
+}
|