| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- package com.kingdee.eas.custom.perfweb.handler;
- import com.kingdee.bos.Context;
- import com.kingdee.bos.metadata.entity.*;
- import com.kingdee.bos.metadata.query.util.CompareType;
- import com.kingdee.eas.custom.perfweb.utils.FeishuMessageUtil;
- import com.kingdee.eas.custom.perfweb.utils.UrlParamUtil;
- import com.kingdee.eas.custom.perfweb.service.CenterPerfStatService;
- import com.kingdee.shr.base.syssetting.context.SHRContext;
- import com.kingdee.shr.base.syssetting.exception.SHRWebException;
- import com.kingdee.shr.base.syssetting.web.json.JSONUtils;
- import com.kingdee.shr.perfweb.app.base.evalplan.*;
- import com.kingdee.shr.perfweb.planexecute.handler.EvaResultSummaryManagerListHandler;
- import org.apache.commons.lang3.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.ui.ModelMap;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.util.*;
- /**
- * 类名称: EvaResultSummaryManagerListHandlerEx
- * 功能描述: 考核结果汇总列表发送飞书消息
- * 创建日期: 2026-06-15 10:54
- * 作 者: 青梧
- * 版 本: 1.0
- */
- public class EvaResultSummaryManagerListHandlerEx extends EvaResultSummaryManagerListHandler {
- private static final Logger logger = LoggerFactory.getLogger(EvaResultSummaryManagerListHandlerEx.class);
- /** 标品考核结果汇总 billState:3 = 已审批(审批通过) */
- private static final String BILL_STATE_AUDITED = "3";
- /**
- * 发送飞书消息按钮 Action 入口
- * <p>
- * 按前端勾选的每条考核结果,向对应<strong>被考核人本人</strong>各发一条飞书通知(勾选几条发几条)。
- * 发送前须校验:对应考核周期下全部「考核结果说明」均已审批通过(autoStatus = SPTG)。
- * 单条考核结果须已审批(billState = 3,与列表「绩效状态」一致)。消息正文见 {@link FeishuMessageUtil#buildEvaResultSummaryFeishuMessage}。
- */
- public void sendFeishuToLeadersAction(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) throws SHRWebException {
- Context ctx = SHRContext.getInstance().getContext();
- Map<String, Object> res = new HashMap<>();
- String billId = this.getBillId(request);
- if (StringUtils.isBlank(billId)) {
- res.put("result", "500");
- res.put("msg", "请先勾选需要发送消息的考核结果");
- JSONUtils.writeJson(response, res);
- return;
- }
- try {
- // 保留前端勾选顺序,每条 billId 对应一条发送
- List<String> selectedBillIds = parseSelectedBillIds(billId);
- if (selectedBillIds.isEmpty()) {
- res.put("result", "500");
- res.put("msg", "勾选的考核结果ID无效");
- JSONUtils.writeJson(response, res);
- return;
- }
- Map<String, EvaResultSummaryInfo> summaryById = loadSummaryByIds(ctx, selectedBillIds);
- if (summaryById.isEmpty()) {
- res.put("result", "500");
- res.put("msg", "未查询到勾选的考核结果数据");
- JSONUtils.writeJson(response, res);
- return;
- }
- Set<String> periodIds = collectPeriodIds(summaryById);
- for (String periodId : periodIds) {
- String blockMsg = CenterPerfStatService.validateAllDescriptionApprovedForNotify(ctx, periodId);
- if (blockMsg != null) {
- res.put("result", "500");
- res.put("msg", blockMsg);
- JSONUtils.writeJson(response, res);
- return;
- }
- }
- String pcurl = UrlParamUtil.buildPerfPortalFeishuMessageUrl();
- String appurl = pcurl;
- int successCount = 0;
- int skippedNotApproved = 0;
- int skippedNoPerson = 0;
- int skippedNotFound = 0;
- int failCount = 0;
- for (int i = 0; i < selectedBillIds.size(); i++) {
- String selectedId = selectedBillIds.get(i);
- EvaResultSummaryInfo summaryInfo = summaryById.get(selectedId);
- if (summaryInfo == null) {
- skippedNotFound++;
- continue;
- }
- if (!isApproved(summaryInfo)) {
- skippedNotApproved++;
- continue;
- }
- PerfEvaObjectInfo evaObj = summaryInfo.getEvaObj();
- PerfPeriodInfo period = summaryInfo.getPeriod();
- if (evaObj == null || evaObj.getPerson() == null
- || StringUtils.isBlank(evaObj.getPerson().getNumber()) || period == null) {
- skippedNoPerson++;
- continue;
- }
- String receiverId = evaObj.getPerson().getNumber();
- String periodName = period.getName();
- String messageContent = FeishuMessageUtil.buildEvaResultSummaryFeishuMessage(periodName);
- String workFlowName = "绩效结果公示通知";
- String uuid = "esn_" + selectedId + "_" + receiverId+"_"+System.currentTimeMillis();;
- FeishuMessageUtil.ApprovalBotResult sendResult = FeishuMessageUtil.sendRemindMessage(
- receiverId, workFlowName, messageContent, pcurl, appurl, uuid);
- if (sendResult.isSuccess()) {
- successCount++;
- } else {
- failCount++;
- logger.error("考核结果汇总-飞书消息发送失败,billId={},receiverId={},msg={}",
- selectedId, receiverId, sendResult.getMsg());
- }
- }
- if (successCount == 0) {
- res.put("result", "500");
- if (skippedNotApproved > 0) {
- res.put("msg", "勾选的考核结果均未审批通过,无法发送(共 " + skippedNotApproved + " 条)");
- } else if (skippedNoPerson > 0) {
- res.put("msg", "勾选的考核结果中未找到有效的被考核人工号");
- } else if (failCount > 0) {
- res.put("msg", "飞书消息推送失败,请检查员工工号及飞书接口配置");
- } else {
- res.put("msg", "未找到可推送的考核结果");
- }
- JSONUtils.writeJson(response, res);
- return;
- }
- StringBuilder msg = new StringBuilder("飞书消息推送成功,共发送 ").append(successCount).append(" 条");
- if (skippedNotApproved > 0) {
- msg.append(";").append(skippedNotApproved).append(" 条未审批已跳过");
- }
- if (skippedNoPerson > 0) {
- msg.append(";").append(skippedNoPerson).append(" 条无有效工号已跳过");
- }
- if (skippedNotFound > 0) {
- msg.append(";").append(skippedNotFound).append(" 条未查询到数据已跳过");
- }
- if (failCount > 0) {
- msg.append(";").append(failCount).append(" 条发送失败");
- }
- res.put("result", "200");
- res.put("msg", msg.toString());
- logger.info("考核结果汇总-飞书消息推送完成,成功={},未审批跳过={},无工号跳过={},失败={}",
- successCount, skippedNotApproved, skippedNoPerson, failCount);
- } catch (Exception e) {
- logger.error("考核结果汇总-飞书消息推送异常", e);
- res.put("result", "500");
- res.put("msg", "飞书消息推送失败:" + e.getMessage());
- }
- JSONUtils.writeJson(response, res);
- }
- private List<String> parseSelectedBillIds(String billId) {
- List<String> selectedBillIds = new ArrayList<>();
- Set<String> seen = new HashSet<>();
- for (String id : billId.split(",")) {
- if (StringUtils.isBlank(id)) {
- continue;
- }
- String trimmed = id.trim();
- if (seen.add(trimmed)) {
- selectedBillIds.add(trimmed);
- }
- }
- return selectedBillIds;
- }
- private Map<String, EvaResultSummaryInfo> loadSummaryByIds(Context ctx, List<String> selectedBillIds) throws Exception {
- IEvaResultSummary iEvaResultSummary = EvaResultSummaryFactory.getLocalInstance(ctx);
- FilterInfo filter = new FilterInfo();
- filter.getFilterItems().add(new FilterItemInfo("id", new HashSet<>(selectedBillIds), CompareType.INCLUDE));
- SelectorItemCollection sic = new SelectorItemCollection();
- sic.add(new SelectorItemInfo("*"));
- sic.add(new SelectorItemInfo("evaObj.*"));
- sic.add(new SelectorItemInfo("evaObj.person.*"));
- sic.add(new SelectorItemInfo("evaObj.workFlow.*"));
- sic.add(new SelectorItemInfo("period.*"));
- EntityViewInfo evi = new EntityViewInfo();
- evi.setFilter(filter);
- evi.setSelector(sic);
- EvaResultSummaryCollection coll = iEvaResultSummary.getEvaResultSummaryCollection(evi);
- Map<String, EvaResultSummaryInfo> summaryById = new HashMap<>();
- if (coll == null || coll.isEmpty()) {
- return summaryById;
- }
- for (int i = 0; i < coll.size(); i++) {
- EvaResultSummaryInfo info = coll.get(i);
- if (info != null && info.getId() != null) {
- summaryById.put(info.getId().toString(), info);
- }
- }
- return summaryById;
- }
- private Set<String> collectPeriodIds(Map<String, EvaResultSummaryInfo> summaryById) {
- Set<String> periodIds = new LinkedHashSet<>();
- for (EvaResultSummaryInfo info : summaryById.values()) {
- if (info == null || info.getPeriod() == null || info.getPeriod().getId() == null) {
- continue;
- }
- periodIds.add(info.getPeriod().getId().toString());
- }
- return periodIds;
- }
- private boolean isApproved(EvaResultSummaryInfo info) {
- if (info == null) {
- return false;
- }
- return BILL_STATE_AUDITED.equals(StringUtils.trimToEmpty(info.getString("billState")));
- }
- }
|