Bladeren bron

1.组织长名称相关

Tyx 2 weken geleden
bovenliggende
commit
62c8de7838

+ 59 - 0
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/hrmp/hbpm/opplugin/web/position/PositionDataProviderEx.java

@@ -0,0 +1,59 @@
+package nckd.jimin.jyyy.hr.hrmp.hbpm.opplugin.web.position;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.utils.ObjectUtils;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.mvc.list.ListDataProvider;
+import kd.bos.orm.query.QFilter;
+import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
+import kd.hrmp.hrpi.business.infrastructure.utils.QFilterUtil;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+/**
+ * Tyx 2025-06-19
+ * 岗位信息维护取数器
+ */
+public class PositionDataProviderEx extends ListDataProvider {
+
+    private static final Log log = LogFactory.getLog(PositionDataProviderEx.class);
+
+    @Override
+    public DynamicObjectCollection getData(int start, int limit) {
+        DynamicObjectCollection rows = super.getData(start, limit);
+        //为空直接返回
+        if(rows.isEmpty())
+            return rows;
+        //获取所有Id
+        List<Long> ids = rows.stream().map(dyx -> dyx.getLong("id")).collect(Collectors.toList());
+
+        Map<Long, List<DynamicObject>> map = PositionUtils.getAllUPersonOfPosition("1", ids);
+        if(map.isEmpty())
+            return rows;
+        for(DynamicObject position : rows) {
+            Long positionId = position.getLong("id");
+            //在岗数:
+            List<DynamicObject> personList = map.get(positionId);
+            if(personList == null)
+                continue;
+            //获取在岗数,排除兼职
+            List filterList = personList.stream().filter(dyx -> dyx.getString("postype.number").equals("1010_S")).collect(Collectors.toList());
+            position.set("nckd_personcount", filterList.size());
+            //人员姓名拼接:
+            String personName = personList.stream().map(dyx -> dyx.getString("postype.number").equals("1010_S") ? dyx.getString("person.name") : dyx.getString("person.name") + "(兼)")
+                    .collect(Collectors.joining(", "));
+            position.set("nckd_personname", personName);
+        }
+
+        return rows;
+    }
+
+
+
+
+
+}

+ 33 - 0
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/hrmp/hbpm/opplugin/web/position/PositionListEx.java

@@ -0,0 +1,33 @@
+package nckd.jimin.jyyy.hr.hrmp.hbpm.opplugin.web.position;
+
+import kd.bos.entity.datamodel.events.PackageDataEvent;
+import kd.bos.form.events.BeforeCreateListDataProviderArgs;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.bos.orm.query.QFilter;
+import kd.hrmp.hrpi.business.infrastructure.utils.QFilterUtil;
+import kd.sdk.plugin.Plugin;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Tyx 2025-06-19
+ * 岗位信息维护列表插件
+ * 查询各个岗位在岗人数和在岗人员姓名拼接,兼职情况后面新增(兼)
+ */
+public class PositionListEx extends AbstractListPlugin implements Plugin {
+
+    @Override
+    public void packageData(PackageDataEvent e) {
+        super.packageData(e);
+
+    }
+
+    @Override
+    public void beforeCreateListDataProvider(BeforeCreateListDataProviderArgs args) {
+        super.beforeCreateListDataProvider(args);
+        String appId = this.getView().getFormShowParameter().getAppId();
+        args.setListDataProvider(new PositionDataProviderEx());
+    }
+}

+ 41 - 0
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/hrmp/hbpm/opplugin/web/position/PositionUtils.java

