From 7c6ab720164c2bd7a597ebb84adb88f85a9180d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=BE=E6=96=87=E8=B1=AA?= <980287353@qq.com> Date: Mon, 9 Jan 2023 15:20:52 +0800 Subject: [PATCH] publish 0.0.5 --- demo/pom.xml | 4 +- demo/src/main/resources/application.yml | 8 +- pom.xml | 5 +- tiesheng-annotation/pom.xml | 2 +- tiesheng-db-migration/pom.xml | 2 +- tiesheng-ding/pom.xml | 41 ---- .../controller/PlatformDingController.java | 36 ---- tiesheng-encrypt/pom.xml | 2 +- tiesheng-login/pom.xml | 14 +- .../login/LoginAutoImportSelector.java | 5 +- .../login/config/TieshengLoginConfigurer.java | 30 +++ .../login/config/token/TsTokenConfig.java | 13 -- .../login/config/token/bean/TokenBean.java | 20 ++ .../login/controller/LoginController.java | 201 ++++++++++++++++++ .../login/controller/LoginUserController.java | 12 -- .../login/pojos/dto/UniqueIndexDTO.java | 50 +++++ .../login/service/LoginLogService.java | 42 ---- .../tiesheng/login/service/LoginService.java | 57 +++++ .../resources/static/ding/dingtalk.open.js | 1 + .../src/main/resources/static/ding/error.html | 61 ++++++ .../src/main/resources/static/ding/error.png | Bin 0 -> 11497 bytes .../src/main/resources/static/ding/index.html | 37 ++++ tiesheng-message/pom.xml | 9 +- {tiesheng-wxmp => tiesheng-platform}/pom.xml | 12 +- .../platform/PlatformAutoImportSelector.java | 10 + .../config/ding/PlatformDingConfig.java | 16 +- .../config/ding/bean}/DingConfigBean.java | 2 +- .../config/ding/bean}/DingDeptVo.java | 2 +- .../config/ding/bean}/DingJsapiSignature.java | 2 +- .../config/ding/bean}/DingResponse.java | 2 +- .../config/ding/bean}/DingUserInfo.java | 2 +- .../config/ding/bean}/DingUserListVo.java | 2 +- .../config/wxmp/PlatformWxmpConfig.java | 181 ++++++++++++++++ .../config/wxmp/bean/WxConfigBean.java | 30 +++ .../config/wxmp/bean/WxJsapiSignature.java | 81 +++++++ .../config/wxmp/bean/WxOAuth2AccessToken.java | 46 ++++ .../platform/config/wxmp/bean/WxUserInfo.java | 115 ++++++++++ tiesheng-poi/pom.xml | 2 +- tiesheng-util/pom.xml | 2 +- .../java/com/tiesheng/util/pojos/ApiResp.java | 9 + tiesheng-web/pom.xml | 2 +- .../exception/SpringExceptionHandler.java | 7 +- .../config/json/FastJsonMessageConverter.java | 4 +- .../core/config/web/DefaultWebConfigurer.java | 13 ++ .../config/web/TieshengWebConfigurer.java | 58 ++++- ...rLogController.java => LogController.java} | 11 +- .../core}/mapper/CoreLogLoginMapper.java | 6 +- .../core/mapper/CorePlatformUniqueMapper.java | 7 + .../core}/pojos/dao/CoreLogLogin.java | 55 +---- .../core/pojos/dao/CorePlatformUnique.java | 134 ++++++++++++ .../tiesheng/core/service/CoreLogService.java | 53 ++++- .../service/CorePlatformUniqueService.java | 71 +++++++ .../core/service/FileUploadService.java | 48 ++--- .../resources/db/migration/core_log_login.sql | 0 .../db/migration/core_platform_unique.sql | 22 ++ .../resources/mapper/CoreLogLoginMapper.xml | 6 +- .../mapper/CorePlatformUniqueMapper.xml | 21 ++ 57 files changed, 1381 insertions(+), 305 deletions(-) delete mode 100644 tiesheng-ding/pom.xml delete mode 100644 tiesheng-ding/src/main/java/com/tiesheng/ding/controller/PlatformDingController.java create mode 100644 tiesheng-login/src/main/java/com/tiesheng/login/config/TieshengLoginConfigurer.java create mode 100644 tiesheng-login/src/main/java/com/tiesheng/login/controller/LoginController.java delete mode 100644 tiesheng-login/src/main/java/com/tiesheng/login/controller/LoginUserController.java create mode 100644 tiesheng-login/src/main/java/com/tiesheng/login/pojos/dto/UniqueIndexDTO.java delete mode 100644 tiesheng-login/src/main/java/com/tiesheng/login/service/LoginLogService.java create mode 100644 tiesheng-login/src/main/java/com/tiesheng/login/service/LoginService.java create mode 100644 tiesheng-login/src/main/resources/static/ding/dingtalk.open.js create mode 100644 tiesheng-login/src/main/resources/static/ding/error.html create mode 100644 tiesheng-login/src/main/resources/static/ding/error.png create mode 100644 tiesheng-login/src/main/resources/static/ding/index.html rename {tiesheng-wxmp => tiesheng-platform}/pom.xml (67%) create mode 100644 tiesheng-platform/src/main/java/com/tiesheng/platform/PlatformAutoImportSelector.java rename tiesheng-ding/src/main/java/com/tiesheng/ding/config/DingConfig.java => tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/PlatformDingConfig.java (95%) rename {tiesheng-ding/src/main/java/com/tiesheng/ding/pojos => tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean}/DingConfigBean.java (95%) rename {tiesheng-ding/src/main/java/com/tiesheng/ding/pojos => tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean}/DingDeptVo.java (93%) rename {tiesheng-ding/src/main/java/com/tiesheng/ding/pojos => tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean}/DingJsapiSignature.java (97%) rename {tiesheng-ding/src/main/java/com/tiesheng/ding/pojos => tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean}/DingResponse.java (95%) rename {tiesheng-ding/src/main/java/com/tiesheng/ding/pojos => tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean}/DingUserInfo.java (98%) rename {tiesheng-ding/src/main/java/com/tiesheng/ding/pojos => tiesheng-platform/src/main/java/com/tiesheng/platform/config/ding/bean}/DingUserListVo.java (95%) create mode 100644 tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/PlatformWxmpConfig.java create mode 100644 tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxConfigBean.java create mode 100644 tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxJsapiSignature.java create mode 100644 tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxOAuth2AccessToken.java create mode 100644 tiesheng-platform/src/main/java/com/tiesheng/platform/config/wxmp/bean/WxUserInfo.java create mode 100644 tiesheng-web/src/main/java/com/tiesheng/core/config/web/DefaultWebConfigurer.java rename tiesheng-web/src/main/java/com/tiesheng/core/controller/log/{ManagerLogController.java => LogController.java} (86%) rename {tiesheng-login/src/main/java/com/tiesheng/login => tiesheng-web/src/main/java/com/tiesheng/core}/mapper/CoreLogLoginMapper.java (60%) create mode 100644 tiesheng-web/src/main/java/com/tiesheng/core/mapper/CorePlatformUniqueMapper.java rename {tiesheng-login/src/main/java/com/tiesheng/login => tiesheng-web/src/main/java/com/tiesheng/core}/pojos/dao/CoreLogLogin.java (60%) create mode 100644 tiesheng-web/src/main/java/com/tiesheng/core/pojos/dao/CorePlatformUnique.java create mode 100644 tiesheng-web/src/main/java/com/tiesheng/core/service/CorePlatformUniqueService.java rename tiesheng-login/src/main/resources/db/migration/tiesheng_login_log.sql => tiesheng-web/src/main/resources/db/migration/core_log_login.sql (100%) create mode 100644 tiesheng-web/src/main/resources/db/migration/core_platform_unique.sql rename {tiesheng-login => tiesheng-web}/src/main/resources/mapper/CoreLogLoginMapper.xml (86%) create mode 100644 tiesheng-web/src/main/resources/mapper/CorePlatformUniqueMapper.xml 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 0000000000000000000000000000000000000000..6441fb7904b55192cf409d5fa9ce49242e01fcb6 GIT binary patch literal 11497 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 SCxErffR>t`YK5|O*#82fxI5GU literal 0 HcmV?d00001 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,生成保存文件路径 - FileUploadPath uploadPath = FileUploadPath.random(); - - // 3,如果文件不存在 - if (FileUtil.exist(folder.getAbsolutePath())) { + // 2,如果目录不存在 + if (!FileUtil.exist(folder.getAbsolutePath())) { + throw new ApiException("请先上传文件块"); + } - // 4,获取块文件,此列表是已经排好序的列表 - List chunkFiles = getChunkFiles(new File(folder.getAbsolutePath())); + // 3,生成保存文件的路径 + FileUploadPath uploadPath = FileUploadPath.random(); - // 5,合并文件 - File newFile = FileUtil.newFile(uploadPath.getAbsolutePath()); - for (File file : chunkFiles) { - byte[] bytes = FileUtil.readBytes(file); - FileUtil.writeBytes(bytes, newFile, 0, bytes.length, true); - } + // 4,获取块文件,此列表是已经排好序的列表 + List chunkFiles = getSortedChunkFiles(new File(folder.getAbsolutePath())); - // 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