Heyuan vor 6 Monaten
Ursprung
Commit
de79b66ac4

+ 75 - 11
src/com/kingdee/eas/custom/messageWebService/OAMessageWebServiceDao.java

@@ -17,13 +17,17 @@ import com.kingdee.eas.base.message.webservice.WfrProcMessage;
 import com.kingdee.eas.basedata.person.IPerson;
 import com.kingdee.eas.basedata.person.PersonFactory;
 import com.kingdee.eas.basedata.person.PersonInfo;
+import com.kingdee.eas.common.EASBizException;
 import okhttp3.*;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
+import java.text.MessageFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
@@ -37,6 +41,9 @@ import java.util.Properties;
 public class OAMessageWebServiceDao implements MessageWebServiceDao {
     private static Logger logger = Logger.getLogger(OAMessageWebServiceDao.class);
     private Properties prop = new Properties();
+    private final String MBOSURL = "https://mbos.kdeascloud.com/mbos/mbosw/getWorkflowUrl?assignId={0}&eid={1}&storeEid={2}&name=approveui.navui&billID={3}";
+    //mbos流程助手首页
+    private final String MBOSAPPROVECENTERURL = "https://mbos.kdeascloud.com/mbos/page/loadPage?appid=10036&eid={0}&path=lczs2&name=lczshome.navui";
     String propPath = System.getProperty("EAS_HOME") + "/server/properties/scy/receiveOAConfig.properties";
 
     public OAMessageWebServiceDao() {
@@ -261,21 +268,15 @@ public class OAMessageWebServiceDao implements MessageWebServiceDao {
             }
             String billId = message.getBillId();
             logger.error("billId: " + billId);
-            StringBuilder url = new StringBuilder();
-            StringBuilder redirectUrl = new StringBuilder();
-            url.append(serverName).append("/shr/api/oAToSHR?redirect=");
+            String assignID = null;
             if (!StringUtils.isEmpty(message.getMsgID())) {
                 IAssignRead assignReadIns = AssignReadFactory.getLocalInstance(message.getContext());
                 AssignReadInfo assignReadInfo = assignReadIns.getAssignReadInfo(new ObjectUuidPK(message.getMsgID()));
-                String assignID = assignReadInfo.getAssignID().toString();
-                redirectUrl.append(serverName).append("/easweb/webviews/workflow/transferApprove.jsp?AssignmentId=")
-                        .append(assignID);
-            } else {
-                redirectUrl.append(serverName).append("/shr/dynamic.do?uipk=shr.perself.homepage");
+                assignID = assignReadInfo.getAssignID().toString();
             }
-            url.append(URLEncoder.encode(redirectUrl.toString(), "UTF-8"));
-            params.put("pcurl", url);//PC地址(相对路径/开头)
-            params.put("appurl", url);//APP地址(相对路径/开头)
+
+            params.put("pcurl", getPcUrl(serverName, assignID));//PC地址(相对路径/开头)
+            params.put("appurl", getAppUrl(message.getContext(), serverName, assignID));//APP地址(相对路径/开头)
             params.put("nodename", "sHR");//步骤名称(节点名称)
             params.put("isremark", isremark);//流程处理状态
             params.put("viewtype", viewtype);//流程查看状态
@@ -314,6 +315,67 @@ public class OAMessageWebServiceDao implements MessageWebServiceDao {
         return false;
     }
 
+    /**
+     * 获取pc待办地址
+     *
+     * @param serverName
+     * @param assignID
+     * @return
+     * @throws BOSException
+     * @throws EASBizException
+     * @throws UnsupportedEncodingException
+     */
+    private String getPcUrl(String serverName, String assignID)
+            throws UnsupportedEncodingException {
+        StringBuilder pcurl = new StringBuilder();
+        StringBuilder redirectUrl = new StringBuilder();
+        pcurl.append(serverName).append("/shr/api/oAToSHR?redirect=");
+        if (!StringUtils.isEmpty(assignID)) {
+            redirectUrl.append(serverName).append("/easweb/webviews/workflow/transferApprove.jsp?AssignmentId=")
+                    .append(assignID);
+        } else {
+            redirectUrl.append(serverName).append("/shr/dynamic.do?uipk=shr.perself.homepage");
+        }
+        pcurl.append(URLEncoder.encode(redirectUrl.toString(), "UTF-8"));
+        return pcurl.toString();
+    }
+
+    /**
+     * 获取app待办地址
+     *
+     * @param serverName
+     * @param assignID
+     * @return
+     * @throws BOSException
+     * @throws EASBizException
+     * @throws UnsupportedEncodingException
+     */
+    private String getAppUrl(Context ctx, String serverName, String assignID)
+            throws UnsupportedEncodingException, BOSException {
+        StringBuilder appUrl = new StringBuilder();
+        appUrl.append(serverName).append("/shr/api/oAToMBos?redirect=");
+        String eid = prop.getProperty("eid");
+        if (StringUtils.isEmpty(eid)) {
+            throw new RuntimeException("发送OA待办消息,eid不能为空! 请检查配置文件: " + propPath);
+        }
+        String redirectUrl = null;
+        if (!StringUtils.isEmpty(assignID)) {
+            IAssign iAssign = AssignFactory.getLocalInstance(ctx);
+            AssignInfo assignInfo = iAssign.getValue(new ObjectUuidPK(assignID));
+            String billId = assignInfo.getBizObjID();
+            redirectUrl = MessageFormat.format(MBOSURL,
+                    URLEncoder.encode(assignID, "UTF-8"),
+                    eid,
+                    eid,
+                    URLEncoder.encode(billId, "UTF-8"));
+        } else {
+            redirectUrl = MessageFormat.format(MBOSAPPROVECENTERURL, eid);
+        }
+        appUrl.append(URLEncoder.encode(redirectUrl, "UTF-8"));
+        return appUrl.toString();
+    }
+
+
     /**
      * 删除待办
      *
@@ -361,4 +423,6 @@ public class OAMessageWebServiceDao implements MessageWebServiceDao {
         }
         return false;
     }
+
+
 }

+ 367 - 0
src/com/kingdee/eas/custom/sso/OAToMBos.java

@@ -0,0 +1,367 @@
+package com.kingdee.eas.custom.sso;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.kingdee.bos.BOSException;
+import com.kingdee.bos.Context;
+import com.kingdee.eas.cp.eip.sso.util.CASLoginConfigPropUtil;
+import com.kingdee.eas.cp.eip.sso.util.CloudParamUtil;
+import com.kingdee.eas.util.app.DbUtil;
+import com.kingdee.jdbc.rowset.IRowSet;
+import com.kingdee.shr.base.syssetting.exception.SHRWebException;
+import com.kingdee.util.StringUtils;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.apache.log4j.Logger;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+import java.sql.SQLException;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Random;
+
+/**
+ * @Description OA移动端单点移动bos
+ * @Date 2024/10/30 11:22
+ * @Created by Heyuan
+ */
+public class OAToMBos extends HttpServlet {
+    private static Logger logger = Logger.getLogger(OAToMBos.class);
+    private static ExpiringMapCache<String, String> redirectUrlCache = new ExpiringMapCache<>();
+    private Properties prop = new Properties();
+    private String propPath = System.getProperty("EAS_HOME") + "/server/properties/scy/OAToMBosConfig.properties";
+    private final String MBOSAPPROVECENTERURL = "https://mbos.kdeascloud.com/mbos/page/loadPage?appid=10036&eid={0}&path=lczs2&name=lczshome.navui";
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+            throws ServletException, IOException {
+        logger.error("OAToMBos -> doGet");
+        doPost(req, resp);
+    }
+
+    @Override
+    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+            throws ServletException, IOException {
+        logger.error("OAToMBos -> doPost");
+        BufferedReader streamReader = null;
+        String resultStr = null;
+        prop.load(new FileInputStream(propPath));
+        logger.error("OAToMBos  requestUrl" + req.getRequestURL().toString());
+        try {
+            String ticket = req.getParameter("ticket");
+            String token = req.getParameter("token");
+            logger.error("接收到的请求参数是:ticket " + ticket);
+            if (!StringUtils.isEmpty(ticket)) {
+                //重定向到Mbos
+                redirectMbos(req, resp, ticket);
+            } else if (!StringUtils.isEmpty(token)) {
+                //获取用户信息(mbos回调)
+                getTokenUrl(req, resp, token);
+            } else {
+                //认证
+                authorize(req, resp);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            Map result = new HashMap();
+            result.put("msgType", "0");
+            result.put("reason", e.getMessage());
+            resultStr = JSON.toJSONString(result);
+            resp.setStatus(500);
+            PrintWriter writer = resp.getWriter();
+            resp.setContentType("application/json");
+            writer.write(resultStr);
+            writer.close();
+        } finally {
+            try {
+                if (streamReader != null) {
+                    streamReader.close();
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * 重定向到mbos
+     *
+     * @param req
+     * @param resp
+     * @param ticket
+     * @throws IOException
+     */
+    private void redirectMbos(HttpServletRequest req,
+                              HttpServletResponse resp,
+                              String ticket) throws IOException {
+        if (StringUtils.isEmpty(ticket)) {
+            throw new RuntimeException("ticket不能为空!");
+        }
+        String getAccessTokenPath = prop.getProperty("getAccessTokenPath");
+        if (StringUtils.isEmpty(getAccessTokenPath)) {
+            throw new RuntimeException("getAccessTokenPath不能为空! 请检查配置文件: " + propPath);
+        }
+        String client_secret = prop.getProperty("client_secret");
+        if (StringUtils.isEmpty(client_secret)) {
+            throw new RuntimeException("client_secret不能为空! 请检查配置文件: " + propPath);
+        }
+        String client_id = prop.getProperty("client_id");
+        if (StringUtils.isEmpty(client_id)) {
+            throw new RuntimeException("client_id不能为空! 请检查配置文件: " + propPath);
+        }
+        String redirect_uri2 = prop.getProperty("redirect_uri2");
+        if (StringUtils.isEmpty(redirect_uri2)) {
+            throw new RuntimeException("redirect_uri2不能为空! 请检查配置文件: " + propPath);
+        }
+        String getLoginIdPath = prop.getProperty("getLoginIdPath");
+        if (StringUtils.isEmpty(getLoginIdPath)) {
+            throw new RuntimeException("getLoginIdPath不能为空! 请检查配置文件: " + propPath);
+        }
+        String redirectUrlKey = req.getParameter("redirect");
+        logger.error("callBack redirectUrl" + redirectUrlKey);
+        Map params = new HashMap();
+        params.put("client_id", client_id);
+        params.put("client_secret", client_secret);
+        params.put("grant_type", "authorization_code");
+        params.put("code", ticket);
+        params.put("redirect_uri", URLEncoder.encode(redirect_uri2, "UTF-8"));
+        try {
+            String redirectUrl = null;
+            String token = getAccessToken(getAccessTokenPath, params);
+            logger.error(token);
+            if (StringUtils.isEmpty(redirectUrlKey)) {
+                String eid = prop.getProperty("eid");
+                if (org.apache.commons.lang3.StringUtils.isEmpty(eid)) {
+                    throw new RuntimeException("eid不能为空! 请检查配置文件: " + propPath);
+                }
+                redirectUrl = MessageFormat.format(MBOSAPPROVECENTERURL, eid);
+            } else {
+                redirectUrl = redirectUrlCache.get(redirectUrlKey);
+            }
+            Map toMbosparams = new HashMap();
+            toMbosparams.put("token", token);
+            String urlString = appendUrl(redirectUrl, toMbosparams);
+            resp.sendRedirect(urlString);
+            logger.error("redirectMbos url" + urlString);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    /**
+     * 认证
+     * 拼接OA认证接口地址,转发
+     *
+     * @param resp
+     * @throws Exception
+     */
+    public void authorize(HttpServletRequest req, HttpServletResponse resp) throws Exception {
+        String authorizePath = prop.getProperty("authorizePath");
+        if (StringUtils.isEmpty(authorizePath)) {
+            throw new RuntimeException("authorizePath不能为空! 请检查配置文件: " + propPath);
+        }
+        String response_type = prop.getProperty("response_type");
+        if (StringUtils.isEmpty(response_type)) {
+            throw new RuntimeException("response_type不能为空! 请检查配置文件: " + propPath);
+        }
+        String client_id = prop.getProperty("client_id");
+        if (StringUtils.isEmpty(client_id)) {
+            throw new RuntimeException("client_id不能为空! 请检查配置文件: " + propPath);
+        }
+        String redirect_uri1 = prop.getProperty("redirect_uri1");
+        if (StringUtils.isEmpty(redirect_uri1)) {
+            throw new RuntimeException("redirect_uri1不能为空! 请检查配置文件: " + propPath);
+        }
+        String redirectUrl = req.getParameter("redirect");
+        if (StringUtils.isEmpty(redirectUrl)) {
+            String serverName = prop.getProperty("serverName");
+            if (StringUtils.isEmpty(serverName)) {
+                throw new RuntimeException("serverName不能为空! 请检查配置文件: " + propPath);
+            }
+            redirectUrl = serverName + "/shr/dynamic.do?uipk=shr.perself.homepage";
+        }
+        Random random = new Random();
+        String key = System.currentTimeMillis() + String.valueOf(random.nextInt(99999));
+        redirectUrlCache.put(key, redirectUrl, 300000);
+        logger.error("callBack redirectUrl" + redirectUrl);
+        redirect_uri1 += "?redirect=" + key;
+        Map params = new HashMap();
+        params.put("client_id", client_id);
+        params.put("response_type", response_type);
+        params.put("redirect_uri", URLEncoder.encode(redirect_uri1, "UTF-8"));
+        String urlString = appendUrl(authorizePath, params);
+        resp.sendRedirect(urlString);
+        logger.error("authorize url" + urlString);
+    }
+
+    /**
+     * 获取用户信息
+     * 用户信息
+     *
+     * @param req
+     * @param resp
+     * @param token
+     * @throws SHRWebException
+     * @throws UnsupportedEncodingException
+     */
+    public void getTokenUrl(HttpServletRequest req,
+                            HttpServletResponse resp, String token) throws
+            SHRWebException, IOException {
+        logger.error("getTokenUrl方法入参");
+        if (StringUtils.isEmpty(token)) {
+            throw new RuntimeException("token不能为空!");
+        }
+        String getLoginIdPath = prop.getProperty("getLoginIdPath");
+        if (StringUtils.isEmpty(getLoginIdPath)) {
+            throw new RuntimeException("getLoginIdPath不能为空! 请检查配置文件: " + propPath);
+        }
+        Map result = new HashMap();
+        try {
+            //从人员对象,获取纷享用户userId
+            String loginId = loginId2userId(getLoginIdPath, token);
+            result.put("status", "0");
+            result.put("message", loginId);
+            resp.setStatus(200);
+        } catch (Exception e) {
+            e.printStackTrace();
+            result.put("status", "1");
+            result.put("message", e.getMessage());
+            resp.setStatus(500);
+        }
+        PrintWriter writer = resp.getWriter();
+        resp.setContentType("application/json");
+        writer.write(JSON.toJSONString(result));
+        writer.close();
+    }
+
+    /**
+     * 获取泛微token方法
+     *
+     * @param getAccessTokenPath
+     * @param params
+     * @return
+     * @throws IOException
+     */
+    private String getAccessToken(String getAccessTokenPath, Map<String, String> params)
+            throws IOException {
+        logger.error("getAccessToken方法参数: " + params);
+        String url = appendUrl(getAccessTokenPath, params);
+        logger.error("access_token url" + url);
+        OkHttpClient client = new OkHttpClient();
+        Request request = new Request.Builder()
+                .url(url)
+                .get()
+                .addHeader("content-type", "multipart/form-data; boundary=---011000010111000001101001")
+                .build();
+        Response response = client.newCall(request).execute();
+        if (response.isSuccessful()) {
+            String string = response.body().string();
+            JSONObject jsonObject = JSONObject.parseObject(string);
+            String code = jsonObject.getString("code");
+            if ("0".equals(code)) {
+                String access_token = jsonObject.getString("access_token");
+                logger.error("access_token " + access_token);
+                return access_token;
+            } else {
+                throw new RuntimeException(jsonObject.getString("msg"));
+            }
+        } else {
+            //网络超时
+            throw new RuntimeException("获取token超时");
+        }
+    }
+
+    /**
+     * 获取用户信息
+     *
+     * @param accessToken
+     * @return
+     * @throws IOException
+     * @throws BOSException
+     * @throws SQLException
+     */
+    private String loginId2userId(String getLoginIdPath, String accessToken)
+            throws IOException, BOSException, SQLException {
+        if (StringUtils.isEmpty(accessToken)) {
+            throw new RuntimeException("accessToken不能为空! ");
+        }
+        //获取第三方用户信息
+        Map params = new HashMap();
+        params.put("access_token", accessToken);
+        String url = appendUrl(getLoginIdPath, params);
+        logger.error("loginId2userId url" + url);
+        OkHttpClient client = new OkHttpClient();
+        Request request = new Request.Builder()
+                .url(url)
+                .get()
+                .addHeader("content-type", "multipart/form-data; boundary=---011000010111000001101001")
+                .build();
+        Response response = client.newCall(request).execute();
+        if (response.isSuccessful()) {
+            String string = response.body().string();
+            JSONObject jsonObject = JSONObject.parseObject(string);
+            String code = jsonObject.getString("code");
+            if ("0".equals(code)) {
+                JSONObject attributes = jsonObject.getJSONObject("attributes");
+                //登录id
+                String loginid = attributes.getString("loginid");
+                String dataCenter = CASLoginConfigPropUtil.getDataCenter();
+                String locale = CASLoginConfigPropUtil.getLocale();
+                if (!StringUtils.isEmpty(dataCenter) && !StringUtils.isEmpty(locale)) {
+                    Context ctx = CloudParamUtil.getContext(dataCenter, locale, "administrator");
+                    String sql = "SELECT count(1) total FROM T_PM_USER WHERE fnumber=?";
+                    IRowSet rs = DbUtil.executeQuery(ctx, sql, new Object[]{loginid});
+                    int total = 0;
+                    if (rs.next()) {
+                        total = rs.getInt("total");
+                    }
+                    if (total <= 0) {
+                        logger.error("SHR找不到对应的用户, loginid:" + loginid);
+                        throw new RuntimeException("SHR找不到对应的用户, loginid: " + loginid);
+                        //("您无权限访问SHR系统,请联系管理员处理。")
+                    } else if (total > 1) {
+                        logger.error("SHR找到多个对应的用户, loginid:" + loginid);
+                        throw new RuntimeException("SHR找到多个对应的用户, loginid: " + loginid);
+                        //("您无权限访问SHR系统,请联系管理员处理。")
+                    } else {
+                        return loginid;
+                    }
+                }
+                logger.error("获取用户信息报错,数据中心没找到!");
+                throw new RuntimeException("获取用户信息报错,数据中心没找到!");
+            } else {
+                logger.error(jsonObject.getString("msg"));
+                throw new RuntimeException(jsonObject.getString("msg"));
+            }
+        } else {
+            //网络超时
+            logger.error("网络超时");
+            throw new RuntimeException("网络超时");
+        }
+    }
+
+    /**
+     * 拼接地址参数
+     */
+    private static String appendUrl(String url, Map<String, String> data) {
+        logger.error("appendUrl_url: " + url);
+        logger.error("appendUrl_data: " + data);
+        StringBuilder paramStr = new StringBuilder();
+        for (String key : data.keySet()) {
+            paramStr.append(key).append("=").append(data.get(key)).append("&");
+        }
+        paramStr.deleteCharAt(paramStr.lastIndexOf("&"));
+        String str = url.contains("?") ? (url + "&" + paramStr) : (url + "?" + paramStr);
+        logger.error("拼接后的地址为:" + str);
+        return str;
+    }
+}