publish 0.0.5

This commit is contained in:
曾文豪
2023-01-09 15:20:52 +08:00
parent e61b82d026
commit 7c6ab72016
57 changed files with 1381 additions and 305 deletions

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-parent</artifactId>
<version>0.0.4</version>
<version>0.0.5</version>
</parent>
<artifactId>demo</artifactId>
@@ -21,7 +21,7 @@
<dependency>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-web</artifactId>
<version>0.0.4</version>
<version>0.0.5</version>
</dependency>
</dependencies>

View File

@@ -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

View File

@@ -6,7 +6,7 @@
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-parent</artifactId>
<version>0.0.4</version>
<version>0.0.5</version>
<packaging>pom</packaging>
<name>tiesheng</name>
<description>杭州铁晟科技有限公司基础依赖</description>
@@ -24,8 +24,7 @@
<module>tiesheng-web</module>
<module>tiesheng-util</module>
<module>tiesheng-poi</module>
<module>tiesheng-ding</module>
<module>tiesheng-wxmp</module>
<module>tiesheng-platform</module>
<module>tiesheng-message</module>
<module>tiesheng-encrypt</module>
<module>tiesheng-annotation</module>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-parent</artifactId>
<version>0.0.4</version>
<version>0.0.5</version>
</parent>
<artifactId>tiesheng-annotation</artifactId>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-parent</artifactId>
<version>0.0.4</version>
<version>0.0.5</version>
</parent>
<artifactId>tiesheng-db-migration</artifactId>

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-parent</artifactId>
<version>0.0.4</version>
</parent>
<artifactId>tiesheng-ding</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-util</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-annotation</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -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<DingJsapiSignature> dingJssdk(@PathVariable String service, String url) {
DingJsapiSignature jsapiSignature = dingConfig.createJsapiSignature(service, url);
return ApiResp.respOK(jsapiSignature);
}
}

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-parent</artifactId>
<version>0.0.4</version>
<version>0.0.5</version>
</parent>
<artifactId>tiesheng-encrypt</artifactId>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-parent</artifactId>
<version>0.0.4</version>
<version>0.0.5</version>
</parent>
<artifactId>tiesheng-login</artifactId>
@@ -28,24 +28,16 @@
<dependency>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-ding</artifactId>
<artifactId>tiesheng-annotation</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-wxmp</artifactId>
<artifactId>tiesheng-platform</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@@ -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 {
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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
///////////////////////////////////////////////////////////////////////////

View File

@@ -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<String> uniqueIndex(@RequestBody UniqueIndexDTO dto) {
AtomicReference<TokenBean> 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<String, String> 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<DingJsapiSignature> 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<WxJsapiSignature> wxmpJssdk(@PathVariable String service, String url) {
WxJsapiSignature jsapiSignature = platformWxmpConfig.createJsapiSignature(service, url);
return ApiResp.respOK(jsapiSignature);
}
}

View File

@@ -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 {
}

View File

@@ -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;
}
}

View File

