Merge branch 'dev' into 'test'
重写手动针对用户以及组织的单条同步逻辑 See merge request jygk/dsc!29
This commit is contained in:
514
docs/iWork用印流程集成开发文档.md
Normal file
514
docs/iWork用印流程集成开发文档.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,7 @@ import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -45,6 +46,7 @@ public class ZtDataPermissionAutoConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
public MenuDataPermissionHandler menuDataPermissionHandler(MybatisPlusInterceptor interceptor) {
|
public MenuDataPermissionHandler menuDataPermissionHandler(MybatisPlusInterceptor interceptor) {
|
||||||
// 创建菜单数据权限处理器
|
// 创建菜单数据权限处理器
|
||||||
MenuDataPermissionHandler handler = new MenuDataPermissionHandler();
|
MenuDataPermissionHandler handler = new MenuDataPermissionHandler();
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionIntercepto
|
|||||||
import com.zt.plat.framework.datapermission.core.menudatapermission.handler.MenuDataPermissionHandler;
|
import com.zt.plat.framework.datapermission.core.menudatapermission.handler.MenuDataPermissionHandler;
|
||||||
import com.zt.plat.framework.mybatis.core.util.MyBatisUtils;
|
import com.zt.plat.framework.mybatis.core.util.MyBatisUtils;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -20,6 +21,7 @@ public class MenuDataPermissionConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnBean(MybatisPlusInterceptor.class)
|
@ConditionalOnBean(MybatisPlusInterceptor.class)
|
||||||
|
@ConditionalOnMissingBean
|
||||||
public MenuDataPermissionHandler menuDataPermissionHandler(MybatisPlusInterceptor interceptor) {
|
public MenuDataPermissionHandler menuDataPermissionHandler(MybatisPlusInterceptor interceptor) {
|
||||||
// 创建菜单数据权限处理器
|
// 创建菜单数据权限处理器
|
||||||
MenuDataPermissionHandler handler = new MenuDataPermissionHandler();
|
MenuDataPermissionHandler handler = new MenuDataPermissionHandler();
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ public class DeptDataPermissionRule implements DataPermissionRule {
|
|||||||
/**
|
/**
|
||||||
* 基于用户的表字段配置
|
* 基于用户的表字段配置
|
||||||
* 一般情况下,每个表的部门编号字段是 dept_id,通过该配置自定义。
|
* 一般情况下,每个表的部门编号字段是 dept_id,通过该配置自定义。
|
||||||
* key:表名
|
|
||||||
* value:字段名
|
* value:字段名
|
||||||
*/
|
*/
|
||||||
private final Map<String, String> userColumns = new HashMap<>();
|
private final Map<String, String> userColumns = new HashMap<>();
|
||||||
@@ -262,7 +261,11 @@ public class DeptDataPermissionRule implements DataPermissionRule {
|
|||||||
if (Boolean.FALSE.equals(self)) {
|
if (Boolean.FALSE.equals(self)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String columnName = userColumns.get(tableName);
|
String userColumnsKey = tableName;
|
||||||
|
if (StrUtil.isNotBlank(workCode)) {
|
||||||
|
userColumnsKey = userColumnsKey + "_work_code";
|
||||||
|
}
|
||||||
|
String columnName = userColumns.get(userColumnsKey);
|
||||||
if (StrUtil.isEmpty(columnName)) {
|
if (StrUtil.isEmpty(columnName)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,8 +77,13 @@ public class DbSqlSessionFactory implements SessionFactory {
|
|||||||
// 当前系统适配 dm,如果存在 schema 为空的情况,从 connection 获取
|
// 当前系统适配 dm,如果存在 schema 为空的情况,从 connection 获取
|
||||||
try {
|
try {
|
||||||
if (getDatabaseSchema() == null || getDatabaseSchema().length() == 0){
|
if (getDatabaseSchema() == null || getDatabaseSchema().length() == 0){
|
||||||
|
String schemaFromUrl = extractSchemaFromJdbcUrl(dbSqlSession.getSqlSession().getConnection());
|
||||||
|
if (schemaFromUrl != null && schemaFromUrl.length() > 0) {
|
||||||
|
setDatabaseSchema(schemaFromUrl);
|
||||||
|
} else {
|
||||||
setDatabaseSchema(dbSqlSession.getSqlSession().getConnection().getSchema());
|
setDatabaseSchema(dbSqlSession.getSqlSession().getConnection().getSchema());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
dbSqlSession.getSqlSession().getConnection().getSchema();
|
dbSqlSession.getSqlSession().getConnection().getSchema();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
@@ -351,4 +356,39 @@ public class DbSqlSessionFactory implements SessionFactory {
|
|||||||
public void setUsePrefixId(boolean usePrefixId) {
|
public void setUsePrefixId(boolean usePrefixId) {
|
||||||
this.usePrefixId = usePrefixId;
|
this.usePrefixId = usePrefixId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String extractSchemaFromJdbcUrl(java.sql.Connection connection) {
|
||||||
|
if (connection == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String url = connection.getMetaData().getURL();
|
||||||
|
if (url == null || url.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int queryIndex = url.indexOf('?');
|
||||||
|
if (queryIndex < 0 || queryIndex == url.length() - 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String query = url.substring(queryIndex + 1);
|
||||||
|
String[] parts = query.split("[&;]");
|
||||||
|
for (String part : parts) {
|
||||||
|
int eqIndex = part.indexOf('=');
|
||||||
|
if (eqIndex <= 0 || eqIndex == part.length() - 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String key = part.substring(0, eqIndex).trim().toLowerCase(Locale.ROOT);
|
||||||
|
if ("schema".equals(key) || "currentschema".equals(key) || "current_schema".equals(key)) {
|
||||||
|
String value = part.substring(eqIndex + 1).trim();
|
||||||
|
if ((value.startsWith("\"") && value.endsWith("\"")) || (value.startsWith("'") && value.endsWith("'"))) {
|
||||||
|
value = value.substring(1, value.length() - 1);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ignored) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static com.zt.plat.framework.common.pojo.CommonResult.error;
|
||||||
import static com.zt.plat.framework.common.pojo.CommonResult.success;
|
import static com.zt.plat.framework.common.pojo.CommonResult.success;
|
||||||
import static com.zt.plat.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
import static com.zt.plat.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||||
import static com.zt.plat.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment;
|
import static com.zt.plat.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment;
|
||||||
@@ -52,13 +53,13 @@ public class FileController {
|
|||||||
private FileService fileService;
|
private FileService fileService;
|
||||||
|
|
||||||
@GetMapping("/get")
|
@GetMapping("/get")
|
||||||
@Operation(summary = "获取文件预览地址", description = "根据 fileId 返回文件预览 url(kkfile),支持加密文件预览,需要传递验证码 code,加密文件预览地址默认5分钟内有效,可在配置文件中添加zt.file.preview-expire-seconds配置")
|
@Operation(summary = "获取文件预览地址", description = "根据 fileId 返回文件预览 url(kkfile),支持加密文件预览,加密文件预览地址默认5分钟内有效,可在配置文件中添加zt.file.preview-expire-seconds配置有效时间")
|
||||||
public CommonResult<FileRespVO> getPreviewUrl(@RequestParam("fileId") Long fileId,
|
public CommonResult<FileRespVO> getPreviewUrl(@RequestParam("fileId") Long fileId,
|
||||||
@RequestParam(value = "code", required = false) String code,
|
@RequestParam(value = "code", required = false) String code,
|
||||||
HttpServletRequest request) throws Exception {
|
HttpServletRequest request) throws Exception {
|
||||||
FileDO fileDO = fileService.getActiveFileById(fileId);
|
FileDO fileDO = fileService.getActiveFileById(fileId);
|
||||||
if (fileDO == null) {
|
if (fileDO == null) {
|
||||||
return CommonResult.error(HttpStatus.NOT_FOUND.value(), "文件不存在");
|
return error(HttpStatus.NOT_FOUND.value(), "文件不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 统计下载次数
|
// 统计下载次数
|
||||||
@@ -68,26 +69,24 @@ public class FileController {
|
|||||||
FileRespVO fileRespVO = BeanUtils.toBean(fileDO, FileRespVO.class);
|
FileRespVO fileRespVO = BeanUtils.toBean(fileDO, FileRespVO.class);
|
||||||
|
|
||||||
// 加密文件:塞入“临时解密预览 URL”
|
// 加密文件:塞入“临时解密预览 URL”
|
||||||
if (Boolean.TRUE.equals(fileRespVO.getIsEncrypted())) { // FileDO 通过 aesIv 判断加密
|
if (Boolean.TRUE.equals(fileRespVO.getIsEncrypted()) // FileDO 通过 aesIv 判断加密
|
||||||
|
&& cn.hutool.core.util.StrUtil.isNotBlank(code)) { // 预览文件会调用两次该接口,只有code不为空时候才塞url
|
||||||
|
|
||||||
if (cn.hutool.core.util.StrUtil.isBlank(code)) {
|
/*if (cn.hutool.core.util.StrUtil.isBlank(code)) {
|
||||||
return CommonResult.error(HttpStatus.BAD_REQUEST.value(), "加密文件预览需要验证码 code");
|
return CommonResult.error(HttpStatus.BAD_REQUEST.value(), "加密文件预览需要验证码 code");
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// 验证通过:发放给 kkfile 用的短期 token(kkfile 不带登录态)
|
// 验证通过:发放给 kkfile 用的短期 token(kkfile 不带登录态)
|
||||||
Long userId = getLoginUserId();
|
Long userId = getLoginUserId();
|
||||||
boolean flag = fileService.verifyCode(fileId, userId, code);
|
boolean flag = fileService.verifyCode(fileId, userId, code);
|
||||||
if(!flag){
|
if(!flag){
|
||||||
return CommonResult.customize(null, HttpStatus.INTERNAL_SERVER_ERROR.value(), "验证码错误");
|
return error(HttpStatus.BAD_REQUEST.value(), "验证码错误");
|
||||||
}
|
}
|
||||||
|
|
||||||
String token = fileService.generatePreviewToken(fileId, userId);
|
String token = fileService.generatePreviewToken(fileId, userId);
|
||||||
|
|
||||||
String baseUrl = buildPublicBaseUrl(request); // 见下方函数
|
String baseUrl = buildPublicBaseUrl(request); // 见下方函数
|
||||||
|
|
||||||
String fullfilename = java.net.URLEncoder
|
String fullfilename = java.net.URLEncoder
|
||||||
.encode(fileDO.getName(), java.nio.charset.StandardCharsets.UTF_8)
|
.encode(fileDO.getName(), java.nio.charset.StandardCharsets.UTF_8)
|
||||||
.replace("+", "%20");
|
.replace("+", "%20");
|
||||||
|
|
||||||
String decryptUrl = baseUrl + "/admin-api/infra/file/preview-decrypt"
|
String decryptUrl = baseUrl + "/admin-api/infra/file/preview-decrypt"
|
||||||
+ "?fileId=" + fileId
|
+ "?fileId=" + fileId
|
||||||
+ "&token=" + token
|
+ "&token=" + token
|
||||||
@@ -215,14 +214,14 @@ public class FileController {
|
|||||||
try {
|
try {
|
||||||
sendTypeEnum = VerifyCodeSendType.valueOf(sendType.trim().toUpperCase());
|
sendTypeEnum = VerifyCodeSendType.valueOf(sendType.trim().toUpperCase());
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
return CommonResult.error(HttpStatus.BAD_REQUEST.value(),
|
return error(HttpStatus.BAD_REQUEST.value(),
|
||||||
"sendType 参数不合法,可选:SMS / E_OFFICE");
|
"sendType 参数不合法,可选:SMS / E_OFFICE");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileDO activeFileById = fileService.getActiveFileById(fileId);
|
FileDO activeFileById = fileService.getActiveFileById(fileId);
|
||||||
if (activeFileById == null) {
|
if (activeFileById == null) {
|
||||||
return CommonResult.error(HttpStatus.NOT_FOUND.value(), "文件不存在");
|
return error(HttpStatus.NOT_FOUND.value(), "文件不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
FileRespVO fileRespVO = BeanUtils.toBean(activeFileById, FileRespVO.class);
|
FileRespVO fileRespVO = BeanUtils.toBean(activeFileById, FileRespVO.class);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public class DataPermissionConfiguration {
|
|||||||
rule.addDeptColumn(DeptDO.class, "id");
|
rule.addDeptColumn(DeptDO.class, "id");
|
||||||
// user
|
// user
|
||||||
rule.addUserColumn(AdminUserDO.class, "id");
|
rule.addUserColumn(AdminUserDO.class, "id");
|
||||||
|
rule.addUserColumn("system_users_work_code", "workcode");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,14 +47,14 @@ spring:
|
|||||||
primary: master
|
primary: master
|
||||||
datasource:
|
datasource:
|
||||||
master:
|
master:
|
||||||
url: jdbc:dm://172.16.46.247:1050?schema=RUOYI-VUE-PRO
|
url: jdbc:dm://172.17.11.98:20870?schema=JYGK_TEST
|
||||||
username: SYSDBA
|
username: SYSDBA
|
||||||
password: pgbsci6ddJ6Sqj@e
|
password: P@ssword25
|
||||||
slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
|
slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
|
||||||
lazy: true # 开启懒加载,保证启动速度
|
lazy: true # 开启懒加载,保证启动速度
|
||||||
url: jdbc:dm://172.16.46.247:1050?schema=RUOYI-VUE-PRO
|
url: jdbc:dm://172.17.11.98:20870?schema=JYGK_TEST
|
||||||
username: SYSDBA
|
username: SYSDBA
|
||||||
password: pgbsci6ddJ6Sqj@e
|
password: P@ssword25
|
||||||
|
|
||||||
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
|
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
|
||||||
data:
|
data:
|
||||||
|
|||||||
Reference in New Issue
Block a user