mirror of
https://gitee.com/zhijiantianya/yudao-cloud.git
synced 2026-05-21 14:48:00 +00:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f8129d65b | ||
|
|
6d13b43593 | ||
|
|
5d0a1a6fb5 | ||
|
|
fcfd494747 | ||
|
|
5dd5bfb2c7 | ||
|
|
797244b845 | ||
|
|
2d160aeacd | ||
|
|
c9a50da6f9 | ||
|
|
9347e136a4 | ||
|
|
9b08d0a38c | ||
|
|
dc4f17cb4f | ||
|
|
8d6f7db67b | ||
|
|
9525f2d7ec | ||
|
|
e0e814f38a | ||
|
|
787d7600be | ||
|
|
a9cda4fdb2 | ||
|
|
a3b007b462 | ||
|
|
2247f21db8 | ||
|
|
f672af1a09 | ||
|
|
476adb035a | ||
|
|
b4bf529179 | ||
|
|
ac5299a00b |
10
README.md
10
README.md
@@ -9,7 +9,9 @@
|
||||
|
||||
## 🐶 新手必读
|
||||
|
||||
* 演示地址:<http://dashboard.yudao.iocoder.cn>
|
||||
* 演示地址【Vue3 + element-plus】:<http://dashboard-vue3.yudao.iocoder.cn>
|
||||
* 演示地址【Vue3 + vben(ant-design-vue)】:<http://dashboard-vben.yudao.iocoder.cn>
|
||||
* 演示地址【Vue2 + element-ui】:<http://dashboard.yudao.iocoder.cn>
|
||||
* 启动文档:<https://cloud.iocoder.cn/quick-start/>
|
||||
* 视频教程:<https://cloud.iocoder.cn/video/>
|
||||
|
||||
@@ -23,8 +25,8 @@
|
||||
|
||||