@@ -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<CoreLogLoginMapper, CoreLogLogin> {
/**
* 获取
*
* @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);
}
}

View File

@@ -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<TieshengLoginConfigurer> 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;
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta content="IE=edge" http-equiv="X-UA-Compatible"/>
<meta
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
name="viewport"
/>
</head>
<style>
body {
margin: 0;
padding: 0;
}
.contain {
display: flex;
flex-direction: column;
align-items: center;
height: 100vh;
width: 100%;
font-size: 14px;
color: #8a8a8a;
}
.errorImg {
width: 30vw;
height: 30vw;
object-fit: contain;
margin-bottom: 24px;
margin-top: 25vw;
}
</style>
<body>
<div class="contain">
<img alt="" class="errorImg" src="error.png">
<div id="message"></div>
</div>
<script type="text/javascript">
function getQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null) return decodeURI(r[2]);
return null;
}
let errorMessage = getQueryString("msg");
document.getElementById("message").innerText = errorMessage;
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta content="IE=edge" http-equiv="X-UA-Compatible"/>
<meta
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
name="viewport"
/>
<title>钉钉授权</title>
</head>
<body>
<script src="dingtalk.open.js"></script>
<script type="text/javascript">
function getQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null) return decodeURI(r[2]);
return null;
}
dd.runtime.permission.requestAuthCode({
corpId: getQueryString("corpId"),
onSuccess: function (result) {
let search = window.location.search + "&code=" + result.code;
window.location.href = "/auth/ding/oauth2/" + getQueryString("service") + search;
},
onFail: function (err) {
window.location.href = "./error.html?message=" + JSON.stringify(err);
}
})
</script>
</body>
</html>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-parent</artifactId>
<version>0.0.4</version>
<version>0.0.5</version>
</parent>
<artifactId>tiesheng-message</artifactId>
@@ -18,15 +18,10 @@
</properties>
<dependencies>
<dependency>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-ding</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-wxmp</artifactId>
<artifactId>tiesheng-platform</artifactId>
<version>${project.parent.version}</version>
</dependency>

View File

@@ -6,10 +6,10 @@
<parent>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-parent</artifactId>
<version>0.0.4</version>
<version>0.0.5</version>
</parent>
<artifactId>tiesheng-wxmp</artifactId>
<artifactId>tiesheng-platform</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
@@ -17,4 +17,12 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-util</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,10 @@
package com.tiesheng.platform;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan({
"com.tiesheng.platform.**.*",
})
public class PlatformAutoImportSelector {
}

View File

@@ -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<String, DingConfigBean> 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<String> userIds) {
public void messageNotification(String service, String title, String content, String actionUrl, List<String> 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));
}

View File

@@ -1,4 +1,4 @@
package com.tiesheng.ding.pojos;
package com.tiesheng.platform.config.ding.bean;
/**
* @author hao

View File

@@ -1,4 +1,4 @@
package com.tiesheng.ding.pojos;
package com.tiesheng.platform.config.ding.bean;
public class DingDeptVo {

View File

@@ -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;

View File

@@ -1,4 +1,4 @@
package com.tiesheng.ding.pojos;
package com.tiesheng.platform.config.ding.bean;
import java.util.Objects;

View File

@@ -1,4 +1,4 @@
package com.tiesheng.ding.pojos;
package com.tiesheng.platform.config.ding.bean;
import java.util.List;

View File

@@ -1,4 +1,4 @@
package com.tiesheng.ding.pojos;
package com.tiesheng.platform.config.ding.bean;
import java.util.ArrayList;
import java.util.List;

View File

@@ -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<String, WxConfigBean> 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<String, Object> 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<String, Object> 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 <a href='https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/Get_temporary_materials.html'></a>
*/
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<String, WxConfigBean> getConfigs() {
return configs;
}
public void setConfigs(Map<String, WxConfigBean> configs) {
this.configs = configs;
}
public WxConfigBean getGlobal() {
return global;
}
public void setGlobal(WxConfigBean global) {
this.global = global;
}
}

View File

@@ -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;
}
}

View File

@@ -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() +
"&timestamp=" + 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-parent</artifactId>
<version>0.0.4</version>
<version>0.0.5</version>
</parent>
<artifactId>tiesheng-poi</artifactId>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-parent</artifactId>
<version>0.0.4</version>
<version>0.0.5</version>
</parent>
<artifactId>tiesheng-util</artifactId>

View File

@@ -17,6 +17,7 @@ public class ApiResp<T> {
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<T> {
public void setEncrypt(boolean encrypt) {
this.encrypt = encrypt;
}
public Throwable getException() {
return exception;
}
public void setException(Throwable exception) {
this.exception = exception;
}
}

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.tiesheng</groupId>
<artifactId>tiesheng-parent</artifactId>
<version>0.0.4</version>
<version>0.0.5</version>
</parent>
<artifactId>tiesheng-web</artifactId>

View File

@@ -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);
}
}

View File

@@ -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();

View File

@@ -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 {
}

View File

@@ -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<String> addExceptionHandler(Exception e) {
LogFactory.get().info(e);
return ApiResp.respCust(ApiRespEnum.ServerError);
ApiResp<String> 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);
}
}

