feat:
prd 消息平台改用浙师大接口及 v3 鉴权参数。
企业微信沿用 v3 参数,补齐授权入口和回调。
prd 系统域名固定为 https://lxy.zjnu.edu.cn。
登录跳转兼容本站完整 URL。
清空其他学校的废弃对接参数。
公众号填入模拟参数,保持关闭;dev 配置不变。
This commit is contained in:
@@ -50,6 +50,8 @@ public class SmsServiceImpl implements SmsService {
|
||||
|
||||
@Inject
|
||||
private PropertiesProxy conf;
|
||||
@Inject
|
||||
private ZjnuMsgService zjnuMsgService;
|
||||
|
||||
/**
|
||||
* 发送短信消息。
|
||||
@@ -59,6 +61,9 @@ public class SmsServiceImpl implements SmsService {
|
||||
*/
|
||||
@Override
|
||||
public MsgPlatformResponse sendSms(MsgPlatformSmsRequest request) {
|
||||
if ("prd".equalsIgnoreCase(conf.get("nutz.profiles.active"))) {
|
||||
return zjnuMsgService.send(request, "SMS");
|
||||
}
|
||||
validateCommonRequest(request);
|
||||
JSONObject payload = buildCommonPayload(request, true);
|
||||
return doPost(SMS_API_PATH, payload);
|
||||
@@ -107,6 +112,9 @@ public class SmsServiceImpl implements SmsService {
|
||||
*/
|
||||
@Override
|
||||
public MsgPlatformResponse sendWechat(MsgPlatformWechatRequest request) {
|
||||
if ("prd".equalsIgnoreCase(conf.get("nutz.profiles.active"))) {
|
||||
return zjnuMsgService.send(request, "WeChat");
|
||||
}
|
||||
validateCommonRequest(request);
|
||||
if (Strings.isBlank(request.getWechatType())) {
|
||||
request.setWechatType("text");
|
||||
@@ -342,6 +350,9 @@ public class SmsServiceImpl implements SmsService {
|
||||
* @param request 平台请求参数
|
||||
*/
|
||||
private void fillDefaultSenderInfo(MsgPlatformBaseRequest request) {
|
||||
if ("prd".equalsIgnoreCase(conf.get("nutz.profiles.active"))) {
|
||||
return;
|
||||
}
|
||||
request.setSendUserId(getRequiredConfig("msg.platform.default-send-user-id", "请先配置 msg.platform.default-send-user-id"));
|
||||
request.setSendUserName(getRequiredConfig("msg.platform.default-send-user-name", "请先配置 msg.platform.default-send-user-name"));
|
||||
request.setSendUnitId(conf.get("msg.platform.default-send-unit-id", ""));
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
package com.budwk.app.base.sms.impl;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.budwk.app.base.exception.BaseException;
|
||||
import com.budwk.app.base.sms.model.*;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
import com.budwk.app.web.commons.base.Globals;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.integration.jedis.RedisService;
|
||||
import org.nutz.ioc.impl.PropertiesProxy;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Strings;
|
||||
import org.nutz.log.Log;
|
||||
import org.nutz.log.Logs;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@IocBean
|
||||
public class ZjnuMsgService {
|
||||
private static final Log log = Logs.get();
|
||||
@Inject
|
||||
private PropertiesProxy conf;
|
||||
@Inject
|
||||
private RedisService redisService;
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
public MsgPlatformResponse send(MsgPlatformBaseRequest request, String channel) {
|
||||
MsgPlatformResponse result = new MsgPlatformResponse();
|
||||
if (!conf.getBoolean("msg.platform.enabled", false)
|
||||
|| !Globals.MyConfig.getBoolean("SendMsg", Globals.MyConfig.getBoolean("AppSms", false))) {
|
||||
result.setCode(0);
|
||||
result.setResult(true);
|
||||
result.setMsg("通讯平台未启用,已跳过实际发送");
|
||||
return result;
|
||||
}
|
||||
if (request == null || Strings.isBlank(request.getInfo())) {
|
||||
throw new BaseException("浙师大消息内容不能为空");
|
||||
}
|
||||
List<MsgPlatformRecipient> recipients = request.getRecipients();
|
||||
if (Strings.isNotBlank(request.getPersonInfo())) {
|
||||
recipients = new ArrayList<>();
|
||||
for (String line : request.getPersonInfo().split("\\^@\\^")) {
|
||||
String[] fields = line.split("\\|", -1);
|
||||
MsgPlatformRecipient recipient = new MsgPlatformRecipient();
|
||||
recipient.setName(fields[0]);
|
||||
recipient.setAccount(fields.length > 1 ? fields[1] : "");
|
||||
recipient.setMobile(fields.length > 4 ? fields[4] : "");
|
||||
recipients.add(recipient);
|
||||
}
|
||||
}
|
||||
if (recipients == null || recipients.isEmpty()) {
|
||||
throw new BaseException("接收人列表不能为空");
|
||||
}
|
||||
List<Map<String, Object>> receivers = new ArrayList<>();
|
||||
for (MsgPlatformRecipient recipient : recipients) {
|
||||
if (recipient == null) {
|
||||
throw new BaseException("接收人信息不能为空");
|
||||
}
|
||||
String account = recipient.getAccount();
|
||||
String mobile = recipient.getMobile();
|
||||
if (Strings.isBlank(mobile) && Strings.isNotBlank(account) && account.matches("^\\d{11}$")) {
|
||||
mobile = account;
|
||||
account = null;
|
||||
}
|
||||
if (Strings.isBlank(account) && Strings.isNotBlank(mobile)) {
|
||||
List<Sys_user> users = dao.query(Sys_user.class, Cnd.where("mobile", "=", mobile));
|
||||
if (users.size() != 1) {
|
||||
throw new BaseException("无法通过手机号唯一确定浙师大消息接收人工号");
|
||||
}
|
||||
account = users.get(0).getLoginname();
|
||||
}
|
||||
if (Strings.isBlank(account)) {
|
||||
throw new BaseException("浙师大消息接收人工号不能为空");
|
||||
}
|
||||
receivers.add(Map.of("type", "User", "userId", account, "name", Strings.sNull(recipient.getName())));
|
||||
}
|
||||
try {
|
||||
Map<String, Object> payload = new LinkedHashMap<>();
|
||||
payload.put("token", getToken());
|
||||
payload.put("msgtitle", Globals.AppName);
|
||||
payload.put("msgContent", request.getInfo().replace("<", "<").replace(">", ">"));
|
||||
payload.put("msgType", "0");
|
||||
payload.put("sendStatus", "1");
|
||||
payload.put("sendChannel", channel);
|
||||
payload.put("sendMode", "normal");
|
||||
payload.put("receivers", JSONUtil.toJsonStr(receivers));
|
||||
payload.put("summary", "");
|
||||
payload.put("sendTime", Strings.sNull(request.getSendTime()));
|
||||
payload.put("isReply", "0");
|
||||
payload.put("sendMsgType", "1");
|
||||
try (HttpResponse response = HttpRequest.post(baseUrl() + "/message/sendMessageApi")
|
||||
.form(payload).timeout(conf.getInt("msg.platform.read-timeout", 10000)).execute()) {
|
||||
JSONObject body = JSONUtil.parseObj(response.body());
|
||||
Integer code = body.getInt("rspCode");
|
||||
result.setHttpStatus(response.getStatus());
|
||||
result.setCode(code);
|
||||
result.setResult(response.getStatus() == 200 && Integer.valueOf(0).equals(code));
|
||||
result.setMsg(body.getStr("rspMsg"));
|
||||
if (!Boolean.TRUE.equals(result.getResult())) {
|
||||
log.warn("浙师大消息发送失败,状态码:" + response.getStatus() + ",业务码:" + code);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("浙师大消息接口调用失败:" + e.getClass().getSimpleName());
|
||||
result.setCode(-1);
|
||||
result.setResult(false);
|
||||
result.setMsg("浙师大消息接口调用失败");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private String getToken() {
|
||||
String appId = conf.get("custom.msg.platform.app-id");
|
||||
String cacheKey = "zjnu:msg:token:" + appId;
|
||||
String token = redisService.get(cacheKey);
|
||||
if (Strings.isNotBlank(token)) {
|
||||
return token;
|
||||
}
|
||||
try (HttpResponse response = HttpRequest.get(baseUrl() + "/msg/getThirdAPIToken")
|
||||
.form("appId", appId, "appPassword", conf.get("custom.msg.platform.app-password"))
|
||||
.timeout(conf.getInt("msg.platform.read-timeout", 10000)).execute()) {
|
||||
JSONObject body = JSONUtil.parseObj(response.body());
|
||||
JSONObject data = body.getJSONObject("resultData");
|
||||
token = data == null ? null : data.getStr("token");
|
||||
if (response.getStatus() != 200 || Strings.isBlank(token)) {
|
||||
throw new BaseException("获取浙师大消息平台token失败");
|
||||
}
|
||||
redisService.setex(cacheKey, 1200, token);
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
private String baseUrl() {
|
||||
return conf.get("msg.platform.base-url").replaceAll("/+$", "");
|
||||
}
|
||||
}
|
||||
@@ -190,23 +190,72 @@ public class SysLoginController {
|
||||
return ">>:" + sysUserService.loginPlus(sysUser, LoginType.CAS, request);
|
||||
}
|
||||
|
||||
@At(value = "/platform/wxwork/oauth2/callback", top = true)
|
||||
@At(value = {"/platform/qywechat/oauth", "/platform/qywechat"}, top = true)
|
||||
@Ok("re")
|
||||
public String qywechatOauth(@Param("redirect") String redirect, HttpServletRequest request) {
|
||||
if (!"prd".equalsIgnoreCase(conf.get("nutz.profiles.active")) || !conf.getBoolean("wxwork.enable", false)) {
|
||||
return ">>:/platform/home";
|
||||
}
|
||||
String state = UUID.randomUUID().toString();
|
||||
request.getSession().setAttribute("zjnuWxworkState", state);
|
||||
String callback = Globals.AppDomain + conf.get("wxwork.redirectUri");
|
||||
if (StrUtil.isNotBlank(redirect)) {
|
||||
callback += "?redirect=" + URLEncoder.encode(redirect, StandardCharsets.UTF_8);
|
||||
}
|
||||
return ">>:https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + conf.get("wxwork.corpId")
|
||||
+ "&redirect_uri=" + URLEncoder.encode(callback, StandardCharsets.UTF_8)
|
||||
+ "&response_type=code&scope=snsapi_base&state=" + state + "#wechat_redirect";
|
||||
}
|
||||
|
||||
private String getZjnuWxworkToken() {
|
||||
String cacheKey = RedisConstant.REDIS_KEY_WX_WORK_TOKEN + conf.get("wxwork.corpId");
|
||||
String token = redisService.get(cacheKey);
|
||||
if (StrUtil.isNotBlank(token)) {
|
||||
return token;
|
||||
}
|
||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + conf.get("wxwork.corpId")
|
||||
+ "&corpsecret=" + conf.get("wxwork.corpSecret");
|
||||
JSONObject result = JSONUtil.parseObj(HttpUtil.get(url));
|
||||
token = result.getStr("access_token");
|
||||
if (!Integer.valueOf(0).equals(result.getInt("errcode")) || StrUtil.isBlank(token)) {
|
||||
throw new BaseException("????????????");
|
||||
}
|
||||
redisService.setex(cacheKey, Math.max(1, result.getInt("expires_in", 7200) - 200), token);
|
||||
return token;
|
||||
}
|
||||
|
||||
@At(value = {"/platform/wxwork/oauth2/callback", "/platform/qywechat/getCode"}, top = true)
|
||||
@Ok("re")
|
||||
@ApiOperation("企业微信登录回调")
|
||||
public String wxworkOAuth2(@Param("code") String code, @Param("redirect") String redirect, HttpServletRequest request) {
|
||||
if (StrUtil.isBlank(code)) {
|
||||
return ">>:/platform/home";
|
||||
}
|
||||
String token = redisService.get(RedisConstant.REDIS_KEY_WX_WORK_TOKEN);
|
||||
boolean zjnu = "prd".equalsIgnoreCase(conf.get("nutz.profiles.active"));
|
||||
if (zjnu) {
|
||||
Object expectedState = request.getSession().getAttribute("zjnuWxworkState");
|
||||
request.getSession().removeAttribute("zjnuWxworkState");
|
||||
if (!conf.getBoolean("wxwork.enable", false) || expectedState == null
|
||||
|| !expectedState.equals(request.getParameter("state"))) {
|
||||
return ">>:/platform/home/500";
|
||||
}
|
||||
}
|
||||
String token = zjnu ? getZjnuWxworkToken() : redisService.get(RedisConstant.REDIS_KEY_WX_WORK_TOKEN);
|
||||
if (StrUtil.isBlank(token)) {
|
||||
return ">>:/platform/home";
|
||||
}
|
||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=ACCESS_TOKEN&code=CODE";
|
||||
if (zjnu) {
|
||||
url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE";
|
||||
}
|
||||
url = url.replace("ACCESS_TOKEN", token).replace("CODE", code);
|
||||
String response = HttpUtil.get(url);
|
||||
JSONObject jsonObject = JSONUtil.parseObj(response);
|
||||
if (jsonObject.getInt("errcode") == 0) {
|
||||
String loginName = jsonObject.getStr("userid");
|
||||
String loginName = jsonObject.getStr(zjnu ? "UserId" : "userid");
|
||||
if (StrUtil.isBlank(loginName)) {
|
||||
return ">>:/platform/home/500";
|
||||
}
|
||||
sysUserService.checkThirdPlatformLoginName(loginName);
|
||||
Sys_user sysUser = sysUserService.loginByLoginName(loginName);
|
||||
return ">>:" + sysUserService.loginPlus(sysUser, LoginType.QI_YE_WECHAT, request);
|
||||
|
||||
@@ -496,6 +496,11 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
|
||||
|
||||
String redirect = request.getParameter("redirect");
|
||||
if (StrUtil.isNotBlank(redirect)) {
|
||||
if ("prd".equalsIgnoreCase(conf.get("nutz.profiles.active"))
|
||||
&& (redirect.equals(Globals.AppDomain) || redirect.startsWith(Globals.AppDomain + "/")
|
||||
|| redirect.startsWith(Globals.AppDomain + "?") || redirect.startsWith(Globals.AppDomain + "#"))) {
|
||||
return redirect;
|
||||
}
|
||||
return Globals.AppDomain + redirect;
|
||||
} else {
|
||||
return Globals.AppDomain + "/platform/home";
|
||||
|
||||
@@ -59,8 +59,12 @@ public class Globals {
|
||||
private SysTaskService sysTaskService;
|
||||
@Inject
|
||||
private PropertiesProxy conf;
|
||||
private static String productionAppDomain;
|
||||
|
||||
public void init() {
|
||||
if ("prd".equalsIgnoreCase(conf.get("nutz.profiles.active"))) {
|
||||
productionAppDomain = conf.get("custom.app-domain");
|
||||
}
|
||||
initSysConfig(sysConfigService);
|
||||
initRoute(sysRouteService);
|
||||
initTask(sysTaskService);
|
||||
@@ -95,6 +99,9 @@ public class Globals {
|
||||
default -> Globals.MyConfig.put(sysConfig.getConfigKey(), sysConfig.getConfigValue());
|
||||
}
|
||||
}
|
||||
if (Strings.isNotBlank(productionAppDomain)) {
|
||||
Globals.AppDomain = productionAppDomain;
|
||||
}
|
||||
}
|
||||
|
||||
public static void initRoute(SysRouteService sysRouteService) {
|
||||
|
||||
@@ -188,7 +188,10 @@ public class WkFailProcessor extends ViewProcessor {
|
||||
|
||||
if (Globals.sso) {
|
||||
//1.判断是否为企业微信浏览器并且对接了企业微信
|
||||
if (browserPlatform == BrowserPlatform.QI_YE_WEI_XIN && propertiesProxy.getBoolean("wxwork.enable", false)) {
|
||||
if (browserPlatform == BrowserPlatform.QI_YE_WEI_XIN && propertiesProxy.getBoolean("wxwork.enable", false)
|
||||
&& "prd".equalsIgnoreCase(propertiesProxy.get("nutz.profiles.active"))) {
|
||||
new ServerRedirectView("/platform/qywechat/oauth?redirect=" + redirect).render(request, response, null);
|
||||
} else if (browserPlatform == BrowserPlatform.QI_YE_WEI_XIN && propertiesProxy.getBoolean("wxwork.enable", false)) {
|
||||
//进行企业微信授权
|
||||
// String token = getWxWorkToken();
|
||||
// if (StrUtil.isNotBlank(token)) {
|
||||
|
||||
@@ -23,21 +23,21 @@
|
||||
|
||||
sdk:
|
||||
wxwork:
|
||||
enable: false
|
||||
corpId: wwaca81b3016b9a58c
|
||||
corpSecret: Auc7919Su1Uds5ZErfZybBrt-8FkP5NA-dldZyQuOrM
|
||||
agentId: 1000131
|
||||
redirectUri: /platform/wxwork/oauth2/callback
|
||||
enable: true
|
||||
corpId: 'ww5386df99fd3b6b0f'
|
||||
corpSecret: 'HpSptE9wKZRq_c_kemAPJc0AfXkNSevpfYCJd1TTgrI'
|
||||
agentId: ''
|
||||
redirectUri: /platform/qywechat/getCode
|
||||
wx:
|
||||
enable: false
|
||||
appID: wx4f65ff5f1b72e99d
|
||||
appSecret: a65cec4fb69980bd88258fc8433a3eef
|
||||
appID: 'MOCK_ZJNU_WX_APP_ID'
|
||||
appSecret: 'MOCK_ZJNU_WX_APP_SECRET'
|
||||
redirectUri: /platform/wx/oauth2/callback
|
||||
cas:
|
||||
enable: true
|
||||
server-url-prefix: https://authserver.zjnu.edu.cn/authserver
|
||||
server-login-url: https://authserver.zjnu.edu.cn/authserver/login
|
||||
qi-wx-server-login-url: httos:/cas.whcp.eou.cn/lyuapServer/wechatauz/wxAuthRedirect
|
||||
qi-wx-server-login-url: https://authserver.zjnu.edu.cn/authserver/login
|
||||
client-host-url: https://lxy.zjnu.edu.cn
|
||||
client-call-back-url: /sso/login
|
||||
validation-type: cas
|
||||
@@ -48,6 +48,7 @@ sdk:
|
||||
bucket: zjnu
|
||||
|
||||
custom:
|
||||
app-domain: https://lxy.zjnu.edu.cn
|
||||
spdb:
|
||||
bab7:
|
||||
url: http://localhost:8888/supplierOpenApi/pointOrder/queryOrderInfo
|
||||
@@ -55,26 +56,28 @@ custom:
|
||||
keyHex: 00112233445566778899aabbccddeeff
|
||||
ivHex: 0102030405060708090a0b0c0d0e0f10
|
||||
data-center:
|
||||
grant_type: password
|
||||
scope: read
|
||||
username: 3848A3C738EFBB2C2E76E0D59B419DACA16A80F3AB0354CD
|
||||
password: 3848A3C738EFBB2C2E76E0D59B419DACA16A80F3AB0354CD
|
||||
token-url: https://bd.whcp.edu.cn/sjjkfwpt/api/bd-api/oauth/token
|
||||
grant_type: ''
|
||||
scope: ''
|
||||
username: ''
|
||||
password: ''
|
||||
token-url: ''
|
||||
urls:
|
||||
teacher: http://mdm.zjnu.edu.cn/do/api/call/lxyxt_jzgjbxx
|
||||
unit: http://mdm.zjnu.edu.cn/do/api/call/lxyxt_dwxx
|
||||
msg:
|
||||
platform:
|
||||
enabled: false
|
||||
base-url: https://msg.cug.edu.cn
|
||||
tp-name: nwszl.cug.edu.cn
|
||||
default-send-user-id: 790036
|
||||
default-send-user-name: 周斐霏
|
||||
default-send-unit-id: 421
|
||||
default-send-unit-name: 工会
|
||||
enabled: true
|
||||
app-id: 'MSG45363193'
|
||||
app-password: 'OGQxNzVmOTJkZjM5NzJhZDg1MDNiZGM0MDQ5ZTJlNDY'
|
||||
base-url: http://xxt.zjnu.edu.cn
|
||||
tp-name: ''
|
||||
default-send-user-id: ''
|
||||
default-send-user-name: ''
|
||||
default-send-unit-id: ''
|
||||
default-send-unit-name: ''
|
||||
default-send-user-sign: ''
|
||||
default-template-id: 1978744168869937153
|
||||
raw-secret-key: Z21kbDlwYWJ4c2Vtbnk4NjlxeQ==
|
||||
default-template-id: ''
|
||||
raw-secret-key: ''
|
||||
encrypted-secret-key: ''
|
||||
connect-timeout: 5000
|
||||
read-timeout: 10000
|
||||
|
||||
Reference in New Issue
Block a user