|
||||
|
||||
* 管理后台的 Vue3 版本采用 [vue-element-plus-admin](https://gitee.com/kailong110120130/vue-element-plus-admin) ,Vue2 版本采用 [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
|
||||
* 管理后台的移动端采用 [uni-app](https://github.com/dcloudio/uni-app) 方案,一份代码多终端适配,同时支持 APP、小程序、H5!
|
||||
* 管理后台的电脑端:Vue3 提供 [element-plus](https://gitee.com/yudaocode/yudao-ui-admin-vue3)、[vben(ant-design-vue)](https://gitee.com/yudaocode/yudao-ui-admin-vben) 两个版本,Vue2 提供 [element-ui](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin) 版本
|
||||
* 管理后台的移动端:采用 [uni-app](https://github.com/dcloudio/uni-app) 方案,一份代码多终端适配,同时支持 APP、小程序、H5!
|
||||
* 后端采用 Spring Cloud Alibaba 微服务架构,注册中心 + 配置中心 Nacos,消息队列 RocketMQ,定时任务 XXL-Job,服务保障 Sentinel,服务网关 Gateway,分布式事务 Seata
|
||||
* 数据库可使用 MySQL、Oracle、PostgreSQL、SQL Server、MariaDB、国产达梦 DM、TiDB 等,基于 MyBatis Plus、Redis + Redisson 操作
|
||||
* 权限认证使用 Spring Security & Token & Redis,支持多终端、多种用户的认证系统,支持 SSO 单点登录
|
||||
@@ -254,7 +256,7 @@ ps:核心功能已经实现,正在对接微信小程序中...
|
||||
| [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 8.12.0 | [文档](http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao) |
|
||||
| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.7.10 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) |
|
||||
| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.13.3 | |
|
||||
| [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.5.3.Final | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) |
|
||||
| [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.5.5.Final | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) |
|
||||
| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.18.26 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) |
|
||||
| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.8.2 | - |
|
||||
| [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 4.8.0 | - |
|
||||
|
||||
6
pom.xml
6
pom.xml
@@ -25,7 +25,7 @@
|
||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||
|
||||
<properties>
|
||||
<revision>1.7.2-snapshot</revision>
|
||||
<revision>1.7.3-snapshot</revision>
|
||||
<!-- Maven 相关 -->
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
@@ -34,8 +34,8 @@
|
||||
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
|
||||
<!-- 看看咋放到 bom 里 -->
|
||||
<lombok.version>1.18.26</lombok.version>
|
||||
<spring.boot.version>2.7.10</spring.boot.version>
|
||||
<mapstruct.version>1.5.3.Final</mapstruct.version>
|
||||
<spring.boot.version>2.7.11</spring.boot.version>
|
||||
<mapstruct.version>1.5.5.Final</mapstruct.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
|
||||
5713
sql/dm/ruoyi-vue-pro-dm8.sql
Normal file
5713
sql/dm/ruoyi-vue-pro-dm8.sql
Normal file
File diff suppressed because it is too large
Load Diff
@@ -14,9 +14,9 @@
|
||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||
|
||||
<properties>
|
||||
<revision>1.7.2-snapshot</revision>
|
||||
<revision>1.7.3-snapshot</revision>
|
||||
<!-- 统一依赖管理 -->
|
||||
<spring.boot.version>2.7.10</spring.boot.version>
|
||||
<spring.boot.version>2.7.11</spring.boot.version>
|
||||
<spring.cloud.version>2021.0.5</spring.cloud.version>
|
||||
<spring.cloud.alibaba.version>2021.0.4.0</spring.cloud.alibaba.version>
|
||||
<!-- Web 相关 -->
|
||||
@@ -30,6 +30,7 @@
|
||||
<mybatis-plus-generator.version>3.5.3.1</mybatis-plus-generator.version>
|
||||
<dynamic-datasource.version>3.6.1</dynamic-datasource.version>
|
||||
<redisson.version>3.18.0</redisson.version>
|
||||
<dm8.jdbc.version>8.1.2.141</dm8.jdbc.version>
|
||||
<!-- RPC 相关 -->
|
||||
<dubbo.version>2.7.18</dubbo.version>
|
||||
<!-- Config 配置中心相关 -->
|
||||
@@ -53,9 +54,9 @@
|
||||
<captcha-plus.version>1.0.2</captcha-plus.version>
|
||||
<jsoup.version>1.15.4</jsoup.version>
|
||||
<lombok.version>1.18.26</lombok.version>
|
||||
<mapstruct.version>1.5.3.Final</mapstruct.version>
|
||||
<hutool.version>5.8.15</hutool.version>
|
||||
<easyexcel.verion>3.2.1</easyexcel.verion>
|
||||
<mapstruct.version>1.5.5.Final</mapstruct.version>
|
||||
<hutool.version>5.8.18</hutool.version>
|
||||
<easyexcel.verion>3.3.1</easyexcel.verion>
|
||||
<velocity.version>2.3</velocity.version>
|
||||
<screw.version>1.0.5</screw.version>
|
||||
<fastjson.version>1.2.83</fastjson.version>
|
||||
@@ -71,6 +72,7 @@
|
||||
<!-- 三方云服务相关 -->
|
||||
<okio.version>3.0.0</okio.version>
|
||||
<okhttp3.version>4.10.0</okhttp3.version>
|
||||
<commons-io.version>2.11.0</commons-io.version>
|
||||
<minio.version>8.5.2</minio.version>
|
||||
<aliyun-java-sdk-core.version>4.6.3</aliyun-java-sdk-core.version>
|
||||
<aliyun-java-sdk-dysmsapi.version>2.2.1</aliyun-java-sdk-dysmsapi.version>
|
||||
@@ -285,6 +287,12 @@
|
||||
<version>${redisson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.dameng</groupId>
|
||||
<artifactId>DmJdbcDriver18</artifactId>
|
||||
<version>${dm8.jdbc.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- RPC 远程调用相关 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
@@ -526,6 +534,12 @@
|
||||
<version>${easyexcel.verion}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.tika</groupId>
|
||||
<artifactId>tika-core</artifactId> <!-- 文件类型的识别 -->
|
||||
|
||||
@@ -29,6 +29,15 @@ package cn.iocoder.yudao.framework.common.exception.enums;
|
||||
*/
|
||||
public class ServiceErrorCodeRange {
|
||||
|
||||
// 模块 system 错误码区间 [1-000-001-000 ~ 1-000-002-000]
|
||||
// 模块 infra 错误码区间 [1-001-000-000 ~ 1-002-000-000)
|
||||
// 模块 system 错误码区间 [1-002-000-000 ~ 1-003-000-000)
|
||||
// 模块 report 错误码区间 [1-003-000-000 ~ 1-004-000-000)
|
||||
// 模块 member 错误码区间 [1-004-000-000 ~ 1-005-000-000)
|
||||
// 模块 mp 错误码区间 [1-006-000-000 ~ 1-007-000-000)
|
||||
// 模块 pay 错误码区间 [1-007-000-000 ~ 1-008-000-000)
|
||||
// 模块 product 错误码区间 [1-008-000-000 ~ 1-009-000-000)
|
||||
// 模块 bpm 错误码区间 [1-009-000-000 ~ 1-010-000-000)
|
||||
// 模块 trade 错误码区间 [1-011-000-000 ~ 1-012-000-000)
|
||||
// 模块 promotion 错误码区间 [1-013-000-000 ~ 1-014-000-000)
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package cn.iocoder.yudao.framework.common.util.collection;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -11,8 +11,9 @@ import java.util.Set;
|
||||
*/
|
||||
public class SetUtils {
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> Set<T> asSet(T... objs) {
|
||||
return new HashSet<>(Arrays.asList(objs));
|
||||
return CollUtil.newHashSet(objs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.framework.common.util.string;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
@@ -13,7 +14,14 @@ import java.util.Collection;
|
||||
public class StrUtils {
|
||||
|
||||
public static String maxLength(CharSequence str, int maxLength) {
|
||||
return StrUtil.maxLength(str, maxLength - 3); // -3 的原因,是该方法会补充 ... 恰好
|
||||
Assert.isTrue(maxLength > 0);
|
||||
if (null == str) {
|
||||
return null;
|
||||
}
|
||||
if (str.length() <= maxLength) {
|
||||
return str.toString();
|
||||
}
|
||||
return StrUtil.sub(str, 0, maxLength - 3) + "..."; // -3 的原因,是该方法会补充 ... 恰好
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* 微信拓展
|
||||
* 1. 基于 weixin-java-mp 库,对接微信公众号平台。目前主要解决微信公众号的支付场景。
|
||||
* 2. 基于 weixin-java-miniapp 库,对接微信小程序。目前主要解决微信小程序的一键登录场景。
|
||||
*/
|
||||
package cn.iocoder.yudao.framework.weixin;
|
||||
@@ -45,6 +45,10 @@
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dameng</groupId>
|
||||
<artifactId>DmJdbcDriver18</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
|
||||
@@ -5,10 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.handler.DefaultDBFieldHandler;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
|
||||
import com.baomidou.mybatisplus.extension.incrementer.H2KeyGenerator;
|
||||
import com.baomidou.mybatisplus.extension.incrementer.KingbaseKeyGenerator;
|
||||
import com.baomidou.mybatisplus.extension.incrementer.OracleKeyGenerator;
|
||||
import com.baomidou.mybatisplus.extension.incrementer.PostgreKeyGenerator;
|
||||
import com.baomidou.mybatisplus.extension.incrementer.*;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
@@ -56,6 +53,8 @@ public class YudaoMybatisAutoConfiguration {
|
||||
return new H2KeyGenerator();
|
||||
case KINGBASE_ES:
|
||||
return new KingbaseKeyGenerator();
|
||||
case DM:
|
||||
return new DmKeyGenerator();
|
||||
}
|
||||
}
|
||||
// 找不到合适的 IKeyGenerator 实现类
|
||||
|
||||
@@ -9,6 +9,7 @@ import cn.iocoder.yudao.gateway.util.WebFrameworkUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.cloud.gateway.filter.factory.rewrite.CachedBodyOutputMessage;
|
||||
@@ -23,7 +24,7 @@ import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ReactiveHttpOutputMessage;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
@@ -31,12 +32,12 @@ import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.BodyInserter;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerStrategies;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
@@ -57,7 +58,8 @@ import static cn.hutool.core.date.DatePattern.NORM_DATETIME_MS_FORMATTER;
|
||||
@Component
|
||||
public class AccessLogFilter implements GlobalFilter, Ordered {
|
||||
|
||||
private final List<HttpMessageReader<?>> messageReaders = HandlerStrategies.withDefaults().messageReaders();
|
||||
@Resource
|
||||
private CodecConfigurer codecConfigurer;
|
||||
|
||||
/**
|
||||
* 打印日志
|
||||
@@ -137,7 +139,8 @@ public class AccessLogFilter implements GlobalFilter, Ordered {
|
||||
*/
|
||||
private Mono<Void> filterWithRequestBody(ServerWebExchange exchange, GatewayFilterChain chain, AccessLog gatewayLog) {
|
||||
// 设置 Request Body 读取时,设置到网关日志
|
||||
ServerRequest serverRequest = ServerRequest.create(exchange, messageReaders);
|
||||
// 此处 codecConfigurer.getReaders() 的目的,是解决 spring.codec.max-in-memory-size 不生效
|
||||
ServerRequest serverRequest = ServerRequest.create(exchange, codecConfigurer.getReaders());
|
||||
Mono<String> modifiedBody = serverRequest.bodyToMono(String.class).flatMap(body -> {
|
||||
gatewayLog.setRequestBody(body);
|
||||
return Mono.just(body);
|
||||
|
||||
@@ -66,7 +66,7 @@ public class ProjectReactor {
|
||||
// 写入文件
|
||||
files.forEach(file -> {
|
||||
// 如果是白名单的文件类型,不进行重写,直接拷贝
|
||||
String fileType = FileTypeUtil.getType(file);
|
||||
String fileType = getFileType(file);
|
||||
if (WHITE_FILE_TYPES.contains(fileType)) {
|
||||
copyFile(file, projectBaseDir, projectBaseDirNew, packageNameNew, artifactIdNew);
|
||||
return;
|
||||
@@ -106,7 +106,7 @@ public class ProjectReactor {
|
||||
String titleNew) {
|
||||
String content = FileUtil.readString(file, StandardCharsets.UTF_8);
|
||||
// 如果是白名单的文件类型,不进行重写
|
||||
String fileType = FileTypeUtil.getType(file);
|
||||
String fileType = getFileType(file);
|
||||
if (WHITE_FILE_TYPES.contains(fileType)) {
|
||||
return content;
|
||||
}
|
||||
@@ -139,4 +139,7 @@ public class ProjectReactor {
|
||||
.replaceAll(StrUtil.upperFirst(ARTIFACT_ID), StrUtil.upperFirst(artifactIdNew));
|
||||
}
|
||||
|
||||
private static String getFileType(File file) {
|
||||
return file.length() > 0 ? FileTypeUtil.getType(file) : "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,16 +3,16 @@ package cn.iocoder.yudao.module.bpm.enums;
|
||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
|
||||
/**
|
||||
* 工作流 错误码枚举类
|
||||
* Bpm 错误码枚举类
|
||||
*
|
||||
* 工作流系统,使用 1-009-000-000 段
|
||||
* bpm 系统,使用 1-009-000-000 段
|
||||
*/
|
||||
public interface ErrorCodeConstants {
|
||||
|
||||
// ========== 通用流程处理 模块 1-009-000-000 ==========
|
||||
// ========== 通用流程处理 模块 1009000000 ==========
|
||||
ErrorCode HIGHLIGHT_IMG_ERROR = new ErrorCode(1009000002, "获取高亮流程图异常");
|
||||
|
||||
// ========== OA 流程模块 1-009-001-000 ==========
|
||||
// ========== OA 流程模块 1009001000 ==========
|
||||
ErrorCode OA_LEAVE_NOT_EXISTS = new ErrorCode(1009001001, "请假申请不存在");
|
||||
ErrorCode OA_PM_POST_NOT_EXISTS = new ErrorCode(1009001002, "项目经理岗位未设置");
|
||||
ErrorCode OA_DEPART_PM_POST_NOT_EXISTS = new ErrorCode(1009001009, "部门的项目经理不存在");
|
||||
@@ -21,7 +21,7 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode OA_HR_POST_NOT_EXISTS = new ErrorCode(1009001006, "HR岗位未设置");
|
||||
ErrorCode OA_DAY_LEAVE_ERROR = new ErrorCode(1009001007, "请假天数必须>=1");
|
||||
|
||||
// ========== 流程模型 1-009-002-000 ==========
|
||||
// ========== 流程模型 1009002000 ==========
|
||||
ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1009002000, "已经存在流程标识为【{}】的流程");
|
||||
ErrorCode MODEL_NOT_EXISTS = new ErrorCode(1009002001, "流程模型不存在");
|
||||
ErrorCode MODEL_KEY_VALID = new ErrorCode(1009002002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!");
|
||||
@@ -30,34 +30,34 @@ public interface ErrorCodeConstants {
|
||||
"原因:用户任务({})未配置分配规则,请点击【修改流程】按钮进行配置");
|
||||
ErrorCode MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS = new ErrorCode(1009003005, "流程定义部署失败,原因:信息未发生变化");
|
||||
|
||||
// ========== 流程定义 1-009-003-000 ==========
|
||||
// ========== 流程定义 1009003000 ==========
|
||||
ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");
|
||||
ErrorCode PROCESS_DEFINITION_NAME_NOT_MATCH = new ErrorCode(1009003001, "流程定义的名字期望是({}),当前是({}),请修改 BPMN 流程图");
|
||||
ErrorCode PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1009003002, "流程定义不存在");
|
||||
ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003003, "流程定义处于挂起状态");
|
||||
ErrorCode PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS = new ErrorCode(1009003004, "流程定义的模型不存在");
|
||||
|
||||
// ========== 流程实例 1-009-004-000 ==========
|
||||
// ========== 流程实例 1009004000 ==========
|
||||
ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1009004000, "流程实例不存在");
|
||||
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1009004001, "流程取消失败,流程不处于运行中");
|
||||
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF = new ErrorCode(1009004002, "流程取消失败,该流程不是你发起的");
|
||||
|
||||
// ========== 流程任务 1-009-005-000 ==========
|
||||
// ========== 流程任务 1009005000 ==========
|
||||
ErrorCode TASK_COMPLETE_FAIL_NOT_EXISTS = new ErrorCode(1009005000, "审批任务失败,原因:该任务不处于未审批");
|
||||
ErrorCode TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1009005001, "审批任务失败,原因:该任务的审批人不是你");
|
||||
|
||||
// ========== 流程任务分配规则 1-009-006-000 ==========
|
||||
// ========== 流程任务分配规则 1009006000 ==========
|
||||
ErrorCode TASK_ASSIGN_RULE_EXISTS = new ErrorCode(1009006000, "流程({}) 的任务({}) 已经存在分配规则");
|
||||
ErrorCode TASK_ASSIGN_RULE_NOT_EXISTS = new ErrorCode(1009006001, "流程任务分配规则不存在");
|
||||
ErrorCode TASK_UPDATE_FAIL_NOT_MODEL = new ErrorCode(1009006002, "只有流程模型的任务分配规则,才允许被修改");
|
||||
ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1009006003, "操作失败,原因:找不到任务的审批人!");
|
||||
ErrorCode TASK_ASSIGN_SCRIPT_NOT_EXISTS = new ErrorCode(1009006004, "操作失败,原因:任务分配脚本({}) 不存在");
|
||||
|
||||
// ========== 动态表单模块 1-009-010-000 ==========
|
||||
// ========== 动态表单模块 1009010000 ==========
|
||||
ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在");
|
||||
ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1009010001, "表单项({}) 和 ({}) 使用了相同的字段名({})");
|
||||
|
||||
// ========== 用户组模块 1-009-011-000 ==========
|
||||
// ========== 用户组模块 1009011000 ==========
|
||||
ErrorCode USER_GROUP_NOT_EXISTS = new ErrorCode(1009011000, "用户组不存在");
|
||||
ErrorCode USER_GROUP_IS_DISABLE = new ErrorCode(1009011001, "名字为【{}】的用户组已被禁用");
|
||||
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.security.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
|
||||
import cn.iocoder.yudao.module.system.enums.ApiConstants;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
||||
|
||||
/**
|
||||
* System 模块的 Security 配置
|
||||
* Bpm 模块的 Security 配置
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false, value = "systemSecurityConfiguration")
|
||||
@Configuration(proxyBeanMethods = false, value = "bpmSecurityConfiguration")
|
||||
public class SecurityConfiguration {
|
||||
|
||||
@Bean("systemAuthorizeRequestsCustomizer")
|
||||
@Bean("bpmAuthorizeRequestsCustomizer")
|
||||
public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
|
||||
return new AuthorizeRequestsCustomizer() {
|
||||
|
||||
@@ -28,8 +27,6 @@ public class SecurityConfiguration {
|
||||
// Spring Boot Actuator 的安全配置
|
||||
registry.antMatchers("/actuator").anonymous()
|
||||
.antMatchers("/actuator/**").anonymous();
|
||||
// RPC 服务的安全配置
|
||||
registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
## 提供给 baseVO、createVO、updateVO 生成字段
|
||||
@Schema(description = "${column.columnComment}"#if (!${column.nullable}), required = true#end#if ("$!column.example" != ""), example = "${column.example}"#end)
|
||||
@Schema(description = "${column.columnComment}"#if (!${column.nullable}), requiredMode = Schema.RequiredMode.REQUIRED#end#if ("$!column.example" != ""), example = "${column.example}"#end)
|
||||
#if (!${column.nullable})## 判断 @NotEmpty 和 @NotNull 注解
|
||||
#if (${field.fieldType} == 'String')
|
||||
@NotEmpty(message = "${column.columnComment}不能为空")
|
||||
|
||||
@@ -24,9 +24,9 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
#end
|
||||
|
||||
/**
|
||||
* ${table.classComment} Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
* ${table.classComment} Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class ${sceneEnum.prefixClass}${table.className}BaseVO {
|
||||
|
||||
|
||||
@@ -61,10 +61,10 @@ import static org.mockito.Mockito.*;
|
||||
#end
|
||||
#end
|
||||
/**
|
||||
* {@link ${table.className}ServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author ${table.author}
|
||||
*/
|
||||
* {@link ${table.className}ServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author ${table.author}
|
||||
*/
|
||||
@Import(${table.className}ServiceImpl.class)
|
||||
public class ${table.className}ServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import request from '@/config/axios'
|
||||
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||
|
||||
export interface ${simpleClassName}VO {
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
|
||||
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
|
||||
${column.javaField}: number
|
||||
#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdatetime")
|
||||
${column.javaField}: Date
|
||||
@@ -16,30 +17,30 @@ export interface ${simpleClassName}VO {
|
||||
|
||||
// 查询${table.classComment}列表
|
||||
export const get${simpleClassName}Page = async (params: ${simpleClassName}PageReqVO) => {
|
||||
return await request.get({ url: '${baseURL}/page', params })
|
||||
return await request.get({ url: `${baseURL}/page`, params })
|
||||
}
|
||||
|
||||
// 查询${table.classComment}详情
|
||||
export const get${simpleClassName} = async (id: number) => {
|
||||
return await request.get({ url: '${baseURL}/get?id=' + id })
|
||||
return await request.get({ url: `${baseURL}/get?id=` + id })
|
||||
}
|
||||
|
||||
// 新增${table.classComment}
|
||||
export const create${simpleClassName} = async (data: ${simpleClassName}VO) => {
|
||||
return await request.post({ url: '${baseURL}/create', data })
|
||||
return await request.post({ url: `${baseURL}/create`, data })
|
||||
}
|
||||
|
||||
// 修改${table.classComment}
|
||||
export const update${simpleClassName} = async (data: ${simpleClassName}VO) => {
|
||||
return await request.put({ url: '${baseURL}/update', data })
|
||||
return await request.put({ url: `${baseURL}/update`, data })
|
||||
}
|
||||
|
||||
// 删除${table.classComment}
|
||||
export const delete${simpleClassName} = async (id: number) => {
|
||||
return await request.delete({ url: '${baseURL}/delete?id=' + id })
|
||||
return await request.delete({ url: `${baseURL}/delete?id=` + id })
|
||||
}
|
||||
|
||||
// 导出${table.classComment} Excel
|
||||
export const export${simpleClassName}Api = async (params) => {
|
||||
return await request.download({ url: '${baseURL}/export-excel', params })
|
||||
export const export${simpleClassName} = async (params) => {
|
||||
return await request.download({ url: `${baseURL}/export-excel`, params })
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
<el-date-picker
|
||||
v-model="formData.${javaField}"
|
||||
type="date"
|
||||
value-format="timestamp"
|
||||
value-format="x"
|
||||
placeholder="选择${comment}"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker
|
||||
v-model="queryParams.${javaField}"
|
||||
value-format="yyyy-MM-dd"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="date"
|
||||
placeholder="选择${comment}"
|
||||
clearable
|
||||
@@ -77,7 +77,7 @@
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker
|
||||
v-model="queryParams.${javaField}"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import request from '@/config/axios'
|
||||
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||
|
||||
export interface ${simpleClassName}VO {
|
||||
#foreach ($column in $columns)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { defHttp } from '@/utils/http/axios'
|
||||
|
||||
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||
|
||||
// 查询${table.classComment}列表
|
||||
export function get${simpleClassName}Page(params) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
/**
|
||||
* Report 错误码枚举类
|
||||
*
|
||||
* system 系统,使用 1-003-000-000 段
|
||||
* report 系统,使用 1-003-000-000 段
|
||||
*/
|
||||
public interface ErrorCodeConstants {
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ public interface ErrorCodeConstants {
|
||||
|
||||
// ========== 邮件发送 1002025000 ==========
|
||||
ErrorCode MAIL_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1002025000, "模板参数({})缺失");
|
||||
ErrorCode MAIL_SEND_MAIL_NOT_EXISTS = new ErrorCode(1002025000, "邮箱不存在");
|
||||
ErrorCode MAIL_SEND_MAIL_NOT_EXISTS = new ErrorCode(1002025001, "邮箱不存在");
|
||||
|
||||
// ========== 站内信模版 1002026000 ==========
|
||||
ErrorCode NOTIFY_TEMPLATE_NOT_EXISTS = new ErrorCode(1002026000, "站内信模版不存在");
|
||||
@@ -161,6 +161,6 @@ public interface ErrorCodeConstants {
|
||||
// ========== 站内信模版 1002027000 ==========
|
||||
|
||||
// ========== 站内信发送 1002028000 ==========
|
||||
ErrorCode NOTIFY_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1002025000, "模板参数({})缺失");
|
||||
ErrorCode NOTIFY_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1002028000, "模板参数({})缺失");
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -108,7 +109,7 @@ public class MailLogDO extends BaseDO implements Serializable {
|
||||
/**
|
||||
* 发送时间
|
||||
*/
|
||||
private Date sendTime;
|
||||
private LocalDateTime sendTime;
|
||||
/**
|
||||
* 发送返回的消息 ID
|
||||
*/
|
||||
|
||||
@@ -52,7 +52,7 @@ public class MailProducer extends AbstractBusProducer {
|
||||
MailSendMessage message = new MailSendMessage()
|
||||
.setLogId(sendLogId).setMail(mail).setAccountId(accountId)
|
||||
.setNickname(nickname).setTitle(title).setContent(content);
|
||||
streamBridge.send("smsMail-out-0", message);
|
||||
streamBridge.send("mailSend-out-0", message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -65,12 +66,12 @@ public class MailLogServiceImpl implements MailLogService {
|
||||
public void updateMailSendResult(Long logId, String messageId, Exception exception) {
|
||||
// 1. 成功
|
||||
if (exception == null) {
|
||||
mailLogMapper.updateById(new MailLogDO().setId(logId).setSendTime(new Date())
|
||||
mailLogMapper.updateById(new MailLogDO().setId(logId).setSendTime(LocalDateTime.now())
|
||||
.setSendStatus(MailSendStatusEnum.SUCCESS.getStatus()).setSendMessageId(messageId));
|
||||
return;
|
||||
}
|
||||
// 2. 失败
|
||||
mailLogMapper.updateById(new MailLogDO().setId(logId).setSendTime(new Date())
|
||||
mailLogMapper.updateById(new MailLogDO().setId(logId).setSendTime(LocalDateTime.now())
|
||||
.setSendStatus(MailSendStatusEnum.FAILURE.getStatus()).setSendException(getRootCauseMessage(exception)));
|
||||
|
||||
}
|
||||
|
||||
@@ -89,13 +89,14 @@ public class MailSendServiceImpl implements MailSendService {
|
||||
|
||||
// 创建发送日志。如果模板被禁用,则不发送短信,只记录日志
|
||||
Boolean isSend = CommonStatusEnum.ENABLE.getStatus().equals(template.getStatus());
|
||||
String title = mailTemplateService.formatMailTemplateContent(template.getTitle(), templateParams);
|
||||
String content = mailTemplateService.formatMailTemplateContent(template.getContent(), templateParams);
|
||||
Long sendLogId = mailLogService.createMailLog(userId, userType, mail,
|
||||
account, template, content, templateParams, isSend);
|
||||
// 发送 MQ 消息,异步执行发送短信
|
||||
if (isSend) {
|
||||
mailProducer.sendMailSendMessage(sendLogId, mail, account.getId(),
|
||||
template.getNickname(), template.getTitle(), content);
|
||||
template.getNickname(), title, content);
|
||||
}
|
||||
return sendLogId;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user