@@ -0,0 +1,41 @@
+package nckd.jimin.jyyy.hr.hrmp.hbpm.opplugin.web.position;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.orm.query.QFilter;
+import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
+import kd.hrmp.hrpi.business.infrastructure.utils.QFilterUtil;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class PositionUtils {
+    public static final HRBaseServiceHelper depempServiceHelper = new HRBaseServiceHelper("hrpi_depemp");
+
+    /**
+     * 获取岗位下人员
+     * @param posType 1:所有类型
+     * @param positionIds
+     * @return Map key = 岗位Id, value = 企业人Dyn
+     */
+    public static Map<Long, List<DynamicObject>> getAllUPersonOfPosition(String posType, List<Long> positionIds) {
+        Map<Long, DynamicObject> personMap = new HashMap(16);
+        QFilter orgFilter = new QFilter("position.id", "in", positionIds);
+        orgFilter.and(new QFilter("businessstatus", "=", "1"));
+        if (!"1".equals(posType)) {
+            orgFilter.and(new QFilter("postype.number", "=", posType));
+        }
+        String selectFields = "person.id,person.name,position.id,postype.number";
+        DynamicObject[] dynamicObjects = depempServiceHelper.queryOriginalArray(selectFields
+                ,new QFilter[]{orgFilter, QFilterUtil.getCurrentQf(), QFilterUtil.getDataStatusFilter(), QFilterUtil.getInitStatusFinish()});
+
+
+        List<DynamicObject> list = Arrays.stream(dynamicObjects).collect(Collectors.toList());
+        Map<Long, List<DynamicObject>> map = list.stream().collect(Collectors.groupingBy(dyx -> dyx.getLong("position.id")));
+        return map;
+    }
+
+}

+ 84 - 0
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/hspm/business/repository/ext/service/EmpReportPluginEx.java

@@ -0,0 +1,84 @@
+package nckd.jimin.jyyy.hr.hspm.business.repository.ext.service;
+
+import kd.bos.algo.DataSet;
+import kd.bos.db.DB;
+import kd.bos.db.DBRoute;
+import kd.bos.entity.report.FilterInfo;
+import kd.bos.entity.report.FilterItemInfo;
+import kd.bos.exception.ErrorCode;
+import kd.bos.exception.KDBizException;
+import kd.bos.mservice.extreport.dataset.datasource.generic.runtimemodel.JoinType;
+import kd.bos.orm.query.QFilter;
+import kd.hr.hbp.common.util.HRDateTimeUtils;
+import kd.sdk.hr.hspm.business.repository.ext.service.IEmpReportExtService;
+import kd.sdk.hr.hspm.common.ext.file.EmpReportExtCalculateDTO;
+import kd.sdk.hr.hspm.common.ext.file.EmpReportExtQueryFieldsDTO;
+import kd.sdk.hr.hspm.common.ext.file.EmpReportExtReletionFilterDTO;
+import kd.wtc.wtbs.common.util.third.collect.Lists;
+
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Set;
+
+public class EmpReportPluginEx implements IEmpReportExtService {
+
+    @Override
+    public void addExtReletionFilter(EmpReportExtReletionFilterDTO empReportExtReletionFilterDTO) {
+        // 查询日期过滤
+        Date queryDate = getQueryDate(empReportExtReletionFilterDTO.getFilterInfo());
+        // 开始日期 <= 查询日期 && 结束日期 >= 查询日期
+    }
+
+    /**
+     * 获取查询日期
+     *
+     * @param filterInfo filterInfo
+     * @return 查询日期
+     */
+    public static Date getQueryDate(FilterInfo filterInfo) {
+        // 查询日期
+        FilterItemInfo itemInfo = filterInfo.getFilterItem("date");
+        Date queryDate = (Date) itemInfo.getValue();
+        if(queryDate == null) {
+            // 默认查询当前日期
+            queryDate = new Date();
+        }
+        // 日期去除时分秒
+        try {
+            queryDate = HRDateTimeUtils.parseDate(HRDateTimeUtils.format(queryDate), "yyyy-MM-dd");
+        } catch (ParseException e) {
+            throw new KDBizException(e, new ErrorCode("", "BaselocationExtService queryDate format error."));
+        }
+        return queryDate;
+    }
+
+    @Override
+    public void addExtQueryFields(EmpReportExtQueryFieldsDTO empReportExtQueryFieldsDTO) {
+        // 添加用于计算时存在花名册查询配置实体上的查询字段
+        Set<String> queryFieldSet = empReportExtQueryFieldsDTO.getQueryFieldSet();
+        queryFieldSet.add("TOTO_COLUMN");
+    }
+
+    @Override
+    public DataSet addExtCalculate(EmpReportExtCalculateDTO empReportExtCalculateDTO) {
+        // 获取dataset
+        DataSet dataSet = empReportExtCalculateDTO.getDataSet();
+        // 获取查询字段
+        Set<String> queryFieldSet = empReportExtCalculateDTO.getQueryFieldSet();
+        queryFieldSet.remove("hrpi_pernontsprop.description");
+        String[] array = queryFieldSet.toArray(new String[queryFieldSet.size()]);
+        // 对dataset结果集添加计算函数
+
+        String sql = "select forgid,substring(ffullname,4,length(ffullname)) as \"hrpi_pernontsprop.description\" \n" +
+                "from t_org_structure where fviewid = '1'";
+        DataSet longNamedataSet = DB.queryDataSet(this.getClass().getName(), DBRoute.of("sys"), sql);
+
+        DataSet ResultDataSet = dataSet.leftJoin(longNamedataSet).on("hrpi_empposorgrel.adminorg.boid","forgid")
+                .select(array, new String[]{"hrpi_pernontsprop.description"}).finish();
+
+        // 返回dataset,并将计算后的dataset设置到参数中,方便后续的二开插件使用
+        empReportExtCalculateDTO.setDataSet(ResultDataSet);
+        return ResultDataSet;
+    }
+
+}

