diff --git a/demo/pom.xml b/demo/pom.xml
index 8a1ce5f..c67d8e7 100644
--- a/demo/pom.xml
+++ b/demo/pom.xml
@@ -6,7 +6,7 @@
com.tiesheng
tiesheng-parent
- 0.0.4
+ 0.0.5
demo
@@ -21,7 +21,7 @@
com.tiesheng
tiesheng-web
- 0.0.4
+ 0.0.5
diff --git a/demo/src/main/resources/application.yml b/demo/src/main/resources/application.yml
index dba2ee9..7936be6 100644
--- a/demo/src/main/resources/application.yml
+++ b/demo/src/main/resources/application.yml
@@ -10,13 +10,15 @@ spring:
platform:
wxmp:
- app-id: wx7830e1085881b432
- app-secret: d7757f980b38b5bd8125d45767c40e04
+ global:
+ app-id: wx7830e1085881b432
+ app-secret: d7757f980b38b5bd8125d45767c40e04
tiesheng:
token:
ignores:
"1111":
- id: "1111"
+ id: "1111"
global:
version: 2
+ host: http://localhost:8080
diff --git a/pom.xml b/pom.xml
index 672ec69..831e879 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.tiesheng
tiesheng-parent
- 0.0.4
+ 0.0.5
pom
tiesheng
杭州铁晟科技有限公司基础依赖
@@ -24,8 +24,7 @@
tiesheng-web
tiesheng-util
tiesheng-poi
- tiesheng-ding
- tiesheng-wxmp
+ tiesheng-platform
tiesheng-message
tiesheng-encrypt
tiesheng-annotation
diff --git a/tiesheng-annotation/pom.xml b/tiesheng-annotation/pom.xml
index d01b91c..4e34d3b 100644
--- a/tiesheng-annotation/pom.xml
+++ b/tiesheng-annotation/pom.xml
@@ -6,7 +6,7 @@
com.tiesheng
tiesheng-parent
- 0.0.4
+ 0.0.5
tiesheng-annotation
diff --git a/tiesheng-db-migration/pom.xml b/tiesheng-db-migration/pom.xml
index 7b1d3cc..a12f578 100644
--- a/tiesheng-db-migration/pom.xml
+++ b/tiesheng-db-migration/pom.xml
@@ -6,7 +6,7 @@
com.tiesheng
tiesheng-parent
- 0.0.4
+ 0.0.5
tiesheng-db-migration
diff --git a/tiesheng-ding/pom.xml b/tiesheng-ding/pom.xml
deleted file mode 100644
index 38406f1..0000000
--- a/tiesheng-ding/pom.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
- 4.0.0
-
- com.tiesheng
- tiesheng-parent
- 0.0.4
-
-
- tiesheng-ding
-
-
- 8
- 8
- UTF-8
-
-
-
-
- com.tiesheng
- tiesheng-util
- ${project.parent.version}
-
-
-
- org.springframework.boot
- spring-boot-starter-web
- compile
-
-
-
- com.tiesheng
- tiesheng-annotation
- ${project.parent.version}
-
-
-
-
-
diff --git a/tiesheng-ding/src/main/java/com/tiesheng/ding/controller/PlatformDingController.java b/tiesheng-ding/src/main/java/com/tiesheng/ding/controller/PlatformDingController.java
deleted file mode 100644
index 4677c70..0000000
--- a/tiesheng-ding/src/main/java/com/tiesheng/ding/controller/PlatformDingController.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.tiesheng.ding.controller;
-
-import com.tiesheng.annotation.token.TokenIgnore;
-import com.tiesheng.ding.config.DingConfig;
-import com.tiesheng.ding.pojos.DingJsapiSignature;
-import com.tiesheng.util.pojos.ApiResp;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * @author hao
- */
-@RestController
-@RequestMapping("/platform/ding")
-public class PlatformDingController {
-
- @Autowired
- DingConfig dingConfig;
-
- /**
- * 钉钉授权jssdk
- *
- * @param url
- * @return
- */
- @GetMapping("/jssdk/{service}")
- @TokenIgnore
- public ApiResp dingJssdk(@PathVariable String service, String url) {
- DingJsapiSignature jsapiSignature = dingConfig.createJsapiSignature(service, url);
- return ApiResp.respOK(jsapiSignature);
- }
-
-}
diff --git a/tiesheng-encrypt/pom.xml b/tiesheng-encrypt/pom.xml
index 413daa0..e4f1442 100644
--- a/tiesheng-encrypt/pom.xml
+++ b/tiesheng-encrypt/pom.xml
@@ -6,7 +6,7 @@
com.tiesheng
tiesheng-parent
- 0.0.4
+ 0.0.5
tiesheng-encrypt
diff --git a/tiesheng-login/pom.xml b/tiesheng-login/pom.xml
index 8dc530f..b27385e 100644
--- a/tiesheng-login/pom.xml
+++ b/tiesheng-login/pom.xml
@@ -6,7 +6,7 @@
com.tiesheng
tiesheng-parent
- 0.0.4
+ 0.0.5
tiesheng-login
@@ -28,24 +28,16 @@
com.tiesheng
- tiesheng-ding
+ tiesheng-annotation
${project.parent.version}
com.tiesheng
- tiesheng-wxmp
+ tiesheng-platform
${project.parent.version}
-
-
- com.baomidou
- mybatis-plus-boot-starter
- ${mybatis-plus.version}
- compile
-
-
diff --git a/tiesheng-login/src/main/java/com/tiesheng/login/LoginAutoImportSelector.java b/tiesheng-login/src/main/java/com/tiesheng/login/LoginAutoImportSelector.java
index 900b29e..7f69db2 100644
--- a/tiesheng-login/src/main/java/com/tiesheng/login/LoginAutoImportSelector.java
+++ b/tiesheng-login/src/main/java/com/tiesheng/login/LoginAutoImportSelector.java
@@ -1,7 +1,8 @@
package com.tiesheng.login;
-import org.mybatis.spring.annotation.MapperScan;
+import com.tiesheng.platform.PlatformAutoImportSelector;
import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Import;
/**
* @author hao
@@ -10,6 +11,6 @@ import org.springframework.context.annotation.ComponentScan;
@ComponentScan({
"com.tiesheng.login.**.*",
})
-@MapperScan("com.tiesheng.login.mapper")
+@Import(PlatformAutoImportSelector.class)
public class LoginAutoImportSelector {
}
diff --git a/tiesheng-login/src/main/java/com/tiesheng/login/config/TieshengLoginConfigurer.java b/tiesheng-login/src/main/java/com/tiesheng/login/config/TieshengLoginConfigurer.java
new file mode 100644
index 0000000..5db772e
--- /dev/null
+++ b/tiesheng-login/src/main/java/com/tiesheng/login/config/TieshengLoginConfigurer.java
@@ -0,0 +1,30 @@
+package com.tiesheng.login.config;
+
+import com.tiesheng.login.config.token.bean.TokenBean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author hao
+ */
+@Configuration
+public interface TieshengLoginConfigurer {
+
+ /**
+ * 执行登录
+ *
+ * @return
+ */
+ TokenBean doLogin(String appId, String uniqueId, String platfrom, String info);
+
+
+ /**
+ * 授权登录回调
+ *
+ * @param tokenBean
+ */
+ void onLoginRedirect(TokenBean bean, String extra, HttpServletResponse response);
+
+
+}
diff --git a/tiesheng-login/src/main/java/com/tiesheng/login/config/token/TsTokenConfig.java b/tiesheng-login/src/main/java/com/tiesheng/login/config/token/TsTokenConfig.java
index f8a76be..f8ed6e4 100644
--- a/tiesheng-login/src/main/java/com/tiesheng/login/config/token/TsTokenConfig.java
+++ b/tiesheng-login/src/main/java/com/tiesheng/login/config/token/TsTokenConfig.java
@@ -62,19 +62,6 @@ public class TsTokenConfig {
return ignores.get(token);
}
- /**
- * 设置token
- */
- public String toToken(String id, String environmentType, String service, String extra) {
- return JWT.create()
- .setPayload("id", id)
- .setPayload("environmentType", environmentType)
- .setPayload("service", service)
- .setPayload("extra", extra)
- .setPayload("time", System.currentTimeMillis() + expireHours * 1000 * 60 * 60)
- .setKey(getEncryptKey().getBytes())
- .sign();
- }
/**
* 验证token
diff --git a/tiesheng-login/src/main/java/com/tiesheng/login/config/token/bean/TokenBean.java b/tiesheng-login/src/main/java/com/tiesheng/login/config/token/bean/TokenBean.java
index 59ada0e..5c11159 100644
--- a/tiesheng-login/src/main/java/com/tiesheng/login/config/token/bean/TokenBean.java
+++ b/tiesheng-login/src/main/java/com/tiesheng/login/config/token/bean/TokenBean.java
@@ -1,5 +1,9 @@
package com.tiesheng.login.config.token.bean;
+import cn.hutool.extra.spring.SpringUtil;
+import cn.hutool.jwt.JWT;
+import com.tiesheng.login.config.token.TsTokenConfig;
+
/**
* @author hao
*/
@@ -20,6 +24,22 @@ public class TokenBean {
this.extra = "";
}
+
+ /**
+ * 设置token
+ */
+ public String toToken() {
+ TsTokenConfig tsTokenConfig = SpringUtil.getBean(TsTokenConfig.class);
+ return JWT.create()
+ .setPayload("id", getId())
+ .setPayload("environmentType", getEnvironmentType())
+ .setPayload("service", getService())
+ .setPayload("extra", getExtra())
+ .setPayload("time", System.currentTimeMillis() + tsTokenConfig.getExpireHours() * 1000 * 60 * 60)
+ .setKey(tsTokenConfig.getEncryptKey().getBytes())
+ .sign();
+ }
+
///////////////////////////////////////////////////////////////////////////
// setter\getter
///////////////////////////////////////////////////////////////////////////
diff --git a/tiesheng-login/src/main/java/com/tiesheng/login/controller/LoginController.java b/tiesheng-login/src/main/java/com/tiesheng/login/controller/LoginController.java
new file mode 100644
index 0000000..3436e7c
--- /dev/null
+++ b/tiesheng-login/src/main/java/com/tiesheng/login/controller/LoginController.java
@@ -0,0 +1,201 @@
+package com.tiesheng.login.controller;
+
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.URLUtil;
+import com.alibaba.fastjson.JSON;
+import com.tiesheng.annotation.token.TokenIgnore;
+import com.tiesheng.login.config.token.TsTokenConfig;
+import com.tiesheng.login.config.token.bean.TokenBean;
+import com.tiesheng.login.pojos.dto.UniqueIndexDTO;
+import com.tiesheng.login.service.LoginService;
+import com.tiesheng.platform.config.ding.PlatformDingConfig;
+import com.tiesheng.platform.config.ding.bean.DingJsapiSignature;
+import com.tiesheng.platform.config.ding.bean.DingUserInfo;
+import com.tiesheng.platform.config.wxmp.PlatformWxmpConfig;
+import com.tiesheng.platform.config.wxmp.bean.WxJsapiSignature;
+import com.tiesheng.platform.config.wxmp.bean.WxUserInfo;
+import com.tiesheng.util.exception.ApiException;
+import com.tiesheng.util.pojos.ApiResp;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * @author hao
+ */
+@RestController
+@RequestMapping("/login")
+public class LoginController {
+
+
+ @Autowired
+ PlatformWxmpConfig platformWxmpConfig;
+ @Autowired
+ PlatformDingConfig platformDingConfig;
+ @Autowired
+ LoginService loginService;
+ @Autowired
+ TsTokenConfig tsTokenConfig;
+
+
+ /**
+ * 唯一值登录方式,如学号,手机号等
+ *
+ * @return
+ */
+ @GetMapping("/unique/redirect")
+ @TokenIgnore
+ public void uniqueIndex(UniqueIndexDTO dto, HttpServletResponse response) {
+ loginService.checkLoginConfigurer(s -> {
+ TokenBean tokenBean = s.doLogin("unique_index_" + dto.getPlatform(),
+ dto.getNo(), dto.getPlatform(), dto.getInfo());
+ s.onLoginRedirect(tokenBean, dto.getExtra(), response);
+ });
+ }
+
+
+ /**
+ * 授权登录
+ *
+ * @param dto
+ * @return
+ */
+ @PostMapping("/unique/index")
+ @TokenIgnore
+ public ApiResp uniqueIndex(@RequestBody UniqueIndexDTO dto) {
+ AtomicReference tokenBeanAtomicReference = new AtomicReference<>();
+ loginService.checkLoginConfigurer(s -> {
+ tokenBeanAtomicReference.set(s.doLogin("unique_index_" + dto.getPlatform(),
+ dto.getNo(), dto.getPlatform(), dto.getInfo()));
+ });
+ TokenBean tokenBean = tokenBeanAtomicReference.get();
+ if (tokenBean == null) {
+ throw new ApiException("登录失败");
+ }
+ return ApiResp.respOK(tokenBean.toToken());
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // 钉钉相关授权
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * 钉钉授权登录
+ *
+ * @param service
+ * @param extra
+ * @param response
+ */
+ @GetMapping("/ding/index/{service}")
+ @TokenIgnore
+ public void dingIndex(@PathVariable String service, String extra, HttpServletResponse response) {
+ if (StrUtil.isEmpty(extra)) {
+ extra = "";
+ }
+ Map map = MapUtil.newHashMap();
+ map.put("corpId", platformDingConfig.getConfigBean(service).getCorpId());
+ map.put("service", service);
+ map.put("extra", extra);
+ loginService.checkLoginConfigurer(s -> {
+ String query = URLUtil.buildQuery(map, Charset.defaultCharset());
+ String configUrl = loginService.buildPath("/ding/index.html?" + query);
+ try {
+ response.sendRedirect(configUrl);
+ } catch (IOException ignored) {
+ }
+ });
+ }
+
+
+ /**
+ * 钉钉授权回调
+ *
+ * @param service
+ */
+ @RequestMapping("/ding/oauth2/{service}")
+ @TokenIgnore
+ public void dingOauth2(@PathVariable String service, String code, String extra, HttpServletResponse response) {
+ loginService.checkLoginConfigurer(configurer -> {
+ String ddUserId = platformDingConfig.getUserIdByCode(service, code);
+ DingUserInfo dingUserInfo = platformDingConfig.topapiV2UserGet(service, ddUserId);
+ TokenBean tokenBean = configurer.doLogin(dingUserInfo.getAppId(), dingUserInfo.getUserid(), "ding",
+ JSON.toJSONString(dingUserInfo));
+ configurer.onLoginRedirect(tokenBean, extra, response);
+ });
+ }
+
+
+ /**
+ * 钉钉授权jssdk
+ *
+ * @param url
+ * @return
+ */
+ @GetMapping("/ding/jssdk/{service}")
+ @TokenIgnore
+ public ApiResp dingJssdk(@PathVariable String service, String url) {
+ DingJsapiSignature jsapiSignature = platformDingConfig.createJsapiSignature(service, url);
+ return ApiResp.respOK(jsapiSignature);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // 微信相关
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * 微信授权登录
+ *
+ * @return
+ */
+ @RequestMapping("/wxmp/index/{service}")
+ @TokenIgnore
+ public void wxmpIndex(@PathVariable String service, String extra, HttpServletResponse response) throws IOException {
+ if (StrUtil.isEmpty(extra)) {
+ extra = "";
+ }
+ String configUrl = loginService.buildPath("/auth/wxmp/oauth2/" + service + "?extra=" + extra);
+ String authorizationUrl = platformWxmpConfig.buildAuthorizationUrl(service, configUrl, "snsapi_userinfo");
+ response.sendRedirect(authorizationUrl);
+ }
+
+
+ /**
+ * 微信授权回调
+ *
+ * @param code
+ */
+ @RequestMapping("/wxmp/oauth2/{service}")
+ @TokenIgnore
+ public void wxmpOauth2(@PathVariable String service, String code, String extra, HttpServletResponse response) {
+ loginService.checkLoginConfigurer(configurer -> {
+ WxUserInfo wxUserInfo = platformWxmpConfig.getOAuth2AccessToken(service, code);
+ TokenBean tokenBean = configurer.doLogin(wxUserInfo.getAppId(), wxUserInfo.getOpenid(), "wxmp", JSON.toJSONString(wxUserInfo));
+ configurer.onLoginRedirect(tokenBean, extra, response);
+ });
+ }
+
+
+ /**
+ * 微信授权jssdk
+ *
+ * @param url
+ * @return
+ */
+ @GetMapping("/wxmp/jssdk/{service}")
+ @TokenIgnore
+ public ApiResp wxmpJssdk(@PathVariable String service, String url) {
+ WxJsapiSignature jsapiSignature = platformWxmpConfig.createJsapiSignature(service, url);
+ return ApiResp.respOK(jsapiSignature);
+ }
+
+
+}
diff --git a/tiesheng-login/src/main/java/com/tiesheng/login/controller/LoginUserController.java b/tiesheng-login/src/main/java/com/tiesheng/login/controller/LoginUserController.java
deleted file mode 100644
index 842bf00..0000000
--- a/tiesheng-login/src/main/java/com/tiesheng/login/controller/LoginUserController.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.tiesheng.login.controller;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * @author hao
- */
-@RestController
-@RequestMapping("/login/user")
-public class LoginUserController {
-}
diff --git a/tiesheng-login/src/main/java/com/tiesheng/login/pojos/dto/UniqueIndexDTO.java b/tiesheng-login/src/main/java/com/tiesheng/login/pojos/dto/UniqueIndexDTO.java
new file mode 100644
index 0000000..b104ff4
--- /dev/null
+++ b/tiesheng-login/src/main/java/com/tiesheng/login/pojos/dto/UniqueIndexDTO.java
@@ -0,0 +1,50 @@
+package com.tiesheng.login.pojos.dto;
+
+import cn.hutool.core.util.StrUtil;
+
+public class UniqueIndexDTO {
+
+ private String no;
+ private String platform;
+ private String extra;
+ private String info;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // setter\getter
+ ///////////////////////////////////////////////////////////////////////////
+
+ public String getNo() {
+ return no;
+ }
+
+ public void setNo(String no) {
+ this.no = no;
+ }
+
+ public String getPlatform() {
+ return platform;
+ }
+
+ public void setPlatform(String platform) {
+ this.platform = platform;
+ }
+
+ public String getExtra() {
+ if (StrUtil.isEmpty(extra)) {
+ extra = "";
+ }
+ return extra;
+ }
+
+ public void setExtra(String extra) {
+ this.extra = extra;
+ }
+
+ public String getInfo() {
+ return info;
+ }
+
+ public void setInfo(String info) {
+ this.info = info;
+ }
+}
diff --git a/tiesheng-login/src/main/java/com/tiesheng/login/service/LoginLogService.java b/tiesheng-login/src/main/java/com/tiesheng/login/service/LoginLogService.java
deleted file mode 100644
index 6aca26d..0000000
--- a/tiesheng-login/src/main/java/com/tiesheng/login/service/LoginLogService.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.tiesheng.login.service;
-
-import cn.hutool.extra.servlet.ServletUtil;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.tiesheng.login.mapper.CoreLogLoginMapper;
-import com.tiesheng.login.pojos.dao.CoreLogLogin;
-import com.tiesheng.util.ServletKit;
-import com.tiesheng.util.ip2region.DataBlock;
-import com.tiesheng.util.ip2region.Ip2Region;
-import org.springframework.stereotype.Service;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * @author hao
- */
-@Service
-public class LoginLogService extends ServiceImpl {
-
-
- /**
- * 获取
- *
- * @param userId
- */
- public void addLog(String userId, String platform) {
-
- HttpServletRequest request = ServletKit.getRequest();
- String ip = ServletUtil.getClientIP(request);
-
- CoreLogLogin login = new CoreLogLogin();
- login.setUserId(userId);
- login.setPlatform(platform);
-
- login.setIp(ip);
- DataBlock dataBlock = Ip2Region.getInstance().btreeSearch(ip);
- login.setAddress(dataBlock.getRegion());
- save(login);
- }
-
-
-}
diff --git a/tiesheng-login/src/main/java/com/tiesheng/login/service/LoginService.java b/tiesheng-login/src/main/java/com/tiesheng/login/service/LoginService.java
new file mode 100644
index 0000000..ef12eae
--- /dev/null
+++ b/tiesheng-login/src/main/java/com/tiesheng/login/service/LoginService.java
@@ -0,0 +1,57 @@
+package com.tiesheng.login.service;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.tiesheng.login.config.TieshengLoginConfigurer;
+import com.tiesheng.util.exception.ApiException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.function.Consumer;
+
+/**
+ * @author hao
+ */
+@Service
+public class LoginService {
+
+ @Value("${tiesheng.global.host}")
+ String globalHost;
+ @Autowired(required = false)
+ TieshengLoginConfigurer tieshengLoginConfigurer;
+
+
+ /**
+ * 检查配置
+ */
+ public void checkLoginConfigurer(Consumer consumer) {
+ if (tieshengLoginConfigurer == null) {
+ throw new ApiException("未配置登录逻辑");
+ }
+ consumer.accept(tieshengLoginConfigurer);
+ }
+
+ public String getContextPath() {
+ String context = SpringUtil.getProperty("server.servlet.context-path");
+ if (StrUtil.isEmpty(context)) {
+ context = "";
+ }
+
+ return context;
+ }
+
+ public String buildPath(String path) {
+ if (StrUtil.isEmpty(path)) {
+ path = "";
+ }
+
+ if (!StrUtil.isEmpty(this.globalHost) && !StrUtil.startWith(path, "http")) {
+ path = this.globalHost + this.getContextPath() + path;
+ }
+
+ return path;
+ }
+
+
+}
diff --git a/tiesheng-login/src/main/resources/static/ding/dingtalk.open.js b/tiesheng-login/src/main/resources/static/ding/dingtalk.open.js
new file mode 100644
index 0000000..d6f9219
--- /dev/null
+++ b/tiesheng-login/src/main/resources/static/ding/dingtalk.open.js
@@ -0,0 +1 @@
+(function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.dd=t():e.dd=t()})(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=610)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(2),o=n(166),i=n(2);t.ENV_ENUM=i.ENV_ENUM;var a=n(3);n(172),t.ddSdk=new a.Sdk(r.getENV(),o.log)},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addWatchParamsDeal=function(e){var t=Object.assign({},e);return t.watch=!0,t},t.addDefaultCorpIdParamsDeal=function(e){var t=Object.assign({},e);return t.corpId="corpId",t},t.genDefaultParamsDealFn=function(e){var t=Object.assign({},e);return function(e){return Object.assign(t,e)}},t.forceChangeParamsDealFn=function(e){var t=Object.assign({},e);return function(e){return Object.assign(e,t)}},t.genBoolResultDealFn=function(e){return function(t){var n=Object.assign({},t);return e.forEach(function(e){void 0!==n[e]&&(n[e]=!!n[e])}),n}},t.genBizStoreParamsDealFn=function(e){var t=Object.assign({},e);return"string"!=typeof t.params?(t.params=JSON.stringify(t),t):t}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(3),o=n(3);t.ENV_ENUM=o.ENV_ENUM,t.APP_TYPE=o.APP_TYPE;var i=n(169);t.getUA=function(){var e="";try{"undefined"!=typeof navigator&&(e=navigator&&(navigator.userAgent||navigator.swuserAgent)||"")}catch(t){e=""}return e},t.getENV=function(){var e=t.getUA(),n=/DingTalk/i.test(e)||i.default.isDingTalk,o=/iPhone|iPad|iPod|iOS/i.test(e)&&n||i.default.isWeexiOS,a=/Android/i.test(e)&&n||i.default.isWeexAndroid,s=/Nebula/i.test(e)&&n||"object"==typeof dd&&"function"==typeof dd.dtBridge,d=/dd-web/i.test(e),u=r.APP_TYPE.WEB;d?u=r.APP_TYPE.WEBVIEW_IN_MINIAPP:s?u=r.APP_TYPE.MINI_APP:(i.default.isWeexiOS||i.default.isWeexAndroid)&&(u=r.APP_TYPE.WEEX);var c,l="*",f=e.match(/AliApp\(\w+\/([a-zA-Z0-9.-]+)\)/);null===f&&(f=e.match(/DingTalk\/([a-zA-Z0-9.-]+)/));var v;f&&f[1]&&(v=f[1]);var p="";if("undefined"!=typeof name&&(p=name),p)try{var _=JSON.parse(p);_.hostVersion&&(v=_.hostVersion),l=_.language||navigator.language||"*",c=_.containerId}catch(e){}var E,N=!!c;return E=o?r.ENV_ENUM.ios:a?r.ENV_ENUM.android:N?r.ENV_ENUM.pc:r.ENV_ENUM.notInDingTalk,{platform:E,version:v,appType:u,language:l}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(175);t.APP_TYPE=r.APP_TYPE,t.LogLevel=r.LogLevel,t.isFunction=r.isFunction,t.compareVersion=r.compareVersion,t.ENV_ENUM=r.ENV_ENUM;var o=function(){function e(e,t){var n=this;this.configJsApiList=[],this.hadConfig=!1,this.p={},this.config$=new Promise(function(e,t){n.p.reject=t,n.p.resolve=e}),this.logQueue=[],this.devConfig={debug:!1},this.platformConfigMap={},this.invokeAPIConfigMapByMethod={},this.isBridgeDrity=!0,this.getExportSdk=function(){return n.exportSdk},this.setAPI=function(e,t){n.invokeAPIConfigMapByMethod[e]=t},this.setPlatform=function(e){n.isBridgeDrity=!0,n.platformConfigMap[e.platform]=e,e.platform===n.env.platform&&e.bridgeInit().catch(function(e){n.customLog(r.LogLevel.WARNING,["auto bridgeInit error",e||""])})},this.getPlatformConfigMap=function(){return n.platformConfigMap},this.deleteApiConfig=function(e,t){var r=n.invokeAPIConfigMapByMethod[e];r&&delete r[t]},this.invokeAPI=function(e,t,o){void 0===t&&(t={}),void 0===o&&(o=!0),n.customLog(r.LogLevel.INFO,['==> "'+e+'" params: ',t]);var i=+new Date,a=i+"_"+Math.floor(1e3*Math.random());return n.devConfig.onBeforeInvokeAPI&&n.devConfig.onBeforeInvokeAPI({invokeId:a,method:e,params:t,startTime:i}),!1===n.devConfig.isAuthApi&&(o=!1),n.bridgeInitFn().then(function(s){var d=n.invokeAPIConfigMapByMethod[e],u=!0===n.devConfig.isDisableDeal||n.devConfig.disbaleDealApiWhiteList&&-1!==n.devConfig.disbaleDealApiWhiteList.indexOf(e);if(d||!o){var c;if(d&&(c=d[n.env.platform]),c||!o){var l={};l=!u&&c&&c.paramsDeal&&r.isFunction(c.paramsDeal)?c.paramsDeal(t):Object.assign({},t);var f=function(e){return!u&&c&&c.resultDeal&&r.isFunction(c.resultDeal)?c.resultDeal(e):e};if(r.isFunction(l.onSuccess)){var v=l.onSuccess;l.onSuccess=function(e){v(f(e))}}return s(e,l).then(f,function(t){var i=n.hadConfig&&void 0===n.isReady&&-1!==n.configJsApiList.indexOf(e),a="object"==typeof t&&"string"==typeof t.errorCode&&t.errorCode===r.ERROR_CODE.no_permission,d="object"==typeof t&&"string"==typeof t.errorCode&&t.errorCode===r.ERROR_CODE.cancel,u=c&&c.vs&&n.env.version&&r.compareVersion(n.env.version,c.vs),v=(n.env.platform===r.ENV_ENUM.ios||n.env.platform===r.ENV_ENUM.android)&&i&&a,p=n.env.platform===r.ENV_ENUM.pc&&i&&(u&&!d&&o||a);return v||p?n.config$.then(function(){return s(e,l).then(f)}):Promise.reject(t)}).then(function(o){return n.devConfig.onAfterInvokeAPI&&n.devConfig.onAfterInvokeAPI({invokeId:a,method:e,params:t,payload:o,isSuccess:!0,startTime:i,duration:+new Date-i}),n.customLog(r.LogLevel.INFO,['<== "'+e+'" success result: ',o]),o},function(o){return n.devConfig.onAfterInvokeAPI&&n.devConfig.onAfterInvokeAPI({invokeId:a,method:e,params:t,payload:o,startTime:i,duration:+new Date-i,isSuccess:!1}),n.customLog(r.LogLevel.WARNING,['<== "'+e+'" fail result: ',o]),Promise.reject(o)})}var p='"'+e+'" do not support the current platform ('+n.env.platform+")";return n.customLog(r.LogLevel.ERROR,[p]),Promise.reject({errorCode:r.ERROR_CODE.jsapi_internal_error,errorMessage:p})}var p="This API method is not configured for the platform ("+n.env.platform+")";return n.customLog(r.LogLevel.ERROR,[p]),Promise.reject({errorCode:r.ERROR_CODE.jsapi_internal_error,errorMessage:p})})},this.customLog=function(e,t){var r={level:e,text:t,time:new Date};!0===n.devConfig.debug?n.customLogInstance(r):n.logQueue.push(r)},this.clearLogQueue=function(){n.logQueue.forEach(function(e){n.customLogInstance(e)}),n.logQueue=[]},this.customLogInstance=t,this.env=e,this.bridgeInitFn=function(){if(n.bridgeInitFnPromise&&!n.isBridgeDrity)return n.bridgeInitFnPromise;n.isBridgeDrity=!1;var t=n.platformConfigMap[e.platform];if(t)n.bridgeInitFnPromise=t.bridgeInit().catch(function(e){return n.customLog(r.LogLevel.ERROR,["\b\b\b\b\bJsBridge initialization fails, jsapi will not work"]),Promise.reject(e)});else{var o="Do not support the current environment:"+e.platform;n.customLog(r.LogLevel.WARNING,[o]),n.bridgeInitFnPromise=Promise.reject(new Error(o))}return n.bridgeInitFnPromise};var o=function(e){void 0===e&&(e={}),n.devConfig=Object.assign(n.devConfig,e),!0===e.debug&&n.clearLogQueue(),e.extraPlatform&&n.setPlatform(e.extraPlatform)};this.exportSdk={config:function(t){void 0===t&&(t={});var i=!0;Object.keys(t).forEach(function(e){-1===["debug","usePromise"].indexOf(e)&&(i=!1)}),i?(n.customLog(r.LogLevel.WARNING,["This is a deprecated feature, recommend use dd.devConfig"]),o(t)):n.hadConfig?n.customLog(r.LogLevel.WARNING,["Config has been executed"]):(t.jsApiList&&(n.configJsApiList=t.jsApiList),n.hadConfig=!0,n.bridgeInitFn().then(function(r){var o=n.platformConfigMap[e.platform],i=t;o.authParamsDeal&&(i=o.authParamsDeal(i)),r(o.authMethod,i).then(function(e){n.isReady=!0,n.p.resolve(e)}).catch(function(e){n.isReady=!1,n.p.reject(e)})},function(){n.customLog(r.LogLevel.ERROR,['\b\b\b\b\bJsBridge initialization failed and "dd.config" failed to call'])}))},devConfig:o,ready:function(e){!1===n.hadConfig?(n.customLog(r.LogLevel.WARNING,["You don 't use a dd.config, so you don't need to wrap dd.ready, recommend remove dd.ready"]),n.bridgeInitFn().then(function(){e()})):n.config$.then(function(t){e()})},error:function(e){n.config$.catch(function(t){e(t)})},on:function(t,r){n.bridgeInitFn().then(function(){n.platformConfigMap[e.platform].event.on(t,r)})},off:function(t,r){n.bridgeInitFn().then(function(){n.platformConfigMap[e.platform].event.off(t,r)})},env:e,checkJsApi:function(t){void 0===t&&(t={});var o={};return t.jsApiList&&t.jsApiList.forEach(function(t){var i=n.invokeAPIConfigMapByMethod[t];if(i){var a=i[e.platform];a&&a.vs&&e.version&&r.compareVersion(e.version,a.vs)&&(o[t]=!0)}o[t]||(o[t]=!1)}),Promise.resolve(o)},_invoke:function(e,t){return void 0===t&&(t={}),n.invokeAPI(e,t,!1)}}}return e}();t.Sdk=o},function(e,t,n){(function(t,n){e.exports=n()})(0,function(){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=579)}({179:function(e,t,n){"use strict";var r=n(181);e.exports=r},181:function(e,t,n){"use strict";var r=n(183),o=n(184),i=n(182),a=n(185),s=new i,d=!1,u="",c=null,l={},f=/{.*}/;try{var v=window.name.match(f);if(v&&v[0])var l=JSON.parse(v[0])}catch(e){l={}}l.hostOrigin&&".dingtalk.com"===l.hostOrigin.split(":")[1].slice(0-".dingtalk.com".length)&&l.containerId&&(d=!0,u=l.hostOrigin,c=l.containerId);var p={},_=new Promise(function(e,t){p._resolve=e,p._reject=t}),E={},N=null;window.top!==window&&(N=window.top,p._resolve()),E[a.SYS_INIT]=function(e){N=e.frameWindow,p._resolve(),e.respond({})},window.addEventListener("message",function(e){var t=e.data,n=e.origin;if(n===u)if("response"===t.type&&t.msgId){var r=t.msgId,i=s.getMsyById(r);i&&i.receiveResponse(t.body,!t.success)}else if("event"===t.type&&t.msgId){var r=t.msgId,i=s.getMsyById(r);i&&i.receiveEvent(t.eventName,t.body)}else if("request"===t.type&&t.msgId){var i=new o(e.source,n,t);E[i.methodName]&&E[i.methodName](i)}}),t.invokeAPI=function(e,t){var n=new r(c,e,t);return d&&_.then(function(){N&&N.postMessage(n.getPayload(),u),s.addPending(n)}),n};var P=null;t.addEventListener=function(e,n){P||(P=t.invokeAPI(a.SYS_EVENT,{})),P.addEventListener(e,n)},t.removeEventListener=function(e,t){P&&P.removeEventListener(e,t)}},182:function(e,t,n){"use strict";var r=function(){this.pendingMsgs={}};r.prototype.addPending=function(e){this.pendingMsgs[e.id]=e;var t=function(){delete this.pendingMsgs[e.id],e.removeEventListener("_finish",t)}.bind(this);e.addEventListener("_finish",t)},r.prototype.getMsyById=function(e){return this.pendingMsgs[e]},e.exports=r},183:function(e,t,n){"use strict";var r=n(574),o=n(573),i=0,a=Math.floor(1e3*Math.random()),s=function(){return 1e3*(1e3*a+Math.floor(1e3*Math.random()))+ ++i%1e3},d={code:408,reason:"timeout"},u={TIMEOUT:"_timeout",FINISH:"_finish"},c={timeout:-1},l=function(e,t,n,r){this.id=s(),this.methodName=t,this.containerId=e,this.option=o({},c,r);var n=n||{};this._p={},this.result=new Promise(function(e,t){this._p._resolve=e,this._p._reject=t}.bind(this)),this.callbacks={},this.plainMsg=this._handleMsg(n),this._eventsHandle={},this._timeoutTimer=null,this._initTimeout(),this.isFinish=!1};l.prototype._initTimeout=function(){this._clearTimeout(),this.option.timeout>0&&(this._timeoutTimer=setTimeout(function(){this.receiveEvent(u.TIMEOUT),this.receiveResponse(d,!0)}.bind(this),this.option.timeout))},l.prototype._clearTimeout=function(){clearTimeout(this._timeoutTimer)},l.prototype._handleMsg=function(e){var t={};return Object.keys(e).forEach(function(n){var o=e[n];"function"==typeof o&&"on"===n.slice(0,2)?this.callbacks[n]=o:t[n]=r(o)}.bind(this)),t},l.prototype.getPayload=function(){return{msgId:this.id,containerId:this.containerId,methodName:this.methodName,body:this.plainMsg,type:"request"}},l.prototype.receiveEvent=function(e,t){if(this.isFinish&&e!==u.FINISH)return!1;e!==u.FINISH&&e!==u.TIMEOUT&&this._initTimeout(),Array.isArray(this._eventsHandle[e])&&this._eventsHandle[e].forEach(function(e){try{e(t)}catch(e){console.error(t)}});var n="on"+e.charAt(0).toUpperCase()+e.slice(1);return this.callbacks[n]&&this.callbacks[n](t),!0},l.prototype.addEventListener=function(e,t){if(!e||"function"!=typeof t)throw"eventName is null or handle is not a function, addEventListener fail";Array.isArray(this._eventsHandle[e])||(this._eventsHandle[e]=[]),this._eventsHandle[e].push(t)},l.prototype.removeEventListener=function(e,t){if(!e||!t)throw"eventName is null or handle is null, invoke removeEventListener fail";if(Array.isArray(this._eventsHandle[e])){var n=this._eventsHandle[e].indexOf(t);-1!==n&&this._eventsHandle[e].splice(n,1)}},l.prototype.receiveResponse=function(e,t){if(!0===this.isFinish)return!1;this._clearTimeout();var t=!!t;return t?this._p._reject(e):this._p._resolve(e),setTimeout(function(){this.receiveEvent(u.FINISH)}.bind(this),0),this.isFinish=!0,!0},e.exports=l},184:function(e,t,n){"use strict";var r=function(e,t,n){if(this._msgId=n.msgId,this.frameWindow=e,this.methodName=n.methodName,this.clientOrigin=t,this.containerId=n.containerId,this.params=n.body,!this._msgId)throw"msgId not exist";if(!this.frameWindow)throw"frameWindow not exist";if(!this.methodName)throw"methodName not exits";if(!this.clientOrigin)throw"clientOrigin not exist";this.hasResponded=!1};r.prototype.respond=function(e,t){var t=!!t;if(!0!==this.hasResponded){var n={type:"response",success:!t,body:e,msgId:this._msgId};this.frameWindow.postMessage(n,this.clientOrigin),this.hasResponded=!0}},r.prototype.emit=function(e,t){var n={type:"event",eventName:e,body:t,msgId:this._msgId};this.frameWindow.postMessage(n,this.clientOrigin)},e.exports=r},185:function(e,t,n){"use strict";e.exports={SYS_EVENT:"SYS_openAPIContainerInitEvent",SYS_INIT:"SYS_openAPIContainerInit"}},4:function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n},572:function(e,t,n){(function(e,n){function r(e,t){return e.set(t[0],t[1]),e}function o(e,t){return e.add(t),e}function i(e,t){for(var n=-1,r=e.length;++n-1}function b(e,t){var n=this.__data__,r=x(n,e);return r<0?n.push([e,t]):n[r][1]=t,this}function g(e){var t=-1,n=e?e.length:0;for(this.clear();++t-1&&e%1==0&&e-1&&e%1==0&&e<=Ve}function ke(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function ye(e){return!!e&&"object"==typeof e}function be(e){return!!ke(e)&&(Me(e)||c(e)?Pt:tt).test(_e(e))}function ge(e){return"string"==typeof e||!Lt(e)&&ye(e)&&Nt.call(e)==Re}function Ie(e){var t=pe(e);if(!t&&!Pe(e))return B(e);var n=le(e),r=!!n,o=n||[],i=o.length;for(var a in e)!z(e,a)||r&&("length"==a||fe(a,i))||t&&"constructor"==a||o.push(a);return o}var Ae=200,Se="__lodash_hash_undefined__",Ve=9007199254740991,Ue="[object Arguments]",Oe="[object Boolean]",je="[object Date]",we="[object Function]",$e="[object GeneratorFunction]",De="[object Map]",Ce="[object Number]",Te="[object Object]",xe="[object RegExp]",Fe="[object Set]",Re="[object String]",We="[object Symbol]",Le="[object ArrayBuffer]",ze="[object DataView]",Be="[object Float32Array]",qe="[object Float64Array]",Ye="[object Int8Array]",Je="[object Int16Array]",Ge="[object Int32Array]",He="[object Uint8Array]",Ke="[object Uint8ClampedArray]",Xe="[object Uint16Array]",Qe="[object Uint32Array]",Ze=/[\\^$.*+?()[\]{}|]/g,et=/\w*$/,tt=/^\[object .+?Constructor\]$/,nt=/^(?:0|[1-9]\d*)$/,rt={};rt[Ue]=rt["[object Array]"]=rt[Le]=rt[ze]=rt[Oe]=rt[je]=rt[Be]=rt[qe]=rt[Ye]=rt[Je]=rt[Ge]=rt[De]=rt[Ce]=rt[Te]=rt[xe]=rt[Fe]=rt[Re]=rt[We]=rt[He]=rt[Ke]=rt[Xe]=rt[Qe]=!0,rt["[object Error]"]=rt[we]=rt["[object WeakMap]"]=!1;var ot={function:!0,object:!0},it=ot[typeof t]&&t&&!t.nodeType?t:void 0,at=ot[typeof e]&&e&&!e.nodeType?e:void 0,st=at&&at.exports===it?it:void 0,dt=u(it&&at&&"object"==typeof n&&n),ut=u(ot[typeof self]&&self),ct=u(ot[typeof window]&&window),lt=u(ot[typeof this]&&this),ft=dt||ct!==(lt&<.window)&&ct||ut||lt||Function("return this")(),vt=Array.prototype,pt=Object.prototype,_t=Function.prototype.toString,Et=pt.hasOwnProperty,Nt=pt.toString,Pt=RegExp("^"+_t.call(Et).replace(Ze,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),ht=st?ft.Buffer:void 0,Mt=ft.Symbol,mt=ft.Uint8Array,kt=Object.getOwnPropertySymbols,yt=Object.create,bt=pt.propertyIsEnumerable,gt=vt.splice,It=Object.getPrototypeOf,At=Object.keys,St=oe(ft,"DataView"),Vt=oe(ft,"Map"),Ut=oe(ft,"Promise"),Ot=oe(ft,"Set"),jt=oe(ft,"WeakMap"),wt=oe(Object,"create"),$t=_e(St),Dt=_e(Vt),Ct=_e(Ut),Tt=_e(Ot),xt=_e(jt),Ft=Mt?Mt.prototype:void 0,Rt=Ft?Ft.valueOf:void 0;v.prototype.clear=p,v.prototype.delete=_,v.prototype.get=E,v.prototype.has=N,v.prototype.set=P,h.prototype.clear=M,h.prototype.delete=m,h.prototype.get=k,h.prototype.has=y,h.prototype.set=b,g.prototype.clear=I,g.prototype.delete=A,g.prototype.get=S,g.prototype.has=V,g.prototype.set=U,O.prototype.clear=j,O.prototype.delete=w,O.prototype.get=$,O.prototype.has=D,O.prototype.set=C;var Wt=function(e){return function(e){return null==e?void 0:e.length}}();kt||(ae=function(){return[]}),(St&&se(new St(new ArrayBuffer(1)))!=ze||Vt&&se(new Vt)!=De||Ut&&"[object Promise]"!=se(Ut.resolve())||Ot&&se(new Ot)!=Fe||jt&&"[object WeakMap]"!=se(new jt))&&(se=function(e){var t=Nt.call(e),n=t==Te?e.constructor:void 0,r=n?_e(n):void 0;if(r)switch(r){case $t:return ze;case Dt:return De;case Ct:return"[object Promise]";case Tt:return Fe;case xt:return"[object WeakMap]"}return t});var Lt=Array.isArray,zt=ht?function(e){return e instanceof ht}:function(e){return function(){return!1}}();e.exports=R}).call(t,n(577)(e),n(4))},573:function(e,t,n){function r(e,t,n){var r=e[t];M.call(e,t)&&d(r,n)&&(void 0!==n||t in e)||(e[t]=n)}function o(e,t,n,o){n||(n={});for(var i=-1,a=t.length;++i-1&&e%1==0&&e-1&&e%1==0&&e<=_}function f(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}var v=n(575),p=n(576),_=9007199254740991,E="[object Function]",N="[object GeneratorFunction]",P=/^(?:0|[1-9]\d*)$/,h=Object.prototype,M=h.hasOwnProperty,m=h.toString,k=h.propertyIsEnumerable,y=!k.call({valueOf:1},"valueOf"),b=function(e){return function(e){return null==e?void 0:e.length}}(),g=function(e){return p(function(t,n){var r=-1,o=n.length,i=o>1?n[o-1]:void 0,s=o>2?n[2]:void 0;for(i=e.length>3&&"function"==typeof i?(o--,i):void 0,s&&a(n[0],n[1],s)&&(i=o<3?void 0:i,o=1),t=Object(t);++r-1&&e%1==0&&e-1&&e%1==0&&e<=_}function f(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function v(e){return!!e&&"object"==typeof e}function p(e){return d(e)?r(e):o(e)}var _=9007199254740991,E="[object Arguments]",N="[object Function]",P="[object GeneratorFunction]",h=/^(?:0|[1-9]\d*)$/,M=Object.prototype,m=M.hasOwnProperty,k=M.toString,y=M.propertyIsEnumerable,b=function(e,t){return function(n){return e(t(n))}}(Object.keys,Object),g=Array.isArray;e.exports=p},576:function(e,t){function n(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)}function r(e,t){return t=y(void 0===t?e.length-1:t,0),function(){for(var r=arguments,o=-1,i=y(r.length-t,0),a=Array(i);++o0;)o=a.shift(),i=s.shift();return n?(i||0)>=(o||0):(i||0)>(o||0)},t.language=o.language,t.version=o.version},function(e,t,n){"use strict";function r(e,t,n){var r="Web"===n.platform,i="iOS"===n.platform,a="android"===n.platform,s=a||i,d=function(){return r?window.navigator.userAgent.toLowerCase():""}(),u=function(){var e={};if(r){var t=window.name;try{var n=JSON.parse(t);e.containerId=n.containerId,e.version=n.hostVersion,e.language=n.language||"*"}catch(e){}}return e}(),c=function(){return s?"DingTalk"===n.appName||"com.alibaba.android.rimet"===n.appName:d.indexOf("dingtalk")>-1||!!u.containerId}(),l=function(){if(r){if(u.version)return u.version;var e=d.match(/aliapp\(\w+\/([a-zA-Z0-9.-]+)\)/);null===e&&(e=d.match(/dingtalk\/([a-zA-Z0-9.-]+)/));return e&&e[1]||"Unknown"}return n.appVersion}(),f=!!u.containerId,v=/iphone|ipod|ios/.test(d),p=/ipad/.test(d),_=d.indexOf("android")>-1,E=d.indexOf("mac")>-1&&f,N=d.indexOf("win")>-1&&f,P=!E&&!N&&f,h=f,M="";return M=c?v||i?o.PLATFORM.IOS:_||a?o.PLATFORM.ANDROID:p?o.PLATFORM.IPAD:E?o.PLATFORM.MAC:N?o.PLATFORM.WINDOWS:P?o.PLATFORM.BROWSER:o.PLATFORM.UNKNOWN:o.PLATFORM.UNKNOWN,{isDingTalk:c,isWebiOS:v,isWebAndroid:_,isWeexiOS:i,isWeexAndroid:a,isDingTalkPCMac:E,isDingTalkPCWeb:P,isDingTalkPCWindows:N,isDingTalkPC:h,runtime:e,framework:t,platform:M,version:l}}Object.defineProperty(t,"__esModule",{value:!0});var o=n(11);t.default=r},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(170),o=n(168),i=n(11),a=r.default().split("."),s=a[0],d=a[1],u=function(){var e={};switch(d){case i.FRAMEWORK.VUE:var t=weex.config,n=t.env;e.platform=n.platform,i.RUNTIME.WEEX===s&&(e.appVersion=n.appVersion,e.appName=n.appName);break;case i.FRAMEWORK.RAX:i.RUNTIME.WEEX===s&&(e.platform=navigator.platform,e.appName=navigator.appName,e.appVersion=navigator.appVersion);break;case i.FRAMEWORK.UNKNOWN:i.RUNTIME.WEB===s&&(e.platform=i.RUNTIME.WEB),i.RUNTIME.UNKNOWN===s&&(e.platform=i.RUNTIME.UNKNOWN)}return e}(),c=o.default(s,d,u);t.default=c},function(e,t,n){"use strict";function r(e,t){for(var n=e.length,r=0,o=!0;ro[i])return!0}return!0}Object.defineProperty(t,"__esModule",{value:!0}),t.isFunction=r,t.compareVersion=o;(function(e){e.cancel="-1",e.not_exist="1",e.no_permission="7",e.jsapi_internal_error="22"})(t.ERROR_CODE||(t.ERROR_CODE={}));(function(e){e.pc="pc",e.android="android",e.ios="ios",e.notInDingTalk="notInDingTalk"})(t.ENV_ENUM||(t.ENV_ENUM={}));(function(e){e.WEB="WEB",e.MINI_APP="MINI_APP",e.WEEX="WEEX",e.WEBVIEW_IN_MINIAPP="WEBVIEW_IN_MINIAPP"})(t.APP_TYPE||(t.APP_TYPE={}));(function(e){e[e.INFO=1]="INFO",e[e.WARNING=2]="WARNING",e[e.ERROR=3]="ERROR"})(t.LogLevel||(t.LogLevel={}))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),o=n(2),i=n(3),a=n(5),s=n(9),d=n(162),u=n(6),c=n(8),l=n(10);r.ddSdk.setPlatform({platform:o.ENV_ENUM.android,bridgeInit:function(){var e=o.getENV();return e.appType===i.APP_TYPE.MINI_APP?Promise.resolve(a.default):e.appType===i.APP_TYPE.WEBVIEW_IN_MINIAPP?Promise.resolve(s.default):e.appType===i.APP_TYPE.WEEX?u.androidWeexBridge():d.h5AndroidbridgeInit().then(function(){return d.default})},authMethod:"runtime.permission.requestJsApis",event:{on:function(e,t){var n=o.getENV();switch(n.appType){case i.APP_TYPE.WEB:c.on(e,t);break;case i.APP_TYPE.WEEX:l.on(e,t);break;default:throw new Error("Not support global event in the platfrom: "+n.appType)}},off:function(e,t){var n=o.getENV();switch(n.appType){case i.APP_TYPE.WEB:c.off(e,t);break;case i.APP_TYPE.WEEX:l.off(e,t);break;default:throw new Error("Not support global event in the platfrom: "+n.appType)}}}})},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(179),n(176),n(178)},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),o=n(2),i=n(3),a=n(5),s=n(9),d=n(163),u=n(6),c=n(8),l=n(10);r.ddSdk.setPlatform({platform:o.ENV_ENUM.ios,bridgeInit:function(){var e=o.getENV();return e.appType===i.APP_TYPE.MINI_APP?Promise.resolve(a.default):e.appType===i.APP_TYPE.WEBVIEW_IN_MINIAPP?Promise.resolve(s.default):e.appType===i.APP_TYPE.WEEX?u.iosWeexBridge():d.h5IosBridgeInit().then(function(){return d.default})},authMethod:"runtime.permission.requestJsApis",event:{on:function(e,t){var n=o.getENV();switch(n.appType){case i.APP_TYPE.WEB:c.on(e,t);break;case i.APP_TYPE.WEEX:l.on(e,t);break;default:throw new Error("Not support global event in the platfrom: "+n.appType)}},off:function(e,t){var n=o.getENV();switch(n.appType){case i.APP_TYPE.WEB:c.off(e,t);break;case i.APP_TYPE.WEEX:l.off(e,t);break;default:throw new Error("Not support global event in the platfrom: "+n.appType)}}}})},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),o=n(2),i=n(164),a=n(5),s=n(3),d=n(165);r.ddSdk.setPlatform({platform:o.ENV_ENUM.pc,bridgeInit:function(){switch(o.getENV().appType){case s.APP_TYPE.MINI_APP:return Promise.resolve(a.default);default:return i.h5PcBridgeInit().then(function(){return i.default})}},authMethod:"config",authParamsDeal:function(e){var t=Object.assign({},e);return t.url=window.location.href.split("#")[0],t},event:{on:function(e,t){if(o.getENV().appType===s.APP_TYPE.WEB)return d.on(e,t)},off:function(e,t){if(o.getENV().appType===s.APP_TYPE.WEB)return d.off(e,t)}}})},function(e,t){function n(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function o(e){if(c===setTimeout)return setTimeout(e,0);if((c===n||!c)&&setTimeout)return c=setTimeout,setTimeout(e,0);try{return c(e,0)}catch(t){try{return c.call(null,e,0)}catch(t){return c.call(this,e,0)}}}function i(e){if(l===clearTimeout)return clearTimeout(e);if((l===r||!l)&&clearTimeout)return l=clearTimeout,clearTimeout(e);try{return l(e)}catch(t){try{return l.call(null,e)}catch(t){return l.call(this,e)}}}function a(){_&&v&&(_=!1,v.length?p=v.concat(p):E=-1,p.length&&s())}function s(){if(!_){var e=o(a);_=!0;for(var t=p.length;t;){for(v=p,p=[];++E1)for(var n=1;n=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},n(182),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(t,n(7))},,function(e,t,n){"use strict";var r=n(161),o=n(568),i=Object.assign(r,o.apiObj);e.exports=i},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(12),o=n(13),i=n(14),a=n(15),s=n(16),d=n(17),u=n(18),c=n(19),l=n(20),f=n(21),v=n(22),p=n(23),_=n(24),E=n(25),N=n(26),P=n(27),h=n(28),M=n(29),m=n(30),k=n(31),y=n(32),b=n(33),g=n(34),I=n(35),A=n(36),S=n(37),V=n(38),U=n(39),O=n(40),j=n(41),w=n(42),$=n(43),D=n(44),C=n(45),T=n(46),x=n(47),F=n(48),R=n(49),W=n(50),L=n(51),z=n(52),B=n(53),q=n(54),Y=n(55),J=n(56),G=n(57),H=n(58),K=n(59),X=n(60),Q=n(61),Z=n(62),ee=n(63),te=n(64),ne=n(65),re=n(66),oe=n(67),ie=n(68),ae=n(69),se=n(70),de=n(71),ue=n(72),ce=n(73),le=n(74),fe=n(75),ve=n(76),pe=n(77),_e=n(78),Ee=n(79),Ne=n(80),Pe=n(81),he=n(82),Me=n(83),me=n(84),ke=n(85),ye=n(86),be=n(87),ge=n(88),Ie=n(89),Ae=n(90),Se=n(91),Ve=n(92),Ue=n(93),Oe=n(94),je=n(95),we=n(96),$e=n(97),De=n(98),Ce=n(99),Te=n(100),xe=n(101),Fe=n(102),Re=n(103),We=n(104),Le=n(105),ze=n(106),Be=n(107),qe=n(108),Ye=n(109),Je=n(110),Ge=n(111),He=n(112),Ke=n(113),Xe=n(114),Qe=n(115),Ze=n(116),et=n(117),tt=n(118),nt=n(119),rt=n(120),ot=n(121),it=n(122),at=n(123),st=n(124),dt=n(125),ut=n(126),ct=n(127),lt=n(128),ft=n(129),vt=n(130),pt=n(131),_t=n(132),Et=n(133),Nt=n(134),Pt=n(135),ht=n(136),Mt=n(137),mt=n(138),kt=n(139),yt=n(140),bt=n(141),gt=n(142),It=n(143),At=n(144),St=n(145),Vt=n(146),Ut=n(147),Ot=n(148),jt=n(149),wt=n(150),$t=n(151),Dt=n(152),Ct=n(153),Tt=n(154),xt=n(155),Ft=n(156),Rt=n(157),Wt=n(158),Lt=n(159);t.apiObj={biz:{alipay:{pay:r.pay$},calendar:{chooseDateTime:o.chooseDateTime$,chooseHalfDay:i.chooseHalfDay$,chooseInterval:a.chooseInterval$,chooseOneDay:s.chooseOneDay$},chat:{chooseConversationByCorpId:d.chooseConversationByCorpId$,collectSticker:u.collectSticker$,locationChatMessage:c.locationChatMessage$,openSingleChat:l.openSingleChat$,pickConversation:f.pickConversation$,sendEmotion:v.sendEmotion$,toConversation:p.toConversation$},clipboardData:{setData:_.setData$},contact:{choose:E.choose$,chooseMobileContacts:N.chooseMobileContacts$,complexPicker:P.complexPicker$,createGroup:h.createGroup$,departmentsPicker:M.departmentsPicker$,externalComplexPicker:m.externalComplexPicker$,externalEditForm:k.externalEditForm$,setRule:y.setRule$},cspace:{chooseSpaceDir:b.chooseSpaceDir$,delete:g.delete$,preview:I.preview$,saveFile:A.saveFile$},customContact:{choose:S.choose$,multipleChoose:V.multipleChoose$},ding:{create:U.create$,post:O.post$},event:{notifyWeex:j.notifyWeex$},intent:{fetchData:w.fetchData$},iot:{bind:$.bind$,bindMeetingRoom:D.bindMeetingRoom$,queryMeetingRoomList:C.queryMeetingRoomList$,unbind:T.unbind$},map:{locate:x.locate$,search:F.search$,view:R.view$},microApp:{openApp:W.openApp$},navigation:{close:L.close$,goBack:z.goBack$,hideBar:B.hideBar$,quit:q.quit$,replace:Y.replace$,setIcon:J.setIcon$,setLeft:G.setLeft$,setMenu:H.setMenu$,setRight:K.setRight$,setTitle:X.setTitle$},store:{closeUnpayOrder:Q.closeUnpayOrder$,createOrder:Z.createOrder$,getPayUrl:ee.getPayUrl$,inquiry:te.inquiry$},telephone:{call:ne.call$,checkBizCall:re.checkBizCall$,quickCallList:oe.quickCallList$,showCallMenu:ie.showCallMenu$},user:{checkPassword:ae.checkPassword$,get:se.get$},util:{chosen:de.chosen$,datepicker:ue.datepicker$,datetimepicker:ce.datetimepicker$,decrypt:le.decrypt$,downloadFile:fe.downloadFile$,encrypt:ve.encrypt$,isLocalFileExist:pe.isLocalFileExist$,multiSelect:_e.multiSelect$,open:Ee.open$,openLink:Ne.openLink$,openLocalFile:Pe.openLocalFile$,openModal:he.openModal$,openSlidePanel:Me.openSlidePanel$,presentWindow:me.presentWindow$,previewImage:ke.previewImage$,previewVideo:ye.previewVideo$,scan:be.scan$,scanCard:ge.scanCard$,setScreenBrightnessAndKeepOn:Ie.setScreenBrightnessAndKeepOn$,share:Ae.share$,startDocSign:Se.startDocSign$,systemShare:Ve.systemShare$,timepicker:Ue.timepicker$,uploadAttachment:Oe.uploadAttachment$,uploadImage:je.uploadImage$,uploadImageFromCamera:we.uploadImageFromCamera$,ut:$e.ut$},verify:{openBindIDCard:De.openBindIDCard$,startAuth:Ce.startAuth$}},channel:{permission:{requestAuthCode:Te.requestAuthCode$}},device:{accelerometer:{clearShake:xe.clearShake$,watchShake:Fe.watchShake$},audio:{download:Re.download$,onPlayEnd:We.onPlayEnd$,onRecordEnd:Le.onRecordEnd$,pause:ze.pause$,play:Be.play$,resume:qe.resume$,startRecord:Ye.startRecord$,stop:Je.stop$,stopRecord:Ge.stopRecord$,translateVoice:He.translateVoice$},base:{getInterface:Ke.getInterface$,getPhoneInfo:Xe.getPhoneInfo$,getUUID:Qe.getUUID$,getWifiStatus:Ze.getWifiStatus$},connection:{getNetworkType:et.getNetworkType$},geolocation:{get:tt.get$,start:nt.start$,status:rt.status$,stop:ot.stop$},launcher:{checkInstalledApps:it.checkInstalledApps$,launchApp:at.launchApp$},nfc:{nfcRead:st.nfcRead$,nfcStop:dt.nfcStop$,nfcWrite:ut.nfcWrite$},notification:{actionSheet:ct.actionSheet$,alert:lt.alert$,confirm:ft.confirm$,extendModal:vt.extendModal$,hidePreloader:pt.hidePreloader$,modal:_t.modal$,prompt:Et.prompt$,showPreloader:Nt.showPreloader$,toast:Pt.toast$,vibrate:ht.vibrate$},screen:{insetAdjust:Mt.insetAdjust$,resetView:mt.resetView$,rotateView:kt.rotateView$}},net:{bjGovApn:{loginGovNet:yt.loginGovNet$}},runtime:{message:{fetch:bt.fetch$,post:gt.post$},permission:{requestAuthCode:It.requestAuthCode$,requestOperateAuthCode:At.requestOperateAuthCode$}},ui:{input:{plain:St.plain$},nav:{close:Vt.close$,getCurrentId:Ut.getCurrentId$,go:Ot.go$,preload:jt.preload$,recycle:wt.recycle$},progressBar:{setColors:$t.setColors$},pullToRefresh:{disable:Dt.disable$,enable:Ct.enable$,stop:Tt.stop$},webViewBounce:{disable:xt.disable$,enable:Ft.enable$}},util:{domainStorage:{getItem:Rt.getItem$,removeItem:Wt.removeItem$,setItem:Lt.setItem$}}}},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,function(e,t,n){e.exports=n(185)}])});
\ No newline at end of file
diff --git a/tiesheng-login/src/main/resources/static/ding/error.html b/tiesheng-login/src/main/resources/static/ding/error.html
new file mode 100644
index 0000000..01b5db4
--- /dev/null
+++ b/tiesheng-login/src/main/resources/static/ding/error.html
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
diff --git a/tiesheng-login/src/main/resources/static/ding/error.png b/tiesheng-login/src/main/resources/static/ding/error.png
new file mode 100644
index 0000000..6441fb7
Binary files /dev/null and b/tiesheng-login/src/main/resources/static/ding/error.png differ
diff --git a/tiesheng-login/src/main/resources/static/ding/index.html b/tiesheng-login/src/main/resources/static/ding/index.html
new file mode 100644
index 0000000..451c6cf
--- /dev/null
+++ b/tiesheng-login/src/main/resources/static/ding/index.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+ 钉钉授权
+
+
+
+
+
+
+
diff --git a/tiesheng-message/pom.xml b/tiesheng-message/pom.xml
index 97e877b..11463e2 100644
--- a/tiesheng-message/pom.xml
+++ b/tiesheng-message/pom.xml
@@ -6,7 +6,7 @@
com.tiesheng
tiesheng-parent
- 0.0.4
+ 0.0.5
tiesheng-message
@@ -18,15 +18,10 @@
-
- com.tiesheng
- tiesheng-ding
- ${project.parent.version}
-
com.tiesheng
- tiesheng-wxmp
+ tiesheng-platform
${project.parent.version}
diff --git a/tiesheng-wxmp/pom.xml b/tiesheng-platform/pom.xml
similarity index 67%
rename from tiesheng-wxmp/pom.xml
rename to tiesheng-platform/pom.xml
index 05e0d88..62bc495 100644
--- a/tiesheng-wxmp/pom.xml
+++ b/tiesheng-platform/pom.xml
@@ -6,10 +6,10 @@
com.tiesheng
tiesheng-parent
- 0.0.4
+ 0.0.5
- tiesheng-wxmp
+ tiesheng-platform
8
@@ -17,4 +17,12 @@
UTF-8
+
+
+ com.tiesheng
+ tiesheng-util
+ ${project.parent.version}
+
+
+
diff --git a/tiesheng-platform/src/main/java/com/tiesheng/platform/PlatformAutoImportSelector.java b/tiesheng-platform/src/main/java/com/tiesheng/platform/PlatformAutoImportSelector.java
new file mode 100644
index 0000000..9c32826
--- /dev/null
+++ b/tiesheng-platform/src/main/java/com/tiesheng/platform/PlatformAutoImportSelector.java
@@ -0,0 +1,10 @@
+package com.tiesheng.platform;
+
+
+import org.springframework.context.annotation.ComponentScan;
+
+@ComponentScan({
+ "com.tiesheng.platform.**.*",
+})
+public class PlatformAutoImportSelector {
+}
diff --git a/tiesheng-ding/src/main/java/com/tiesheng/ding/config/DingConfig.java b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/PlatformDingConfig.java
similarity index 95%
rename from tiesheng-ding/src/main/java/com/tiesheng/ding/config/DingConfig.java
rename to tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/PlatformDingConfig.java
index 4cc7b3c..6bebb4f 100644
--- a/tiesheng-ding/src/main/java/com/tiesheng/ding/config/DingConfig.java
+++ b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/PlatformDingConfig.java
@@ -1,4 +1,4 @@
-package com.tiesheng.ding.config;
+package com.tiesheng.platform.config.ding;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.TypeReference;
@@ -9,7 +9,7 @@ import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.LogFactory;
-import com.tiesheng.ding.pojos.*;
+import com.tiesheng.platform.config.ding.bean.*;
import com.tiesheng.util.TimedCacheHelper;
import com.tiesheng.util.exception.ApiException;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -22,13 +22,12 @@ import java.util.function.Consumer;
* @author hao
*/
@Configuration
-@ConfigurationProperties(prefix = "tiesheng.ding")
-public class DingConfig {
+@ConfigurationProperties(prefix = "platform.ding")
+public class PlatformDingConfig {
private static final String CACHE_ACCESS_TOKEN = "cache_ding_access_token_";
private static final String CACHE_JSAPI_TICKET = "cache_ding_jsapi_ticket_";
-
private Map configs = MapUtil.newHashMap();
private DingConfigBean global;
@@ -240,12 +239,11 @@ public class DingConfig {
* @param content
* @param actionUrl
* @param userIds
- * @return
*/
- public String messageNotification(String service, String title, String content, String actionUrl, List userIds) {
+ public void messageNotification(String service, String title, String content, String actionUrl, List userIds) {
if (CollUtil.isEmpty(userIds)) {
- return "";
+ return;
}
DingConfigBean configBean = getConfigBean(service);
@@ -264,7 +262,7 @@ public class DingConfig {
body.put("agent_id", configBean.getAgentId());
body.put("userid_list", CollUtil.join(userIds, ","));
body.put("msg", msg);
- return HttpUtil.post("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token=" + getAccessToken(service),
+ String resp = HttpUtil.post("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token=" + getAccessToken(service),
JSONUtil.toJsonStr(body));
}
diff --git a/tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingConfigBean.java b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingConfigBean.java
similarity index 95%
rename from tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingConfigBean.java
rename to tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingConfigBean.java
index 17e0c30..74d3ac1 100644
--- a/tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingConfigBean.java
+++ b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingConfigBean.java
@@ -1,4 +1,4 @@
-package com.tiesheng.ding.pojos;
+package com.tiesheng.platform.config.ding.bean;
/**
* @author hao
diff --git a/tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingDeptVo.java b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingDeptVo.java
similarity index 93%
rename from tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingDeptVo.java
rename to tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingDeptVo.java
index 451f2bf..ab237be 100644
--- a/tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingDeptVo.java
+++ b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingDeptVo.java
@@ -1,4 +1,4 @@
-package com.tiesheng.ding.pojos;
+package com.tiesheng.platform.config.ding.bean;
public class DingDeptVo {
diff --git a/tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingJsapiSignature.java b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingJsapiSignature.java
similarity index 97%
rename from tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingJsapiSignature.java
rename to tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingJsapiSignature.java
index c7ca7ba..880e653 100644
--- a/tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingJsapiSignature.java
+++ b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingJsapiSignature.java
@@ -1,4 +1,4 @@
-package com.tiesheng.ding.pojos;
+package com.tiesheng.platform.config.ding.bean;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
diff --git a/tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingResponse.java b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingResponse.java
similarity index 95%
rename from tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingResponse.java
rename to tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingResponse.java
index 3c3935d..9b017fd 100644
--- a/tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingResponse.java
+++ b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingResponse.java
@@ -1,4 +1,4 @@
-package com.tiesheng.ding.pojos;
+package com.tiesheng.platform.config.ding.bean;
import java.util.Objects;
diff --git a/tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingUserInfo.java b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingUserInfo.java
similarity index 98%
rename from tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingUserInfo.java
rename to tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingUserInfo.java
index b6c8cb0..7855d98 100644
--- a/tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingUserInfo.java
+++ b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingUserInfo.java
@@ -1,4 +1,4 @@
-package com.tiesheng.ding.pojos;
+package com.tiesheng.platform.config.ding.bean;
import java.util.List;
diff --git a/tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingUserListVo.java b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingUserListVo.java
similarity index 95%
rename from tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingUserListVo.java
rename to tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingUserListVo.java
index 5a92a0b..f07a99a 100644
--- a/tiesheng-ding/src/main/java/com/tiesheng/ding/pojos/DingUserListVo.java
+++ b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean/DingUserListVo.java
@@ -1,4 +1,4 @@
-package com.tiesheng.ding.pojos;
+package com.tiesheng.platform.config.ding.bean;
import java.util.ArrayList;
import java.util.List;
diff --git a/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/PlatformWxmpConfig.java b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/PlatformWxmpConfig.java
new file mode 100644
index 0000000..93a5aa5
--- /dev/null
+++ b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/PlatformWxmpConfig.java
@@ -0,0 +1,181 @@
+package com.tiesheng.platform.config.wxmp;
+
+
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.URLUtil;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import cn.hutool.log.LogFactory;
+import com.tiesheng.platform.config.wxmp.bean.WxConfigBean;
+import com.tiesheng.platform.config.wxmp.bean.WxJsapiSignature;
+import com.tiesheng.platform.config.wxmp.bean.WxOAuth2AccessToken;
+import com.tiesheng.platform.config.wxmp.bean.WxUserInfo;
+import com.tiesheng.util.TimedCacheHelper;
+import com.tiesheng.util.exception.ApiException;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author hao
+ */
+@Configuration
+@ConfigurationProperties(prefix = "platform.wxmp")
+public class PlatformWxmpConfig {
+
+ private static final String CACHE_ACCESS_TOKEN = "cache_weixin_access_token_";
+ private static final String CACHE_JSAPI_TICKET = "cache_weixin_jsapi_ticket_";
+
+
+ private WxConfigBean global;
+ private Map configs = MapUtil.newHashMap();
+
+ /**
+ * 获取一个DingConfigBean
+ *
+ * @param service
+ * @return
+ */
+ public WxConfigBean getConfigBean(String service) {
+ WxConfigBean bean = configs.get(service);
+ if (bean == null) {
+ bean = global;
+ }
+ if (bean == null) {
+ throw new ApiException("该服务未配置微信授权");
+ }
+ return bean;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // 业务逻辑
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * 获取accessToken
+ *
+ * @return
+ */
+ private String getAccessToken(String service) {
+ WxConfigBean configBean = getConfigBean(service);
+ String accessToken = TimedCacheHelper.getTimedCache().get(CACHE_ACCESS_TOKEN + configBean.getAppId(), false);
+ if (StrUtil.isEmpty(accessToken)) {
+ Map query = new HashMap<>(10);
+ query.put("grant_type", "client_credential");
+ query.put("appid", configBean.getAppId());
+ query.put("secret", configBean.getAppSecret());
+ String response = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token", query);
+ LogFactory.get().info("getAccessToken: " + response);
+ JSONObject respJson = JSONUtil.parseObj(response);
+ accessToken = respJson.getStr("access_token");
+ TimedCacheHelper.getTimedCache().put(CACHE_ACCESS_TOKEN + configBean.getAppId(), accessToken, respJson.getLong("expires_in"));
+ }
+ return accessToken;
+ }
+
+
+ /**
+ * 获取jsapi_ticket
+ *
+ * @return
+ */
+ private String getJsapiTicket(String service) {
+ WxConfigBean configBean = getConfigBean(service);
+ String jsapiTicket = TimedCacheHelper.getTimedCache().get(CACHE_JSAPI_TICKET + configBean.getAppId(), false);
+ if (StrUtil.isEmpty(jsapiTicket)) {
+ Map query = new HashMap<>(10);
+ query.put("access_token", getAccessToken(service));
+ query.put("type", "jsapi");
+ String response = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/ticket/getticket", query);
+ LogFactory.get().info("getJsapiTicket: " + response);
+ JSONObject respJson = JSONUtil.parseObj(response);
+ jsapiTicket = respJson.getStr("ticket");
+ TimedCacheHelper.getTimedCache().put(CACHE_JSAPI_TICKET + configBean.getAppId(), jsapiTicket, respJson.getLong("expires_in"));
+ }
+ return jsapiTicket;
+ }
+
+
+ /**
+ * 创建jssdk配置
+ *
+ * @param url
+ * @return
+ */
+ public WxJsapiSignature createJsapiSignature(String service, String url) {
+ WxConfigBean configBean = getConfigBean(service);
+ if (StrUtil.contains(url, "#")) {
+ url = StrUtil.sub(url, 0, StrUtil.indexOf(url, '#'));
+ }
+ return WxJsapiSignature.create(configBean.getAppId(), url, getJsapiTicket(service));
+ }
+
+
+ /**
+ * 生成认证url
+ *
+ * @return
+ */
+ public String buildAuthorizationUrl(String service, String redirectUrl, String scope) {
+ WxConfigBean configBean = getConfigBean(service);
+ return "https://open.weixin.qq.com/connect/oauth2/authorize"
+ + "?appid=" + configBean.getAppId()
+ + "&redirect_uri=" + URLUtil.encodeAll(redirectUrl)
+ + "&response_type=code&scope=" + scope
+ + "&state=STATE#wechat_redirect";
+ }
+
+
+ /**
+ * 通过code获取用户授权信息
+ *
+ * @param code
+ * @return
+ */
+ public WxUserInfo getOAuth2AccessToken(String service, String code) {
+ WxConfigBean configBean = getConfigBean(service);
+ WxOAuth2AccessToken wxOAuth2AccessToken = WxOAuth2AccessToken.create(configBean.getAppId(), configBean.getAppSecret(), code);
+ WxUserInfo wxUserInfo = WxUserInfo.create(wxOAuth2AccessToken);
+ wxUserInfo.setAppId(configBean.getAppId());
+ return wxUserInfo;
+ }
+
+
+ /**
+ * 获取临时素材-图片
+ *
+ * @return
+ * @link
+ */
+ public void mediaPicGet(String service, String mediaId, String filePath) {
+ String fileUrl = String.format("https://api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s",
+ getAccessToken(service), mediaId);
+ HttpUtil.downloadFile(fileUrl, filePath);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // setter\getter
+ ///////////////////////////////////////////////////////////////////////////
+
+ public Map getConfigs() {
+ return configs;
+ }
+
+ public void setConfigs(Map configs) {
+ this.configs = configs;
+ }
+
+ public WxConfigBean getGlobal() {
+ return global;
+ }
+
+ public void setGlobal(WxConfigBean global) {
+ this.global = global;
+ }
+}
diff --git a/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxConfigBean.java b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxConfigBean.java
new file mode 100644
index 0000000..5a24275
--- /dev/null
+++ b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxConfigBean.java
@@ -0,0 +1,30 @@
+package com.tiesheng.platform.config.wxmp.bean;
+
+/**
+ * @author hao
+ */
+public class WxConfigBean {
+
+ private String appId;
+ private String appSecret;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // setter\getter
+ ///////////////////////////////////////////////////////////////////////////
+
+ public String getAppId() {
+ return appId;
+ }
+
+ public void setAppId(String appId) {
+ this.appId = appId;
+ }
+
+ public String getAppSecret() {
+ return appSecret;
+ }
+
+ public void setAppSecret(String appSecret) {
+ this.appSecret = appSecret;
+ }
+}
diff --git a/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxJsapiSignature.java b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxJsapiSignature.java
new file mode 100644
index 0000000..45ae405
--- /dev/null
+++ b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxJsapiSignature.java
@@ -0,0 +1,81 @@
+package com.tiesheng.platform.config.wxmp.bean;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.crypto.SecureUtil;
+
+/**
+ * jssdk配置
+ *
+ * @author hao
+ */
+public class WxJsapiSignature {
+
+ private String appId;
+ private String nonceStr;
+ private long timestamp;
+ private String url;
+ private String signature;
+
+ public static WxJsapiSignature create(String appId, String url, String ticket) {
+ WxJsapiSignature wxJsapiSignature = new WxJsapiSignature();
+ wxJsapiSignature.setAppId(appId);
+ wxJsapiSignature.setUrl(url);
+ wxJsapiSignature.setTimestamp(DateUtil.currentSeconds());
+ wxJsapiSignature.setNonceStr(RandomUtil.randomString(10));
+
+ // 生成签名
+ String builder = "jsapi_ticket=" + ticket +
+ "&noncestr=" + wxJsapiSignature.getNonceStr() +
+ "×tamp=" + wxJsapiSignature.getTimestamp() +
+ "&url=" + wxJsapiSignature.getUrl();
+ wxJsapiSignature.setSignature(SecureUtil.sha1(builder));
+
+ return wxJsapiSignature;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // setter\getter
+ ///////////////////////////////////////////////////////////////////////////
+
+ public String getAppId() {
+ return appId;
+ }
+
+ public void setAppId(String appId) {
+ this.appId = appId;
+ }
+
+ public String getNonceStr() {
+ return nonceStr;
+ }
+
+ public void setNonceStr(String nonceStr) {
+ this.nonceStr = nonceStr;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getSignature() {
+ return signature;
+ }
+
+ public void setSignature(String signature) {
+ this.signature = signature;
+ }
+}
diff --git a/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxOAuth2AccessToken.java b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxOAuth2AccessToken.java
new file mode 100644
index 0000000..97d93d9
--- /dev/null
+++ b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxOAuth2AccessToken.java
@@ -0,0 +1,46 @@
+package com.tiesheng.platform.config.wxmp.bean;
+
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+
+/**
+ * @author hao
+ */
+public class WxOAuth2AccessToken {
+
+ private String accessToken;
+ private String openid;
+
+ public static WxOAuth2AccessToken create(String appId, String secret, String code) {
+ String response = HttpUtil.get("https://api.weixin.qq.com/sns/oauth2/access_token" +
+ "?appid=" + appId + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code");
+ JSONObject respJson = JSONUtil.parseObj(response);
+
+ WxOAuth2AccessToken oAuth2AccessToken = new WxOAuth2AccessToken();
+ oAuth2AccessToken.setOpenid(respJson.getStr("openid"));
+ oAuth2AccessToken.setAccessToken(respJson.getStr("access_token"));
+ return oAuth2AccessToken;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // setter\getter
+ ///////////////////////////////////////////////////////////////////////////
+
+ public String getAccessToken() {
+ return accessToken;
+ }
+
+ public void setAccessToken(String accessToken) {
+ this.accessToken = accessToken;
+ }
+
+ public String getOpenid() {
+ return openid;
+ }
+
+ public void setOpenid(String openid) {
+ this.openid = openid;
+ }
+}
diff --git a/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxUserInfo.java b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxUserInfo.java
new file mode 100644
index 0000000..447f217
--- /dev/null
+++ b/tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxUserInfo.java
@@ -0,0 +1,115 @@
+package com.tiesheng.platform.config.wxmp.bean;
+
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONUtil;
+
+/**
+ * @author hao
+ */
+public class WxUserInfo {
+
+ private String accessToken;
+ private String nickname;
+ private String sex;
+ private String province;
+ private String city;
+ private String country;
+ private String headimgurl;
+ private String openid;
+ private String appId;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // 逻辑方法
+ ///////////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * 通过oAuth2AccessToken获取用户信息
+ *
+ * @param oAuth2AccessToken
+ * @return
+ */
+ public static WxUserInfo create(WxOAuth2AccessToken oAuth2AccessToken) {
+ String s = HttpUtil.get("https://api.weixin.qq.com/sns/userinfo"
+ + "?access_token=" + oAuth2AccessToken.getAccessToken()
+ + "&openid=" + oAuth2AccessToken.getOpenid() + "&lang=zh_CN");
+ return JSONUtil.toBean(s, WxUserInfo.class);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // setter\getter
+ ///////////////////////////////////////////////////////////////////////////
+
+ public String getAccessToken() {
+ return accessToken;
+ }
+
+ public void setAccessToken(String accessToken) {
+ this.accessToken = accessToken;
+ }
+
+ public String getNickname() {
+ return nickname;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+
+ public String getSex() {
+ return sex;
+ }
+
+ public void setSex(String sex) {
+ this.sex = sex;
+ }
+
+ public String getProvince() {
+ return province;
+ }
+
+ public void setProvince(String province) {
+ this.province = province;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ public String getHeadimgurl() {
+ return headimgurl;
+ }
+
+ public void setHeadimgurl(String headimgurl) {
+ this.headimgurl = headimgurl;
+ }
+
+ public String getOpenid() {
+ return openid;
+ }
+
+ public void setOpenid(String openid) {
+ this.openid = openid;
+ }
+
+ public String getAppId() {
+ return appId;
+ }
+
+ public void setAppId(String appId) {
+ this.appId = appId;
+ }
+}
diff --git a/tiesheng-poi/pom.xml b/tiesheng-poi/pom.xml
index ad4017b..dd93475 100644
--- a/tiesheng-poi/pom.xml
+++ b/tiesheng-poi/pom.xml
@@ -6,7 +6,7 @@
com.tiesheng
tiesheng-parent
- 0.0.4
+ 0.0.5
tiesheng-poi
diff --git a/tiesheng-util/pom.xml b/tiesheng-util/pom.xml
index 7589245..0906519 100644
--- a/tiesheng-util/pom.xml
+++ b/tiesheng-util/pom.xml
@@ -6,7 +6,7 @@
com.tiesheng
tiesheng-parent
- 0.0.4
+ 0.0.5
tiesheng-util
diff --git a/tiesheng-util/src/main/java/com/tiesheng/util/pojos/ApiResp.java b/tiesheng-util/src/main/java/com/tiesheng/util/pojos/ApiResp.java
index 2bc2805..2760bbe 100644
--- a/tiesheng-util/src/main/java/com/tiesheng/util/pojos/ApiResp.java
+++ b/tiesheng-util/src/main/java/com/tiesheng/util/pojos/ApiResp.java
@@ -17,6 +17,7 @@ public class ApiResp {
private int code;
private String message;
+ private Throwable exception;
private T data;
private long recordsTotal = 0;
private boolean encrypt = false;
@@ -171,4 +172,12 @@ public class ApiResp {
public void setEncrypt(boolean encrypt) {
this.encrypt = encrypt;
}
+
+ public Throwable getException() {
+ return exception;
+ }
+
+ public void setException(Throwable exception) {
+ this.exception = exception;
+ }
}
diff --git a/tiesheng-web/pom.xml b/tiesheng-web/pom.xml
index f2bbaa6..fb1e20f 100644
--- a/tiesheng-web/pom.xml
+++ b/tiesheng-web/pom.xml
@@ -6,7 +6,7 @@
com.tiesheng
tiesheng-parent
- 0.0.4
+ 0.0.5
tiesheng-web
diff --git a/tiesheng-web/src/main/java/com/tiesheng/core/config/exception/SpringExceptionHandler.java b/tiesheng-web/src/main/java/com/tiesheng/core/config/exception/SpringExceptionHandler.java
index a88150f..0f608b1 100644
--- a/tiesheng-web/src/main/java/com/tiesheng/core/config/exception/SpringExceptionHandler.java
+++ b/tiesheng-web/src/main/java/com/tiesheng/core/config/exception/SpringExceptionHandler.java
@@ -25,7 +25,7 @@ import java.io.IOException;
@RestControllerAdvice
public class SpringExceptionHandler {
- @Autowired(required = false)
+ @Autowired
TieshengWebConfigurer tieshengWebConfigurer;
@@ -74,10 +74,7 @@ public class SpringExceptionHandler {
return ApiResp.respCust(ApiRespEnum.ServerError.getCode(), "IO异常");
}
- if (tieshengWebConfigurer != null) {
- return tieshengWebConfigurer.addExceptionHandler(e);
- }
- return ApiResp.respCust(ApiRespEnum.ServerError);
+ return tieshengWebConfigurer.addExceptionHandler(e);
}
}
diff --git a/tiesheng-web/src/main/java/com/tiesheng/core/config/json/FastJsonMessageConverter.java b/tiesheng-web/src/main/java/com/tiesheng/core/config/json/FastJsonMessageConverter.java
index c1dc2f9..5266855 100644
--- a/tiesheng-web/src/main/java/com/tiesheng/core/config/json/FastJsonMessageConverter.java
+++ b/tiesheng-web/src/main/java/com/tiesheng/core/config/json/FastJsonMessageConverter.java
@@ -1,6 +1,5 @@
package com.tiesheng.core.config.json;
-import cn.hutool.log.LogFactory;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
@@ -29,8 +28,7 @@ public class FastJsonMessageConverter {
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullStringAsEmpty,
- SerializerFeature.WriteEnumUsingName,
- SerializerFeature.WriteNullNumberAsZero);
+ SerializerFeature.WriteEnumUsingName);
config.setDateFormat("yyyy-MM-dd HH:mm:ss");
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
diff --git a/tiesheng-web/src/main/java/com/tiesheng/core/config/web/DefaultWebConfigurer.java b/tiesheng-web/src/main/java/com/tiesheng/core/config/web/DefaultWebConfigurer.java
new file mode 100644
index 0000000..4d7bc02
--- /dev/null
+++ b/tiesheng-web/src/main/java/com/tiesheng/core/config/web/DefaultWebConfigurer.java
@@ -0,0 +1,13 @@
+package com.tiesheng.core.config.web;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Configuration;
+
+
+/**
+ * @author hao
+ */
+@Configuration
+@ConditionalOnMissingBean(value = TieshengWebConfigurer.class, ignored = DefaultWebConfigurer.class)
+public class DefaultWebConfigurer implements TieshengWebConfigurer {
+}
diff --git a/tiesheng-web/src/main/java/com/tiesheng/core/config/web/TieshengWebConfigurer.java b/tiesheng-web/src/main/java/com/tiesheng/core/config/web/TieshengWebConfigurer.java
index 17ad62a..5e3a5ec 100644
--- a/tiesheng-web/src/main/java/com/tiesheng/core/config/web/TieshengWebConfigurer.java
+++ b/tiesheng-web/src/main/java/com/tiesheng/core/config/web/TieshengWebConfigurer.java
@@ -1,12 +1,17 @@
package com.tiesheng.core.config.web;
import cn.hutool.log.LogFactory;
-import com.tiesheng.login.config.token.TsTokenConfig;
import com.tiesheng.core.config.web.bean.CurrentWebUser;
+import com.tiesheng.core.pojos.dao.CorePlatformUnique;
+import com.tiesheng.login.config.token.TsTokenConfig;
+import com.tiesheng.login.config.token.bean.TokenBean;
+import com.tiesheng.util.exception.ApiException;
import com.tiesheng.util.exception.ApiRespEnum;
import com.tiesheng.util.pojos.ApiResp;
import org.springframework.context.annotation.Configuration;
+import javax.servlet.http.HttpServletResponse;
+
/**
* WEB配置
*
@@ -24,6 +29,7 @@ public interface TieshengWebConfigurer {
default CurrentWebUser getCurrentUserName() {
CurrentWebUser webUser = new CurrentWebUser();
webUser.setId(TsTokenConfig.getWithoutThr().getId());
+ webUser.setName(webUser.getId());
return webUser;
}
@@ -34,8 +40,10 @@ public interface TieshengWebConfigurer {
* @param e 异常
*/
default ApiResp addExceptionHandler(Exception e) {
- LogFactory.get().info(e);
- return ApiResp.respCust(ApiRespEnum.ServerError);
+ ApiResp apiResp = ApiResp.respCust(ApiRespEnum.ServerError);
+ apiResp.setException(e);
+ LogFactory.get().info(apiResp.getException());
+ return apiResp;
}
@@ -45,4 +53,48 @@ public interface TieshengWebConfigurer {
default void uploadFileCheck(String fileExt) {
}
+
+ /**
+ * 配置登录
+ *
+ * @return
+ */
+ default LoginConfigurer loginConfigurer() {
+ return new LoginConfigurer() {
+ @Override
+ public TokenBean doLogin(CorePlatformUnique platformUnique) {
+ throw new ApiException("请配置TieshengWebConfigurer->loginConfigurer");
+ }
+
+ @Override
+ public void redirect(TokenBean bean, String extra, HttpServletResponse response) {
+ throw new ApiException("请配置TieshengWebConfigurer->loginConfigurer");
+ }
+ };
+ }
+
+
+ interface LoginConfigurer {
+
+ /**
+ * 登录逻辑
+ *
+ * @param platformUnique
+ * @return
+ */
+ TokenBean doLogin(CorePlatformUnique platformUnique);
+
+
+ /**
+ * 登录重定向
+ *
+ * @param bean
+ * @param extra
+ * @param response
+ */
+ void redirect(TokenBean bean, String extra, HttpServletResponse response);
+
+ }
+
+
}
diff --git a/tiesheng-web/src/main/java/com/tiesheng/core/controller/log/ManagerLogController.java b/tiesheng-web/src/main/java/com/tiesheng/core/controller/log/LogController.java
similarity index 86%
rename from tiesheng-web/src/main/java/com/tiesheng/core/controller/log/ManagerLogController.java
rename to tiesheng-web/src/main/java/com/tiesheng/core/controller/log/LogController.java
index 5143244..d8a97ee 100644
--- a/tiesheng-web/src/main/java/com/tiesheng/core/controller/log/ManagerLogController.java
+++ b/tiesheng-web/src/main/java/com/tiesheng/core/controller/log/LogController.java
@@ -2,11 +2,10 @@ package com.tiesheng.core.controller.log;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.tiesheng.core.pojos.dao.CoreLogLogin;
import com.tiesheng.core.pojos.dao.CoreLogOperation;
import com.tiesheng.core.pojos.dto.PageDTO;
import com.tiesheng.core.service.CoreLogService;
-import com.tiesheng.login.pojos.dao.CoreLogLogin;
-import com.tiesheng.login.service.LoginLogService;
import com.tiesheng.util.pojos.ApiResp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@@ -21,12 +20,10 @@ import java.util.List;
*/
@RestController
@RequestMapping("/manager/log")
-public class ManagerLogController {
+public class LogController {
@Autowired
CoreLogService coreLogService;
- @Autowired(required = false)
- LoginLogService loginLogService;
/**
@@ -63,9 +60,7 @@ public class ManagerLogController {
queryWrapper.orderByDesc("create_time");
Page page = dto.pageObj();
- if (loginLogService != null) {
- loginLogService.page(page, queryWrapper);
- }
+ coreLogService.getLogLoginMapper().selectPage(page, queryWrapper);
return ApiResp.respOK(page.getRecords(), page.getTotal());
}
diff --git a/tiesheng-login/src/main/java/com/tiesheng/login/mapper/CoreLogLoginMapper.java b/tiesheng-web/src/main/java/com/tiesheng/core/mapper/CoreLogLoginMapper.java
similarity index 60%
rename from tiesheng-login/src/main/java/com/tiesheng/login/mapper/CoreLogLoginMapper.java
rename to tiesheng-web/src/main/java/com/tiesheng/core/mapper/CoreLogLoginMapper.java
index decbb40..81f3c88 100644
--- a/tiesheng-login/src/main/java/com/tiesheng/login/mapper/CoreLogLoginMapper.java
+++ b/tiesheng-web/src/main/java/com/tiesheng/core/mapper/CoreLogLoginMapper.java
@@ -1,7 +1,7 @@
-package com.tiesheng.login.mapper;
+package com.tiesheng.core.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.tiesheng.login.pojos.dao.CoreLogLogin;
+import com.tiesheng.core.pojos.dao.CoreLogLogin;
public interface CoreLogLoginMapper extends BaseMapper {
-}
\ No newline at end of file
+}
diff --git a/tiesheng-web/src/main/java/com/tiesheng/core/mapper/CorePlatformUniqueMapper.java b/tiesheng-web/src/main/java/com/tiesheng/core/mapper/CorePlatformUniqueMapper.java
new file mode 100644
index 0000000..e96f83a
--- /dev/null
+++ b/tiesheng-web/src/main/java/com/tiesheng/core/mapper/CorePlatformUniqueMapper.java
@@ -0,0 +1,7 @@
+package com.tiesheng.core.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.tiesheng.core.pojos.dao.CorePlatformUnique;
+
+public interface CorePlatformUniqueMapper extends BaseMapper {
+}
\ No newline at end of file
diff --git a/tiesheng-login/src/main/java/com/tiesheng/login/pojos/dao/CoreLogLogin.java b/tiesheng-web/src/main/java/com/tiesheng/core/pojos/dao/CoreLogLogin.java
similarity index 60%
rename from tiesheng-login/src/main/java/com/tiesheng/login/pojos/dao/CoreLogLogin.java
rename to tiesheng-web/src/main/java/com/tiesheng/core/pojos/dao/CoreLogLogin.java
index 5215090..eac49fa 100644
--- a/tiesheng-login/src/main/java/com/tiesheng/login/pojos/dao/CoreLogLogin.java
+++ b/tiesheng-web/src/main/java/com/tiesheng/core/pojos/dao/CoreLogLogin.java
@@ -1,27 +1,14 @@
-package com.tiesheng.login.pojos.dao;
+package com.tiesheng.core.pojos.dao;
-import com.baomidou.mybatisplus.annotation.*;
-
-import java.util.Date;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.tiesheng.core.pojos.DaoBase;
/**
* 日志-登录
*/
@TableName(value = "core_log_login")
-public class CoreLogLogin {
-
- @TableId(value = "id", type = IdType.ASSIGN_ID)
- private String id;
-
- @TableField(value = "create_time", fill = FieldFill.INSERT)
- private Date createTime;
-
- @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
- private Date updateTime;
-
- @TableField(value = "is_deleted")
- private Integer isDeleted;
-
+public class CoreLogLogin extends DaoBase {
/**
* 用户id
*/
@@ -52,38 +39,6 @@ public class CoreLogLogin {
@TableField(value = "address")
private String address;
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- public Date getCreateTime() {
- return createTime;
- }
-
- public void setCreateTime(Date createTime) {
- this.createTime = createTime;
- }
-
- public Date getUpdateTime() {
- return updateTime;
- }
-
- public void setUpdateTime(Date updateTime) {
- this.updateTime = updateTime;
- }
-
- public Integer getIsDeleted() {
- return isDeleted;
- }
-
- public void setIsDeleted(Integer isDeleted) {
- this.isDeleted = isDeleted;
- }
-
/**
* 获取用户id
*
diff --git a/tiesheng-web/src/main/java/com/tiesheng/core/pojos/dao/CorePlatformUnique.java b/tiesheng-web/src/main/java/com/tiesheng/core/pojos/dao/CorePlatformUnique.java
new file mode 100644
index 0000000..daa4880
--- /dev/null
+++ b/tiesheng-web/src/main/java/com/tiesheng/core/pojos/dao/CorePlatformUnique.java
@@ -0,0 +1,134 @@
+package com.tiesheng.core.pojos.dao;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.tiesheng.core.pojos.DaoBase;
+import java.util.Date;
+
+/**
+ * 平台-唯一值
+ */
+@TableName(value = "core_platform_unique")
+public class CorePlatformUnique extends DaoBase {
+ /**
+ * 用户id
+ */
+ @TableField(value = "user_id")
+ private String userId;
+
+ /**
+ * appId
+ */
+ @TableField(value = "app_id")
+ private String appId;
+
+ /**
+ * 唯一值
+ */
+ @TableField(value = "unique_id")
+ private String uniqueId;
+
+ /**
+ * 平台
+ */
+ @TableField(value = "platform")
+ private String platform;
+
+ /**
+ * 其他参数
+ */
+ @TableField(value = "info")
+ private String info;
+
+ /**
+ * 获取用户id
+ *
+ * @return user_id - 用户id
+ */
+ public String getUserId() {
+ return userId;
+ }
+
+ /**
+ * 设置用户id
+ *
+ * @param userId 用户id
+ */
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ /**
+ * 获取appId
+ *
+ * @return app_id - appId
+ */
+ public String getAppId() {
+ return appId;
+ }
+
+ /**
+ * 设置appId
+ *
+ * @param appId appId
+ */
+ public void setAppId(String appId) {
+ this.appId = appId;
+ }
+
+ /**
+ * 获取唯一值
+ *
+ * @return unique_id - 唯一值
+ */
+ public String getUniqueId() {
+ return uniqueId;
+ }
+
+ /**
+ * 设置唯一值
+ *
+ * @param uniqueId 唯一值
+ */
+ public void setUniqueId(String uniqueId) {
+ this.uniqueId = uniqueId;
+ }
+
+ /**
+ * 获取平台
+ *
+ * @return platform - 平台
+ */
+ public String getPlatform() {
+ return platform;
+ }
+
+ /**
+ * 设置平台
+ *
+ * @param platform 平台
+ */
+ public void setPlatform(String platform) {
+ this.platform = platform;
+ }
+
+ /**
+ * 获取其他参数
+ *
+ * @return info - 其他参数
+ */
+ public String getInfo() {
+ return info;
+ }
+
+ /**
+ * 设置其他参数
+ *
+ * @param info 其他参数
+ */
+ public void setInfo(String info) {
+ this.info = info;
+ }
+}
\ No newline at end of file
diff --git a/tiesheng-web/src/main/java/com/tiesheng/core/service/CoreLogService.java b/tiesheng-web/src/main/java/com/tiesheng/core/service/CoreLogService.java
index 9794b40..0381a99 100644
--- a/tiesheng-web/src/main/java/com/tiesheng/core/service/CoreLogService.java
+++ b/tiesheng-web/src/main/java/com/tiesheng/core/service/CoreLogService.java
@@ -1,22 +1,36 @@
package com.tiesheng.core.service;
+import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONUtil;
-import com.tiesheng.login.config.token.TsTokenConfig;
import com.tiesheng.core.config.web.TieshengWebConfigurer;
import com.tiesheng.core.config.web.bean.CurrentWebUser;
+import com.tiesheng.core.mapper.CoreLogLoginMapper;
import com.tiesheng.core.mapper.CoreLogOperationMapper;
+import com.tiesheng.core.pojos.dao.CoreLogLogin;
import com.tiesheng.core.pojos.dao.CoreLogOperation;
+import com.tiesheng.core.pojos.dao.CorePlatformUnique;
+import com.tiesheng.util.ServletKit;
+import com.tiesheng.util.ip2region.DataBlock;
+import com.tiesheng.util.ip2region.Ip2Region;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import javax.servlet.http.HttpServletRequest;
+
/**
* @author hao
*/
@Service
public class CoreLogService extends TsServiceBase {
- @Autowired(required = false)
+ @Autowired
TieshengWebConfigurer tieshengWebConfigurer;
+ @Autowired
+ CoreLogLoginMapper coreLogLoginMapper;
+
+ public CoreLogLoginMapper getLogLoginMapper() {
+ return coreLogLoginMapper;
+ }
///////////////////////////////////////////////////////////////////////////
// 操作日志
@@ -28,13 +42,9 @@ public class CoreLogService extends TsServiceBase implements TieshengLoginConfigurer {
+
+ @Autowired
+ TieshengWebConfigurer tieshengWebConfigurer;
+ @Autowired
+ CoreLogService coreLogService;
+
+ @Override
+ public TokenBean doLogin(String appId, String uniqueId, String platfrom, String info) {
+
+ CorePlatformUnique platformUnique = getByAppAndUnique(appId, uniqueId, platfrom);
+ platformUnique.setInfo(info);
+ TokenBean tokenBean = tieshengWebConfigurer.loginConfigurer().doLogin(platformUnique);
+ if (tokenBean != null) {
+ platformUnique.setUserId(tokenBean.getId());
+ platformUnique.setIsDeleted(0);
+ saveOrUpdate(platformUnique);
+
+ // 添加登录日志
+ coreLogService.addLoginLog(platformUnique);
+ }
+ return tokenBean;
+ }
+
+ @Override
+ public void onLoginRedirect(TokenBean bean, String extra, HttpServletResponse response) {
+ tieshengWebConfigurer.loginConfigurer().redirect(bean, extra, response);
+ }
+
+
+ /**
+ * 通过appId获取登录对象
+ *
+ * @param appId
+ * @param uniqueId
+ * @return
+ */
+ private CorePlatformUnique getByAppAndUnique(String appId, String uniqueId, String platform) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("app_id", appId);
+ queryWrapper.eq("unique_id", uniqueId);
+ queryWrapper.eq("platform", platform);
+ queryWrapper.last("limit 1");
+ CorePlatformUnique platformUnique = getOne(queryWrapper);
+ if (platformUnique == null) {
+ platformUnique = new CorePlatformUnique();
+ platformUnique.setAppId(appId);
+ platformUnique.setUniqueId(uniqueId);
+ platformUnique.setPlatform(platform);
+ }
+ return platformUnique;
+ }
+
+}
diff --git a/tiesheng-web/src/main/java/com/tiesheng/core/service/FileUploadService.java b/tiesheng-web/src/main/java/com/tiesheng/core/service/FileUploadService.java
index b793527..6a59886 100644
--- a/tiesheng-web/src/main/java/com/tiesheng/core/service/FileUploadService.java
+++ b/tiesheng-web/src/main/java/com/tiesheng/core/service/FileUploadService.java
@@ -22,7 +22,7 @@ import java.util.List;
@Service
public class FileUploadService {
- @Autowired(required = false)
+ @Autowired
TieshengWebConfigurer tieshengWebConfigurer;
@@ -38,10 +38,8 @@ public class FileUploadService {
public String saveMultipartFile(MultipartFile file) {
try {
- if (tieshengWebConfigurer != null) {
- String fileType = FileTypeUtil.getType(file.getInputStream(), file.getOriginalFilename());
- tieshengWebConfigurer.uploadFileCheck(fileType);
- }
+ String fileType = FileTypeUtil.getType(file.getInputStream(), file.getOriginalFilename());
+ tieshengWebConfigurer.uploadFileCheck(fileType);
FileUploadPath filePath = FileUploadPath.random();
@@ -65,9 +63,7 @@ public class FileUploadService {
* @param fileExt
*/
public void chunkStart(String fileExt) {
- if (tieshengWebConfigurer != null) {
- tieshengWebConfigurer.uploadFileCheck(fileExt);
- }
+ tieshengWebConfigurer.uploadFileCheck(fileExt);
}
/**
@@ -111,33 +107,33 @@ public class FileUploadService {
* 合并块文件
*
* @param fileMd5
- * @param fileExt
*/
public String chunkMerge(String fileMd5) {
- // 1,获取块文件的路径
+ // 1,获取文件块的目录
FileUploadPath folder = FileUploadPath.folder(fileMd5);
- // 2,生成保存文件路径
+ // 2,如果目录不存在
+ if (!FileUtil.exist(folder.getAbsolutePath())) {
+ throw new ApiException("请先上传文件块");
+ }
+
+ // 3,生成保存文件的路径
FileUploadPath uploadPath = FileUploadPath.random();
- // 3,如果文件不存在
- if (FileUtil.exist(folder.getAbsolutePath())) {
+ // 4,获取块文件,此列表是已经排好序的列表
+ List chunkFiles = getSortedChunkFiles(new File(folder.getAbsolutePath()));
- // 4,获取块文件,此列表是已经排好序的列表
- List chunkFiles = getChunkFiles(new File(folder.getAbsolutePath()));
-
- // 5,合并文件
- File newFile = FileUtil.newFile(uploadPath.getAbsolutePath());
- for (File file : chunkFiles) {
- byte[] bytes = FileUtil.readBytes(file);
- FileUtil.writeBytes(bytes, newFile, 0, bytes.length, true);
- }
-
- // 6,删除块文件目录
- FileUtil.del(folder.getAbsolutePath());
+ // 5,合并文件
+ File newFile = FileUtil.newFile(uploadPath.getAbsolutePath());
+ for (File file : chunkFiles) {
+ byte[] bytes = FileUtil.readBytes(file);
+ FileUtil.writeBytes(bytes, newFile, 0, bytes.length, true);
}
+ // 6,删除块文件目录
+ FileUtil.del(folder.getAbsolutePath());
+
return uploadPath.getHttpPath();
}
@@ -148,7 +144,7 @@ public class FileUploadService {
* @param chunkFileFolder
* @return
*/
- private List getChunkFiles(File chunkFileFolder) {
+ private List getSortedChunkFiles(File chunkFileFolder) {
//获取路径下的所有块文件
File[] chunkFiles = chunkFileFolder.listFiles();
diff --git a/tiesheng-login/src/main/resources/db/migration/tiesheng_login_log.sql b/tiesheng-web/src/main/resources/db/migration/core_log_login.sql
similarity index 100%
rename from tiesheng-login/src/main/resources/db/migration/tiesheng_login_log.sql
rename to tiesheng-web/src/main/resources/db/migration/core_log_login.sql
diff --git a/tiesheng-web/src/main/resources/db/migration/core_platform_unique.sql b/tiesheng-web/src/main/resources/db/migration/core_platform_unique.sql
new file mode 100644
index 0000000..b517b02
--- /dev/null
+++ b/tiesheng-web/src/main/resources/db/migration/core_platform_unique.sql
@@ -0,0 +1,22 @@
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for core_platform_unique
+-- ----------------------------
+CREATE TABLE `core_platform_unique`
+(
+ `id` varchar(50) NOT NULL,
+ `create_time` datetime NOT NULL,
+ `update_time` datetime NOT NULL,
+ `is_deleted` int(6) NOT NULL DEFAULT '0',
+ `user_id` varchar(50) DEFAULT NULL COMMENT '用户id',
+ `app_id` varchar(255) DEFAULT NULL COMMENT 'appId',
+ `unique_id` varchar(255) DEFAULT NULL COMMENT '唯一值',
+ `platform` varchar(255) DEFAULT NULL COMMENT '平台',
+ `info` text COMMENT '其他参数',
+ PRIMARY KEY (`id`)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4 COMMENT ='平台-唯一值';
+
+SET FOREIGN_KEY_CHECKS = 1;
diff --git a/tiesheng-login/src/main/resources/mapper/CoreLogLoginMapper.xml b/tiesheng-web/src/main/resources/mapper/CoreLogLoginMapper.xml
similarity index 86%
rename from tiesheng-login/src/main/resources/mapper/CoreLogLoginMapper.xml
rename to tiesheng-web/src/main/resources/mapper/CoreLogLoginMapper.xml
index 9aeaf93..700fbd3 100644
--- a/tiesheng-login/src/main/resources/mapper/CoreLogLoginMapper.xml
+++ b/tiesheng-web/src/main/resources/mapper/CoreLogLoginMapper.xml
@@ -1,7 +1,7 @@
-
-
+
+
@@ -18,4 +18,4 @@
id, create_time, update_time, is_deleted, user_id, user_name, platform, ip, address
-
\ No newline at end of file
+
diff --git a/tiesheng-web/src/main/resources/mapper/CorePlatformUniqueMapper.xml b/tiesheng-web/src/main/resources/mapper/CorePlatformUniqueMapper.xml
new file mode 100644
index 0000000..8cf45eb
--- /dev/null
+++ b/tiesheng-web/src/main/resources/mapper/CorePlatformUniqueMapper.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, create_time, update_time, is_deleted, user_id, app_id, unique_id, platform, info
+
+
\ No newline at end of file