View File

@@ -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<CoreLogLogin> page = dto.pageObj();
if (loginLogService != null) {
loginLogService.page(page, queryWrapper);
}
coreLogService.getLogLoginMapper().selectPage(page, queryWrapper);
return ApiResp.respOK(page.getRecords(), page.getTotal());
}

View File

@@ -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<CoreLogLogin> {
}
}

View File

@@ -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<CorePlatformUnique> {
}

View File

@@ -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
*

View File

@@ -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;
}
}

View File

@@ -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<CoreLogOperationMapper, CoreLogOperation> {
@Autowired(required = false)
@Autowired
TieshengWebConfigurer tieshengWebConfigurer;
@Autowired
CoreLogLoginMapper coreLogLoginMapper;
public CoreLogLoginMapper getLogLoginMapper() {
return coreLogLoginMapper;
}
///////////////////////////////////////////////////////////////////////////
// 操作日志
@@ -28,13 +42,9 @@ public class CoreLogService extends TsServiceBase<CoreLogOperationMapper, CoreLo
*/
public void addOperationLog(String title, String subject, Object params) {
CoreLogOperation operation = new CoreLogOperation();
if (tieshengWebConfigurer != null) {
CurrentWebUser currentWebUser = tieshengWebConfigurer.getCurrentUserName();
operation.setUserId(currentWebUser.getId());
operation.setUserName(currentWebUser.getName());
} else {
operation.setUserId(TsTokenConfig.getWithoutThr().getId());
}
CurrentWebUser currentWebUser = tieshengWebConfigurer.getCurrentUserName();
operation.setUserId(currentWebUser.getId());
operation.setUserName(currentWebUser.getName());
operation.setTitle(title);
operation.setSubject(subject);
if (params != null) {
@@ -43,4 +53,29 @@ public class CoreLogService extends TsServiceBase<CoreLogOperationMapper, CoreLo
save(operation);
}
///////////////////////////////////////////////////////////////////////////
// 登录日志
///////////////////////////////////////////////////////////////////////////
/**
* 添加登录日志
*
* @param platformUnique
*/
public void addLoginLog(CorePlatformUnique platformUnique) {
HttpServletRequest request = ServletKit.getRequest();
String ip = ServletUtil.getClientIP(request);
CoreLogLogin login = new CoreLogLogin();
login.setUserId(platformUnique.getUserId());
login.setPlatform(platformUnique.getPlatform());
login.setIp(ip);
DataBlock dataBlock = Ip2Region.getInstance().btreeSearch(ip);
login.setAddress(dataBlock.getRegion());
coreLogLoginMapper.insert(login);
}
}

View File

@@ -0,0 +1,71 @@
package com.tiesheng.core.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tiesheng.core.config.web.TieshengWebConfigurer;
import com.tiesheng.core.mapper.CorePlatformUniqueMapper;
import com.tiesheng.core.pojos.dao.CorePlatformUnique;
import com.tiesheng.login.config.TieshengLoginConfigurer;
import com.tiesheng.login.config.token.bean.TokenBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
/**
* @author hao
*/
@Service
public class CorePlatformUniqueService extends TsServiceBase<CorePlatformUniqueMapper, CorePlatformUnique> 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<CorePlatformUnique> 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;
}
}

View File