+ 42 - 0
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/hspm/formplugin/web/reform/file/web/manage/FileManageReformEmpPosListPluginEx.java

@@ -0,0 +1,42 @@
+package nckd.jimin.jyyy.hr.hspm.formplugin.web.reform.file.web.manage;
+
+import kd.bos.base.AbstractBasePlugIn;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.datamodel.events.IDataModelListener;
+import kd.bos.entity.datamodel.events.PackageDataEvent;
+import kd.bos.form.control.Label;
+import kd.bos.list.events.ListRowClickListener;
+import kd.hr.haos.business.servicehelper.OrgBatchBillHelper;
+import kd.hr.hbp.formplugin.web.HRDataBaseList;
+import kd.sdk.plugin.Plugin;
+
+import java.util.Date;
+import java.util.EventObject;
+
+/**
+ * Tyx 2025-06-19
+ * 任职经历卡片新增组织长名称
+ * hspm_empposorgrel_reform
+ */
+public class FileManageReformEmpPosListPluginEx extends HRDataBaseList implements ListRowClickListener, IDataModelListener {
+
+    @Override
+    public void packageData(PackageDataEvent e) {
+        super.packageData(e);
+        DynamicObject org = e.getRowData();
+        if("company.name".equals(e.getColKey())) {
+            Long orgId = org.getLong("adminorg.id");
+            Date date = new Date();
+            String orgLongName = OrgBatchBillHelper.getOrgLongName(orgId, date, null);
+            org.set("description", orgLongName.replace("集团_", ""));
+        }
+    }
+
+    @Override
+    public void afterBindData(EventObject e) {
+        super.afterBindData(e);
+    }
+
+
+
+}

+ 10 - 0
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/swc/hsas/formplugin/web/AdjSalFileService.java

@@ -0,0 +1,10 @@
+package nckd.jimin.jyyy.hr.swc.hsas.formplugin.web;
+
+import kd.bos.dataentity.entity.DynamicObject;
+
+import java.util.List;
+import java.util.Map;
+
+public interface AdjSalFileService{
+    public abstract Map<String, String> execute (DynamicObject onBrdBillDyn);
+}

+ 21 - 0
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/swc/hsas/formplugin/web/impl/AdjSalFileServiceImpl.java

@@ -0,0 +1,21 @@
+package nckd.jimin.jyyy.hr.swc.hsas.formplugin.web.impl;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import nckd.jimin.jyyy.hr.swc.hsas.formplugin.web.AdjSalFileService;
+
+import java.util.Map;
+
+/**
+ * 新增定调薪信息微服务
+ * Tyx
+ * 2025-06-05
+ */
+public class AdjSalFileServiceImpl implements AdjSalFileService {
+    private static final Log log = LogFactory.getLog(AdjSalFileServiceImpl.class);
+    @Override
+    public Map<String, String> execute(DynamicObject onBrdBillDyn) {
+        return null;
+    }
+}

+ 128 - 0
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/tsrsc/plugin/api/MokaRedirectUrlApi.java

