| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- package com.kingdee.eas.custom.weaverTodo.util;
- import com.alibaba.fastjson.JSONObject;
- import com.kingdee.bos.BOSException;
- import com.kingdee.bos.Context;
- import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
- import com.kingdee.bos.metadata.IMetaDataLoader;
- import com.kingdee.bos.metadata.MetaDataLoaderFactory;
- import com.kingdee.bos.metadata.entity.EntityObjectInfo;
- import com.kingdee.bos.util.BOSUuid;
- import com.kingdee.eas.base.message.AssignReadFactory;
- import com.kingdee.eas.base.message.AssignReadInfo;
- import com.kingdee.eas.base.message.IAssignRead;
- import com.kingdee.eas.base.message.URLInfo;
- import com.kingdee.eas.base.message.util.ProcessCenterUtil;
- import com.kingdee.eas.base.permission.IUser;
- import com.kingdee.eas.base.permission.UserFactory;
- import com.kingdee.eas.base.permission.UserInfo;
- import com.kingdee.eas.common.EASBizException;
- import com.kingdee.eas.custom.weaverTodo.config.WeaverTodoConfig;
- import com.kingdee.eas.custom.weaverTodo.enums.WeaverCallOperTypeEnum;
- import com.kingdee.eas.custom.weaverTodo.enums.WeaverIsRemarkEnum;
- import com.kingdee.eas.custom.weaverTodo.enums.WeaverRequestStatusEnum;
- import com.kingdee.eas.custom.weaverTodo.enums.WeaverViewTypeEnum;
- import com.kingdee.eas.util.app.DbUtil;
- import com.kingdee.jdbc.rowset.IRowSet;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.log4j.Logger;
- import java.net.URLEncoder;
- import java.nio.charset.StandardCharsets;
- import java.sql.Timestamp;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- /**
- * 统一待办字段拼装、相对链接、人员工号、本地日志表。
- */
- public class WeaverTodoSupport {
- private static final Logger logger = Logger.getLogger(WeaverTodoSupport.class);
- private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- private final WeaverTodoConfig config;
- public WeaverTodoSupport(WeaverTodoConfig config) {
- this.config = config;
- }
- public void delayForWf() {
- try {
- Thread.sleep(config.getWfDelayMs());
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
- public String sanitize(String text) {
- if (text == null) {
- return "";
- }
- String s = text.replace("'", "")
- .replace(" ", " ")
- .replace("<", "")
- .replace(">", "")
- .replace("&", "")
- .replace("\"", "");
- if (s.length() > 2000) {
- s = s.substring(0, 2000);
- }
- return s.trim();
- }
- public String nowDatetime() {
- return SDF.format(new Date());
- }
- public String workflowCodeOf(String workflowname) {
- String name = sanitize(workflowname);
- if (StringUtils.isBlank(name)) {
- name = "SHR流程";
- }
- return String.valueOf(name.hashCode());
- }
- public String getAssignIdByMsgId(Context ctx, String msgId) throws BOSException, EASBizException {
- if (StringUtils.isBlank(msgId)) {
- return "";
- }
- IAssignRead assignReadIns = AssignReadFactory.getLocalInstance(ctx);
- AssignReadInfo assignReadInfo = assignReadIns.getAssignReadInfo(new ObjectUuidPK(msgId));
- if (assignReadInfo == null || assignReadInfo.getAssignID() == null) {
- return "";
- }
- return assignReadInfo.getAssignID().toString();
- }
- public String resolveBillId(Context ctx, String billId, String assignId) throws Exception {
- if (StringUtils.isNotBlank(billId)) {
- return billId;
- }
- if (StringUtils.isBlank(assignId)) {
- return "";
- }
- URLInfo info = ProcessCenterUtil.getUrlInfos(assignId, ctx);
- return info == null ? "" : StringUtils.defaultString(info.getBillID());
- }
- public String resolveWorkflowName(Context ctx, String msgId, String billId, String assignId) {
- String flowTypeName = "SHR流程";
- try {
- String resolvedBill = resolveBillId(ctx, billId, assignId);
- if (StringUtils.isBlank(resolvedBill) && StringUtils.isNotBlank(msgId)) {
- assignId = getAssignIdByMsgId(ctx, msgId);
- resolvedBill = resolveBillId(ctx, billId, assignId);
- }
- if (StringUtils.isBlank(resolvedBill)) {
- return flowTypeName;
- }
- IMetaDataLoader loader = MetaDataLoaderFactory.getRemoteMetaDataLoader();
- EntityObjectInfo vo = loader.getEntity(BOSUuid.read(resolvedBill).getType());
- if (vo != null && StringUtils.isNotBlank(vo.getDisplayName())) {
- flowTypeName = vo.getDisplayName();
- }
- } catch (Exception e) {
- logger.warn("解析流程类型名失败,使用默认", e);
- }
- return sanitize(flowTypeName);
- }
- /**
- * 报业返回人员工号 pp.FNumber(与 SSO PERSON_NUMBER 一致)
- */
- public String resolveReceiverWorkcode(Context ctx, String userIdOrNumber) {
- if (StringUtils.isBlank(userIdOrNumber)) {
- return "";
- }
- String key = userIdOrNumber.trim();
- try {
- String sql = "select uu.FNumber userNumber from T_PM_User uu "
- + "where uu.FForbidden = 0 and (uu.FNumber = ? or uu.FID = ?) "
- + "order by uu.FIsDelete";
- IRowSet rs = DbUtil.executeQuery(ctx, sql, new Object[]{key, key});
- if (rs.next()) {
- String userNumber = rs.getString("userNumber");
- if (StringUtils.isNotBlank(userNumber)) {
- return userNumber.trim();
- }
- }
- } catch (Exception e) {
- logger.warn("SQL 解析工号失败 key=" + key + ": " + e.getMessage());
- }
- return "";
- }
-
- /**
- * 按用户 id 取 UserInfo(BMC 发送人等)。
- */
- public UserInfo getUserById(Context ctx, String userId) {
- if (StringUtils.isBlank(userId)) {
- return null;
- }
- try {
- IUser iUser = UserFactory.getLocalInstance(ctx);
- return iUser.getUserInfo(new ObjectUuidPK(userId.trim()));
- } catch (Exception e) {
- logger.warn("按 id 取用户失败 userId=" + userId + ": " + e.getMessage());
- return null;
- }
- }
- /**
- * 泛微要求相对路径。落地走 SSO:entryPath?appId&redirect=审批页绝对地址(编码)。
- * entryPath 来自 weaver.sso.entryPath,默认 /qy/auth/weaver/app.do。
- */
- public String buildRelativePcUrl(Context ctx, String billId, String assignId) throws Exception {
- String resolvedBill = resolveBillId(ctx, billId, assignId);
- String approveAbs;
- if (StringUtils.isNotBlank(assignId)) {
- approveAbs = config.getShrServerName() + config.getApprovePcPath()
- + "?AssignmentId=" + URLEncoder.encode(assignId, StandardCharsets.UTF_8.name())
- + "&billID=" + URLEncoder.encode(StringUtils.defaultString(resolvedBill), StandardCharsets.UTF_8.name());
- } else {
- approveAbs = config.getShrServerName() + "/shr/dynamic.do?uipk=shr.workflow.view&inFrame=true";
- }
- String entryPath = StringUtils.defaultIfBlank(config.getSsoEntryPath(), "/qy/auth/weaver/app.do");
- String relative = entryPath + "?appId=" + URLEncoder.encode(config.getSsoAppId(), StandardCharsets.UTF_8.name())
- + "&redirect=" + URLEncoder.encode(approveAbs, StandardCharsets.UTF_8.name());
- if (relative.startsWith("http://") || relative.startsWith("https://")) {
- throw new IllegalStateException("pcurl 不允许绝对地址");
- }
- return relative;
- }
- public String buildRelativeAppUrl(Context ctx, String billId, String assignId) throws Exception {
- // 移动端暂与 PC 同路径,由泛微外链前缀区分端;后续可接 MBOS
- return buildRelativePcUrl(ctx, billId, assignId);
- }
- public JSONObject buildPayload(String flowid,
- String requestname,
- String workflowname,
- String nodename,
- String receiver,
- String creator,
- String pcurl,
- String appurl,
- WeaverIsRemarkEnum isRemark,
- WeaverViewTypeEnum viewType,
- WeaverRequestStatusEnum requestStatus) {
- JSONObject body = new JSONObject();
- body.put("syscode", config.getSyscode());
- body.put("flowid", StringUtils.defaultString(flowid));
- body.put("requestname", sanitize(requestname));
- String typeName = sanitize(workflowname);
- if (StringUtils.isBlank(typeName)) {
- typeName = "SHR流程";
- }
- body.put("workflowname", typeName);
- body.put("workflowcode", workflowCodeOf(typeName));
- body.put("nodename", sanitize(StringUtils.defaultIfBlank(nodename, "审批节点")));
- body.put("createdatetime", nowDatetime());
- body.put("receiver", sanitize(receiver));
- body.put("receivedatetime", nowDatetime());
- body.put("isremark", isRemark.getCode());
- body.put("viewtype", viewType.getCode());
- body.put("receivets", String.valueOf(System.currentTimeMillis()));
- if (StringUtils.isNotBlank(creator)) {
- body.put("creator", sanitize(creator));
- }
- if (StringUtils.isNotBlank(pcurl)) {
- body.put("pcurl", pcurl);
- }
- if (StringUtils.isNotBlank(appurl)) {
- body.put("appurl", appurl);
- }
- if (requestStatus != null) {
- body.put("requestStatus", requestStatus.getCode());
- }
- return body;
- }
- public void saveAssignRecord(Context ctx, String msgId, String assignId, String billId,
- String workflowname, String procInstId, String receiver) {
- // 优先带 receiver 列;老表没有该列则回退
- try {
- String sql = "insert into assignReadRecord(MsgId,assignID,billId,workflowname,procInstId,receiver) values(?,?,?,?,?,?)";
- Object[] params = new Object[]{
- nvl(msgId), nvl(assignId), nvl(billId), nvl(workflowname), nvl(procInstId), nvl(receiver)
- };
- DbUtil.execute(ctx, sql, params);
- return;
- } catch (Exception e) {
- logger.warn("带 receiver 写入 assignReadRecord 失败,尝试无 receiver 列: " + e.getMessage());
- }
- try {
- String sql = "insert into assignReadRecord(MsgId,assignID,billId,workflowname,procInstId) values(?,?,?,?,?)";
- Object[] params = new Object[]{
- nvl(msgId), nvl(assignId), nvl(billId), nvl(workflowname), nvl(procInstId)
- };
- DbUtil.execute(ctx, sql, params);
- } catch (Exception e) {
- logger.warn("写入 assignReadRecord 失败(表可能已存在同键或未建表): " + e.getMessage());
- }
- }
- /** 统一待办接口 URL(不含 access_token,便于落库)。 */
- public String buildReceiveTodoUrl() {
- return StringUtils.defaultString(config.getOpenapiHost())
- + StringUtils.defaultString(config.getReceivePath());
- }
- /** 消息中心 sendMsg URL(不含 access_token)。 */
- public String buildSendMsgUrl() {
- return StringUtils.defaultString(config.getOpenapiHost())
- + StringUtils.defaultString(config.getSendMsgPath());
- }
- public void addCallLog(Context ctx, String msgId, String assignId, String billId,
- WeaverCallOperTypeEnum operType, String requestUrl,
- String requestParams, String responseResult,
- int statusCode, String message) {
- try {
- logger.info("[WEAVER-TODO] CallLog write OperType=" + (operType == null ? "" : operType.getLabel())
- + " msgId=" + msgId + " assignId=" + assignId + " billId=" + billId
- + " requestUrl=" + requestUrl
- + " statusCode=" + statusCode + " message=" + message);
- String sql = "insert into OAMsgCallLog(MsgId,assignID,billId,OperType,RequestUrl,RequestParams,ResponseResult,StatusCode,Message,CreateTime) "
- + "values(?,?,?,?,?,?,?,?,?,?)";
- String operLabel = operType == null ? "" : operType.getLabel();
- Object[] params = new Object[]{
- msgId, assignId, billId, operLabel,
- StringUtils.defaultString(requestUrl),
- requestParams, responseResult,
- statusCode, message, new Timestamp(System.currentTimeMillis())
- };
- DbUtil.execute(ctx, sql, params);
- } catch (Exception e) {
- logger.warn("写入 OAMsgCallLog 失败: " + e.getMessage());
- }
- }
- /**
- * 截断字符串
- * @param s
- * @param maxLen
- * @return
- */
- private static String cutStr(String s, int maxLen) {
- if (s == null) {
- return "";
- }
- if (s.length() <= maxLen) {
- return s;
- }
- return s.substring(0, maxLen);
- }
- public String getMsgIdByAssignId(Context ctx, String assignId) {
- try {
- IRowSet rs = DbUtil.executeQuery(ctx, "select MsgId from assignReadRecord where assignID = ?",
- new Object[]{assignId});
- if (rs.next()) {
- return rs.getString("MsgId");
- }
- } catch (Exception e) {
- logger.warn("按 assignId 查 msgId 失败", e);
- }
- return "";
- }
- public String getProcInstIdByAssignId(Context ctx, String assignId) {
- try {
- IRowSet rs = DbUtil.executeQuery(ctx, "select procInstId from assignReadRecord where assignID = ?",
- new Object[]{assignId});
- if (rs.next()) {
- return rs.getString("procInstId");
- }
- } catch (Exception e) {
- logger.warn("按 assignId 查 procInstId 失败", e);
- }
- return "";
- }
- public String getBillIdByAssignId(Context ctx, String assignId) {
- try {
- IRowSet rs = DbUtil.executeQuery(ctx, "select billId from assignReadRecord where assignID = ?",
- new Object[]{assignId});
- if (rs.next()) {
- return StringUtils.defaultString(rs.getString("billId"));
- }
- } catch (Exception e) {
- logger.warn("get billId by assignId failed", e);
- }
- return "";
- }
- /**
- * 删除/撤销必须用当初推待办的 workflowname,否则泛微 upsert 键对不上。
- */
- public String getWorkflowNameByAssignId(Context ctx, String assignId) {
- try {
- IRowSet rs = DbUtil.executeQuery(ctx, "select workflowname from assignReadRecord where assignID = ?",
- new Object[]{assignId});
- if (rs.next()) {
- String name = rs.getString("workflowname");
- if (StringUtils.isNotBlank(name)) {
- return sanitize(name);
- }
- }
- } catch (Exception e) {
- logger.warn("get workflowname by assignId failed: " + e.getMessage());
- }
- try {
- IRowSet rs = DbUtil.executeQuery(ctx,
- "select RequestParams from OAMsgCallLog where assignID = ? and OperType = ? order by CreateTime desc",
- new Object[]{assignId, WeaverCallOperTypeEnum.TODO_ADD.getLabel()});
- if (rs.next()) {
- String raw = rs.getString("RequestParams");
- if (StringUtils.isNotBlank(raw)) {
- JSONObject json = JSONObject.parseObject(raw);
- String name = json.getString("workflowname");
- if (StringUtils.isNotBlank(name)) {
- return sanitize(name);
- }
- }
- }
- } catch (Exception e) {
- logger.warn("parse workflowname from CallLog failed", e);
- }
- return "";
- }
- public String getReceiverByAssignId(Context ctx, String assignId) {
- try {
- IRowSet rs = DbUtil.executeQuery(ctx, "select receiver from assignReadRecord where assignID = ?",
- new Object[]{assignId});
- if (rs.next()) {
- String r = rs.getString("receiver");
- if (StringUtils.isNotBlank(r)) {
- return r;
- }
- }
- } catch (Exception e) {
- logger.warn("按 assignId 查 receiver 列失败,回退 CallLog: " + e.getMessage());
- }
- try {
- IRowSet rs = DbUtil.executeQuery(ctx,
- "select RequestParams from OAMsgCallLog where assignID = ? and OperType = ? order by CreateTime desc",
- new Object[]{assignId, WeaverCallOperTypeEnum.TODO_ADD.getLabel()});
- if (rs.next()) {
- String raw = rs.getString("RequestParams");
- if (StringUtils.isNotBlank(raw)) {
- JSONObject json = JSONObject.parseObject(raw);
- String r = json.getString("receiver");
- if (StringUtils.isNotBlank(r)) {
- return r;
- }
- }
- }
- } catch (Exception e) {
- logger.warn("从 OAMsgCallLog 解析 receiver 失败", e);
- }
- return "";
- }
- private static String nvl(String s) {
- return s == null ? "" : s;
- }
- }
|