@@ -22,7 +22,7 @@ import java.util.List;
@Service
public class FileUploadService {
@Autowired(required = false)
@Autowired
TieshengWebConfigurer tieshengWebConfigurer;
@@ -38,10 +38,8 @@ public class FileUploadService {
public String saveMultipartFile(MultipartFile file) {
try {
if (tieshengWebConfigurer != null) {
String fileType = FileTypeUtil.getType(file.getInputStream(), file.getOriginalFilename());
tieshengWebConfigurer.uploadFileCheck(fileType);
}
String fileType = FileTypeUtil.getType(file.getInputStream(), file.getOriginalFilename());
tieshengWebConfigurer.uploadFileCheck(fileType);
FileUploadPath filePath = FileUploadPath.random();
@@ -65,9 +63,7 @@ public class FileUploadService {
* @param fileExt
*/
public void chunkStart(String fileExt) {
if (tieshengWebConfigurer != null) {
tieshengWebConfigurer.uploadFileCheck(fileExt);
}
tieshengWebConfigurer.uploadFileCheck(fileExt);
}
/**
@@ -111,33 +107,33 @@ public class FileUploadService {
* 合并块文件
*
* @param fileMd5
* @param fileExt
*/
public String chunkMerge(String fileMd5) {
// 1获取文件的路径
// 1获取文件块的目录
FileUploadPath folder = FileUploadPath.folder(fileMd5);
// 2生成保存文件路径
// 2如果目录不存在
if (!FileUtil.exist(folder.getAbsolutePath())) {
throw new ApiException("请先上传文件块");
}
// 3生成保存文件的路径
FileUploadPath uploadPath = FileUploadPath.random();
// 3如果文件不存在
if (FileUtil.exist(folder.getAbsolutePath())) {
// 4获取块文件此列表是已经排好序的列表
List<File> chunkFiles = getSortedChunkFiles(new File(folder.getAbsolutePath()));
// 4获取块文件此列表是已经排好序的列表
List<File> chunkFiles = getChunkFiles(new File(folder.getAbsolutePath()));
// 5合并文件
File newFile = FileUtil.newFile(uploadPath.getAbsolutePath());
for (File file : chunkFiles) {
byte[] bytes = FileUtil.readBytes(file);
FileUtil.writeBytes(bytes, newFile, 0, bytes.length, true);
}
// 6删除块文件目录
FileUtil.del(folder.getAbsolutePath());
// 5合并文件
File newFile = FileUtil.newFile(uploadPath.getAbsolutePath());
for (File file : chunkFiles) {
byte[] bytes = FileUtil.readBytes(file);
FileUtil.writeBytes(bytes, newFile, 0, bytes.length, true);
}
// 6删除块文件目录
FileUtil.del(folder.getAbsolutePath());
return uploadPath.getHttpPath();
}
@@ -148,7 +144,7 @@ public class FileUploadService {
* @param chunkFileFolder
* @return
*/
private List<File> getChunkFiles(File chunkFileFolder) {
private List<File> getSortedChunkFiles(File chunkFileFolder) {
//获取路径下的所有块文件
File[] chunkFiles = chunkFileFolder.listFiles();

View File

@@ -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;

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tiesheng.login.mapper.CoreLogLoginMapper">
<resultMap id="BaseResultMap" type="com.tiesheng.login.pojos.dao.CoreLogLogin">
<mapper namespace="com.tiesheng.core.mapper.CoreLogLoginMapper">
<resultMap id="BaseResultMap" type="com.tiesheng.core.pojos.dao.CoreLogLogin">
<!--@mbg.generated-->
<!--@Table core_log_login-->
<id column="id" jdbcType="VARCHAR" property="id" />
@@ -18,4 +18,4 @@
<!--@mbg.generated-->
id, create_time, update_time, is_deleted, user_id, user_name, platform, ip, address
</sql>
</mapper>
</mapper>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tiesheng.core.mapper.CorePlatformUniqueMapper">
<resultMap id="BaseResultMap" type="com.tiesheng.core.pojos.dao.CorePlatformUnique">
<!--@mbg.generated-->
<!--@Table core_platform_unique-->
<id column="id" jdbcType="VARCHAR" property="id" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
<result column="is_deleted" jdbcType="INTEGER" property="isDeleted" />
<result column="user_id" jdbcType="VARCHAR" property="userId" />
<result column="app_id" jdbcType="VARCHAR" property="appId" />
<result column="unique_id" jdbcType="VARCHAR" property="uniqueId" />
<result column="platform" jdbcType="VARCHAR" property="platform" />
<result column="info" jdbcType="LONGVARCHAR" property="info" />
</resultMap>
<sql id="Base_Column_List">
<!--@mbg.generated-->
id, create_time, update_time, is_deleted, user_id, app_id, unique_id, platform, info
</sql>
</mapper>