@@ -0,0 +1,128 @@
+package nckd.jimin.jyyy.hr.tsrsc.plugin.api;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.exception.KDException;
+import kd.bos.ext.ssc.util.DateUtil;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.openapi.common.custom.annotation.*;
+import kd.bos.openapi.common.result.CustomApiResult;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import nckd.jimin.jyyy.hr.tsrsc.plugin.util.MokaApiUtil;
+
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * Moka跳转金蝶:根据操作人邮箱返回对应跳转地址
+ * api编码:data/redirectUrl
+ * Tyx
+ * 2025-06-13
+ */
+@ApiController(value = "moka", desc = "Moka")
+@ApiMapping("/data")
+public class MokaRedirectUrlApi implements Serializable {
+    private static final Log log = LogFactory.getLog(MokaRedirectUrlApi.class);
+
+    /**
+     * 金蝶环境地址
+     */
+    private String kingdeeUrl = System.getProperty("domain.contextUrl") + "/";
+
+
+    @ApiPostMapping(value = "/redirectUrl", desc = "根据操作人邮箱返回对应跳转地址")
+    public CustomApiResult<@ApiResponseBody JSONObject> pushRedirectUrl(
+            @ApiParam(value = "候选人信息", required = true) JSONObject data
+    ) {
+        try {
+            // 操作人邮箱
+            String email = data.getJSONObject("operator").getString("email");
+            if (email == null) {
+                log.error("MokaRedirectUrlApi:入参邮箱为空");
+                throw new KDException("入参邮箱为空");
+            }
+            JSONObject responseJson = getKingdeeToken();
+
+            String accessToken = "";
+            if ("0".equals(responseJson.getString("errorCode"))) {
+                accessToken = responseJson.getJSONObject("data").getString("access_token");
+            } else {
+                log.error("MokaRedirectUrlApi:获取星瀚accessToken失败!{}", responseJson.getString("message"));
+                throw new KDException("获取星瀚accessToken失败!" + responseJson.getString("message"));
+            }
+
+            // 新建表,将token和邮箱属性落库,并建立token和邮箱的映射关系,后续需根据token查询邮箱。
+            DynamicObject mokaToken = BusinessDataServiceHelper.newDynamicObject("nckd_mokatoken");
+            mokaToken.set("nckd_email", email);
+            mokaToken.set("nckd_accesstoken", accessToken);
+            SaveServiceHelper.save(new DynamicObject[]{mokaToken});
+
+            // 拼接返回的url
+            String redirectUrl = kingdeeUrl +
+                    "?formId=pc_main_console" +
+                    "&appNumber=tsrsc" +
+                    "&token=" + accessToken +
+                    "&thirdAppType=moka";
+
+            /*
+             *{
+             *     "code": 200,
+             *     "flag": false,
+             *     "message": "成功111",
+             *     "redirectUrl": {
+             *         "mobileUrl": "http://www.baidu.com?name=1",
+             *         "pcUrl": "http://www.baidu.com?name=1"
+             *     }
+             * }
+             *
+             */
+
+            JSONObject responeData = new JSONObject()
+                    .fluentPut("code", 200)
+                    .fluentPut("flag", false)
+                    .fluentPut("message", "成功111")
+                    .fluentPut("redirectUrl", new JSONObject()
+                            .fluentPut("mobileUrl", "")
+                            .fluentPut("pcUrl", redirectUrl)
+                    );
+
+            return CustomApiResult.success(responeData);
+        } catch (Exception e) {
+            // 出现报错,返回默认的url
+            log.error("MokaRedirectUrlApi出现异常:{}", e.getMessage());
+            return CustomApiResult.success(new JSONObject()
+                    .fluentPut("code", 200)
+                    .fluentPut("flag", false)
+                    .fluentPut("message", "成功111")
+                    .fluentPut("redirectUrl", new JSONObject()
+                            .fluentPut("mobileUrl", "")
+                            .fluentPut("pcUrl", kingdeeUrl)
+                    ));
+        }
+    }
+
+    private JSONObject getKingdeeToken() throws IOException {
+        // 获取该操作人的token
+        String url = kingdeeUrl + "kapi/oauth2/getToken";
+        //
+        JSONObject body = new JSONObject()
+                .fluentPut("client_id", MokaApiUtil.getParamValue("moka_client_id", "Moka_tomoka"))
+                .fluentPut("client_secret", MokaApiUtil.getParamValue("moka_client_secret", "1q;E28%E@zY*Mo9y"))
+                .fluentPut("username", MokaApiUtil.getParamValue("moka_username", "xinghanduiwaitongyongjiekouzhang"))
+                .fluentPut("accountId", RequestContext.get().getAccountId())
+                .fluentPut("nonce", UUID.randomUUID())
+                .fluentPut("timestamp", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"))
+                .fluentPut("language", "zh_CN");
+
+        return MokaApiUtil.doKingdeePostByHttpClient(url, body);
+    }
+
+
+}

+ 89 - 0
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/tsrsc/plugin/thirdapp/auth/MokaThirdAppAuthtication.java

@@ -0,0 +1,89 @@
+package nckd.jimin.jyyy.hr.tsrsc.plugin.thirdapp.auth;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dc.api.model.Account;
+import kd.bos.entity.plugin.support.util.StringUtils;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.login.thirdauth.app.AppAuthResult;
+import kd.bos.login.thirdauth.app.ThirdAppAuthtication;
+import kd.bos.login.thirdauth.app.UserType;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import nckd.jimin.jyyy.hr.tsrsc.plugin.util.MokaApiUtil;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Moka第三方单点登陆
+ *
+ * @author :liuxiao
+ * @since :Created in 11:35 2024/12/24
+ */
+public class MokaThirdAppAuthtication extends ThirdAppAuthtication {
+    private static final Log LOG = LogFactory.getLog(MokaThirdAppAuthtication.class);
+
+    /**
+     * 检查请求url是否需要本插件认证,如果是返回true,否返回false
+     */
+    @Override
+    public boolean isNeedHandle(HttpServletRequest request, Account account) {
+        // 是否需要通过第三方办公APP插件认证
+        boolean isNeed = false;
+        // 第三方用户身份标识 参数名根据实际情况而定
+        String token = request.getParameter("token");
+        LOG.info("MokaThirdAppAuthtication.isNeedHandle.token:{}", token);
+        // 请求 url携带的判断第三方办公APP认证插件类型  示例:金蝶云使用jindieyun 可自行定义传参用于判断
+        String thirdAppType = request.getParameter("thirdAppType");
+        LOG.info("MokaThirdAppAuthtication.isNeedHandle.thirdAppType:{}", thirdAppType);
+        if (!StringUtils.isEmpty(token) && "moka".equals(thirdAppType)) {
+            isNeed = true;
+        }
+        return isNeed;
+    }
+
+    /**
+     * 实现苍穹调用第三方办公APP系统的相关接口完成认证,返回认证结果。
+     */
+    @Override
+    public AppAuthResult appAuthtication(HttpServletRequest request, Account account) {
+        AppAuthResult result = new AppAuthResult();
+        result.setSucceed(false);
+        //第三方用户身份标识 参数名根据实际情况而定
+        String token = request.getParameter("token");
+        // 根据token查email
+        DynamicObject tokenObj = BusinessDataServiceHelper.loadSingle(
+                "nckd_mokatoken",
+                new QFilter[]{
+                        // 第三方数据id
+                        new QFilter("nckd_accesstoken", QCP.equals, token),
+                        // 创建时间:5分钟内
+                        new QFilter("createtime", QCP.large_equals, MokaApiUtil.offsetMinute(-5)),
+                }
+        );
+        if (tokenObj == null) {
+            return result;
+        }
+        String email = tokenObj.getString("nckd_email");
+        LOG.info("MokaThirdAppAuthtication.appAuthtication.email:{}", email);
+        // 系统中是否存在该邮箱用户
+        DynamicObject user = BusinessDataServiceHelper.loadSingle(
+                "bos_user",
+                new QFilter[]{
+                        // 操作人邮箱
+                        new QFilter("email", QCP.equals, email),
+                }
+        );
+        if (user == null) {
+            return result;
+        }
+
+        result.setSucceed(true);
+        // 用户标识,包括手机号、邮箱、用户名
+        result.setUserFlag(email);
+        // 用户类型 枚举类UserType 对应用户标识
+        result.setUserType(UserType.EMAIL);
+        return result;
+    }
+}