mirror of
https://gitee.com/orangeform/orange-admin.git
synced 2026-01-17 02:26:28 +08:00
commit:同步2.3版本
This commit is contained in:
@@ -28,10 +28,14 @@ public class FilterConfig {
|
||||
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
|
||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
if (StringUtils.isNotBlank(applicationConfig.getCredentialIpList())) {
|
||||
String[] credentialIpList = StringUtils.split(applicationConfig.getCredentialIpList(), ",");
|
||||
if (credentialIpList.length > 0) {
|
||||
for (String ip : credentialIpList) {
|
||||
corsConfiguration.addAllowedOrigin(ip);
|
||||
if ("*".equals(applicationConfig.getCredentialIpList())) {
|
||||
corsConfiguration.addAllowedOriginPattern("*");
|
||||
} else {
|
||||
String[] credentialIpList = StringUtils.split(applicationConfig.getCredentialIpList(), ",");
|
||||
if (credentialIpList.length > 0) {
|
||||
for (String ip : credentialIpList) {
|
||||
corsConfiguration.addAllowedOrigin(ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
corsConfiguration.addAllowedHeader("*");
|
||||
|
||||
@@ -26,7 +26,7 @@ public interface SysDeptRelationMapper extends BaseDaoMapper<SysDeptRelation> {
|
||||
/**
|
||||
* 批量插入部门关联数据。
|
||||
* 由于目前版本(3.4.1)的Mybatis Plus没有提供真正的批量插入,为了保证效率需要自己实现。
|
||||
* 目前我们仅仅给出MySQL的insert list实现作为参考,其他数据库需要自行修改。
|
||||
* 目前我们仅仅给出MySQL和PostgresSQL的insert list实现作为参考,其他数据库需要自行修改。
|
||||
*
|
||||
* @param deptRelationList 部门关联关系数据列表。
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<id column="post_id" jdbcType="BIGINT" property="postId"/>
|
||||
<result column="post_name" jdbcType="VARCHAR" property="postName"/>
|
||||
<result column="level" jdbcType="INTEGER" property="level"/>
|
||||
<result column="leader_post" jdbcType="BIT" property="leaderPost"/>
|
||||
<result column="leader_post" jdbcType="BOOLEAN" property="leaderPost"/>
|
||||
<result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||
<result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
spring:
|
||||
# aj-captcha 对redis缓存的依赖。
|
||||
redis:
|
||||
database: 2
|
||||
host: localhost
|
||||
port: 6379
|
||||
password: ''
|
||||
timeout: 60000
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
druid:
|
||||
# 数据库链接 [主数据源]
|
||||
main:
|
||||
url: jdbc:mysql://localhost:3306/zzdemo-online?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: 123456
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
name: application-webadmin
|
||||
initialSize: 10
|
||||
minIdle: 10
|
||||
maxActive: 50
|
||||
maxWait: 60000
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
poolPreparedStatements: true
|
||||
maxPoolPreparedStatementPerConnectionSize: 20
|
||||
maxOpenPreparedStatements: 20
|
||||
validationQuery: SELECT 'x'
|
||||
testWhileIdle: true
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
|
||||
filters: stat,wall
|
||||
useGlobalDataSourceStat: true
|
||||
web-stat-filter:
|
||||
enabled: true
|
||||
url-pattern: /*
|
||||
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*,/actuator/*"
|
||||
stat-view-servlet:
|
||||
enabled: true
|
||||
urlPattern: /druid/*
|
||||
resetEnable: true
|
||||
|
||||
application:
|
||||
# Jwt令牌加密的签名值。该值的长度要超过10个字符(过短会报错)。
|
||||
tokenSigningKey: DemoFlow-signing-key
|
||||
# Jwt令牌在Http Header中的键名称。
|
||||
tokenHeaderKey: Authorization
|
||||
# Jwt令牌刷新后在Http Header中的键名称。
|
||||
refreshedTokenHeaderKey: RefreshedToken
|
||||
# Jwt令牌过期时间(毫秒)。
|
||||
expiration: 72000000
|
||||
# 初始化密码。
|
||||
defaultUserPassword: 123456
|
||||
# 缺省的文件上传根目录。
|
||||
uploadFileBaseDir: ./zz-resource/upload-files/app
|
||||
# 跨域的IP(http://192.168.10.10:8086)白名单列表,多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。
|
||||
credentialIpList: "*"
|
||||
# Session的用户和数据权限在Redis中的过期时间(秒)。
|
||||
sessionExpiredSeconds: 86400
|
||||
|
||||
sequence:
|
||||
# Snowflake 分布式Id生成算法所需的WorkNode参数值。
|
||||
snowflakeWorkNode: 1
|
||||
|
||||
# 存储session数据的Redis,所有服务均需要,因此放到公共配置中。
|
||||
# 根据实际情况,该Redis也可以用于存储其他数据。
|
||||
redis:
|
||||
# redisson的配置。每个服务可以自己的配置文件中覆盖此选项。
|
||||
redisson:
|
||||
# 如果该值为false,系统将不会创建RedissionClient的bean。
|
||||
enabled: true
|
||||
# mode的可用值为,single/cluster/sentinel/master-slave
|
||||
mode: single
|
||||
# single: 单机模式
|
||||
# address: redis://localhost:6379
|
||||
# cluster: 集群模式
|
||||
# 每个节点逗号分隔,同时每个节点前必须以redis://开头。
|
||||
# address: redis://localhost:6379,redis://localhost:6378,...
|
||||
# sentinel:
|
||||
# 每个节点逗号分隔,同时每个节点前必须以redis://开头。
|
||||
# address: redis://localhost:6379,redis://localhost:6378,...
|
||||
# master-slave:
|
||||
# 每个节点逗号分隔,第一个为主节点,其余为从节点。同时每个节点前必须以redis://开头。
|
||||
# address: redis://localhost:6379,redis://localhost:6378,...
|
||||
address: redis://localhost:6379
|
||||
# 链接超时,单位毫秒。
|
||||
timeout: 6000
|
||||
# 单位毫秒。分布式锁的超时检测时长。
|
||||
# 如果一次锁内操作超该毫秒数,或在释放锁之前异常退出,Redis会在该时长之后主动删除该锁使用的key。
|
||||
lockWatchdogTimeout: 60000
|
||||
# redis 密码,空可以不填。
|
||||
password:
|
||||
pool:
|
||||
# 连接池数量。
|
||||
poolSize: 20
|
||||
# 连接池中最小空闲数量。
|
||||
minIdle: 5
|
||||
@@ -59,43 +59,13 @@ pagehelper:
|
||||
supportMethodsArguments: false
|
||||
params: count=countSql
|
||||
|
||||
# 存储session数据的Redis,所有服务均需要,因此放到公共配置中。
|
||||
# 根据实际情况,该Redis也可以用于存储其他数据。
|
||||
redis:
|
||||
# redisson的配置。每个服务可以自己的配置文件中覆盖此选项。
|
||||
redisson:
|
||||
# 如果该值为false,系统将不会创建RedissionClient的bean。
|
||||
enabled: true
|
||||
# mode的可用值为,single/cluster/sentinel/master-slave
|
||||
mode: single
|
||||
# single: 单机模式
|
||||
# address: redis://localhost:6379
|
||||
# cluster: 集群模式
|
||||
# 每个节点逗号分隔,同时每个节点前必须以redis://开头。
|
||||
# address: redis://localhost:6379,redis://localhost:6378,...
|
||||
# sentinel:
|
||||
# 每个节点逗号分隔,同时每个节点前必须以redis://开头。
|
||||
# address: redis://localhost:6379,redis://localhost:6378,...
|
||||
# master-slave:
|
||||
# 每个节点逗号分隔,第一个为主节点,其余为从节点。同时每个节点前必须以redis://开头。
|
||||
# address: redis://localhost:6379,redis://localhost:6378,...
|
||||
address: redis://localhost:6379
|
||||
# 链接超时,单位毫秒。
|
||||
timeout: 6000
|
||||
# 单位毫秒。分布式锁的超时检测时长。
|
||||
# 如果一次锁内操作超该毫秒数,或在释放锁之前异常退出,Redis会在该时长之后主动删除该锁使用的key。
|
||||
lockWatchdogTimeout: 60000
|
||||
# redis 密码,空可以不填。
|
||||
password:
|
||||
pool:
|
||||
# 连接池数量。
|
||||
poolSize: 20
|
||||
# 连接池中最小空闲数量。
|
||||
minIdle: 5
|
||||
common-core:
|
||||
# 可选值为 mysql / postgresql
|
||||
databaseType: mysql
|
||||
|
||||
common-online:
|
||||
# 可选值为 mysql / postgresql
|
||||
datasourceType: mysql
|
||||
databaseType: mysql
|
||||
# 注意不要以反斜杠(/)结尾。
|
||||
operationUrlPrefix: /admin/online
|
||||
# 在线表单业务数据上传资源路径
|
||||
@@ -108,21 +78,25 @@ common-online-api:
|
||||
urlPrefix: /admin/online
|
||||
# 下面的url列表,请保持反斜杠(/)结尾。
|
||||
viewUrlList:
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/viewByDatasourceId/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/viewByOneToManyRelationId/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/listByDatasourceId/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/listByOneToManyRelationId/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/downloadDatasource/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/downloadOneToManyRelation/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/viewByDatasourceId/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/viewByOneToManyRelationId/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/listByDatasourceId/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/listByOneToManyRelationId/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/exportByDatasourceId/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/exportByOneToManyRelationId/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/downloadDatasource/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/downloadOneToManyRelation/
|
||||
editUrlList:
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/addDatasource/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/addOneToManyRelation/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/updateDatasource/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/updateOneToManyRelation/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/deleteDatasource/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/deleteOneToManyRelation/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/uploadDatasource/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/uploadOneToManyRelation/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/addDatasource/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/addOneToManyRelation/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/updateDatasource/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/updateOneToManyRelation/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/deleteDatasource/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/deleteOneToManyRelation/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/deleteBatchDatasource/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/deleteBatchOneToManyRelation/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/uploadDatasource/
|
||||
- ${common-online.operationUrlPrefix}/onlineOperation/uploadOneToManyRelation/
|
||||
|
||||
common-flow:
|
||||
# 请慎重修改urlPrefix的缺省配置,注意不要以反斜杠(/)结尾。如必须修改其他路径,请同步修改数据库脚本。
|
||||
@@ -168,8 +142,7 @@ management:
|
||||
# keys-to-sanitize:
|
||||
keys-to-sanitize: password
|
||||
server:
|
||||
servlet:
|
||||
context-path: "/"
|
||||
base-path: "/"
|
||||
|
||||
aj:
|
||||
captcha:
|
||||
@@ -206,137 +179,3 @@ aj:
|
||||
aes-status: true
|
||||
# 滑动干扰项(0/1/2)
|
||||
interference-options: 2
|
||||
|
||||
# 开发数据库相关配置
|
||||
---
|
||||
spring:
|
||||
profiles: dev
|
||||
# aj-captcha 对redis缓存的依赖。
|
||||
redis:
|
||||
database: 2
|
||||
host: localhost
|
||||
port: 6379
|
||||
password: ''
|
||||
timeout: 60000
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
druid:
|
||||
main:
|
||||
url: jdbc:mysql://localhost:3306/zzdemo-online?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: 123456
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
name: application-webadmin
|
||||
initialSize: 10
|
||||
minIdle: 10
|
||||
maxActive: 50
|
||||
maxWait: 60000
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
poolPreparedStatements: true
|
||||
maxPoolPreparedStatementPerConnectionSize: 20
|
||||
maxOpenPreparedStatements: 20
|
||||
validationQuery: SELECT 'x'
|
||||
testWhileIdle: true
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
|
||||
filters: stat,wall
|
||||
useGlobalDataSourceStat: true
|
||||
web-stat-filter:
|
||||
enabled: true
|
||||
url-pattern: /*
|
||||
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*,/actuator/*"
|
||||
stat-view-servlet:
|
||||
enabled: true
|
||||
urlPattern: /druid/*
|
||||
resetEnable: true
|
||||
|
||||
application:
|
||||
# Jwt令牌加密的签名值。该值的长度要超过10个字符(过短会报错)。
|
||||
tokenSigningKey: DemoFlow-signing-key
|
||||
# Jwt令牌在Http Header中的键名称。
|
||||
tokenHeaderKey: Authorization
|
||||
# Jwt令牌刷新后在Http Header中的键名称。
|
||||
refreshedTokenHeaderKey: RefreshedToken
|
||||
# Jwt令牌过期时间(毫秒)。
|
||||
expiration: 72000000
|
||||
# 初始化密码。
|
||||
defaultUserPassword: 123456
|
||||
# 缺省的文件上传根目录。
|
||||
uploadFileBaseDir: ./zz-resource/upload-files/app
|
||||
# 跨域的IP(http://192.168.10.10:8086)白名单列表,多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。
|
||||
credentialIpList: "*"
|
||||
# Session的用户和数据权限在Redis中的过期时间(秒)。
|
||||
sessionExpiredSeconds: 86400
|
||||
|
||||
sequence:
|
||||
# Snowflake 分布式Id生成算法所需的WorkNode参数值。
|
||||
snowflakeWorkNode: 1
|
||||
|
||||
# 发布数据库相关配置
|
||||
---
|
||||
spring:
|
||||
profiles: product
|
||||
# aj-captcha 对redis缓存的依赖。
|
||||
redis:
|
||||
database: 2
|
||||
host: localhost
|
||||
port: 6379
|
||||
password: ''
|
||||
timeout: 60000
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
druid:
|
||||
main:
|
||||
url: jdbc:mysql://localhost:3306/zzdemo-online?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: 123456
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
name: application-webadmin
|
||||
initialSize: 10
|
||||
minIdle: 10
|
||||
maxActive: 50
|
||||
maxWait: 60000
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
poolPreparedStatements: true
|
||||
maxPoolPreparedStatementPerConnectionSize: 20
|
||||
maxOpenPreparedStatements: 20
|
||||
validationQuery: SELECT 'x'
|
||||
testWhileIdle: true
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
|
||||
filters: stat,wall
|
||||
useGlobalDataSourceStat: true
|
||||
web-stat-filter:
|
||||
enabled: true
|
||||
url-pattern: /*
|
||||
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*,/actuator/*"
|
||||
stat-view-servlet:
|
||||
enabled: true
|
||||
urlPattern: /druid/*
|
||||
resetEnable: true
|
||||
|
||||
application:
|
||||
# Jwt令牌加密的签名值。该值的长度要超过10个字符(过短会报错)。
|
||||
tokenSigningKey: DemoFlow-signing-key
|
||||
# Jwt令牌在Http Header中的键名称。
|
||||
tokenHeaderKey: Authorization
|
||||
# Jwt令牌刷新后在Http Header中的键名称。
|
||||
refreshedTokenHeaderKey: RefreshedToken
|
||||
# Jwt令牌过期时间(毫秒)。
|
||||
expiration: 72000000
|
||||
# 初始化密码。
|
||||
defaultUserPassword: 123456
|
||||
# 缺省的文件上传根目录。
|
||||
uploadFileBaseDir: ./zz-resource/upload-files/app
|
||||
# 跨域的IP(http://192.168.10.10:8086)白名单列表,多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。
|
||||
credentialIpList: "*"
|
||||
# Session的用户和数据权限在Redis中的过期时间(秒)。
|
||||
sessionExpiredSeconds: 86400
|
||||
|
||||
sequence:
|
||||
# Snowflake 分布式Id生成算法所需的WorkNode参数值。
|
||||
snowflakeWorkNode: 1
|
||||
@@ -156,8 +156,8 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
*/
|
||||
private final TableModelInfo tableModelInfo = new TableModelInfo();
|
||||
|
||||
private static final String GROUPED_KEY = "groupedKey";
|
||||
private static final String AGGREGATED_VALUE = "aggregatedValue";
|
||||
private static final String GROUPED_KEY = "grouped_key";
|
||||
private static final String AGGREGATED_VALUE = "aggregated_value";
|
||||
private static final String AND_OP = " AND ";
|
||||
|
||||
@Override
|
||||
|
||||
@@ -43,6 +43,12 @@ public class MyDateUtil {
|
||||
private static final DateTimeFormatter DATETIME_PARSE_FORMATTER =
|
||||
DateTimeFormat.forPattern(MyDateUtil.COMMON_DATETIME_FORMAT);
|
||||
|
||||
/**
|
||||
* 缺省短日期时间格式化器,提前获取提升运行时效率。
|
||||
*/
|
||||
private static final DateTimeFormatter DATETIME_SHORT_PARSE_FORMATTER =
|
||||
DateTimeFormat.forPattern(MyDateUtil.COMMON_SHORT_DATETIME_FORMAT);
|
||||
|
||||
/**
|
||||
* 获取一天的开始时间的字符串格式,如2019-08-03 00:00:00.000。
|
||||
*
|
||||
@@ -144,6 +150,16 @@ public class MyDateUtil {
|
||||
return DATETIME_PARSE_FORMATTER.parseDateTime(dateTimeString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将缺省格式的(不包含毫秒的)日期时间字符串解析为日期对象。
|
||||
*
|
||||
* @param dateTimeString 待解析的字符串。
|
||||
* @return 解析后的日期对象。
|
||||
*/
|
||||
public static DateTime toDateTimeWithoutMs(String dateTimeString) {
|
||||
return DATETIME_SHORT_PARSE_FORMATTER.parseDateTime(dateTimeString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 截取时间到天。如2019-10-03 01:20:30 转换为 2019-10-03 00:00:00。
|
||||
* 由于没有字符串的中间转换,因此效率更高。
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
<result column="deploy_id" jdbcType="VARCHAR" property="deployId"/>
|
||||
<result column="process_definition_id" jdbcType="VARCHAR" property="processDefinitionId"/>
|
||||
<result column="publish_version" jdbcType="INTEGER" property="publishVersion"/>
|
||||
<result column="active_status" jdbcType="BIT" property="activeStatus"/>
|
||||
<result column="main_version" jdbcType="BIT" property="mainVersion"/>
|
||||
<result column="active_status" jdbcType="BOOLEAN" property="activeStatus"/>
|
||||
<result column="main_version" jdbcType="BOOLEAN" property="mainVersion"/>
|
||||
<result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
|
||||
<result column="publish_time" jdbcType="TIMESTAMP" property="publishTime"/>
|
||||
<result column="init_task_info" jdbcType="VARCHAR" property="initTaskInfo"/>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<result column="bind_datasource_id" jdbcType="BIGINT" property="bindDatasourceId"/>
|
||||
<result column="bind_relation_id" jdbcType="BIGINT" property="bindRelationId"/>
|
||||
<result column="bind_column_id" jdbcType="BIGINT" property="bindColumnId"/>
|
||||
<result column="builtin" jdbcType="BIT" property="builtin"/>
|
||||
<result column="builtin" jdbcType="BOOLEAN" property="builtin"/>
|
||||
</resultMap>
|
||||
|
||||
<insert id="insertList">
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<result column="bind_datasource_id" jdbcType="BIGINT" property="bindDatasourceId"/>
|
||||
<result column="bind_relation_id" jdbcType="BIGINT" property="bindRelationId"/>
|
||||
<result column="bind_column_id" jdbcType="BIGINT" property="bindColumnId"/>
|
||||
<result column="builtin" jdbcType="BIT" property="builtin"/>
|
||||
<result column="builtin" jdbcType="BOOLEAN" property="builtin"/>
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<result column="task_name" jdbcType="VARCHAR" property="taskName"/>
|
||||
<result column="task_start_time" jdbcType="TIMESTAMP" property="taskStartTime"/>
|
||||
<result column="task_assignee" jdbcType="VARCHAR" property="taskAssignee"/>
|
||||
<result column="task_finished" jdbcType="BIT" property="taskFinished"/>
|
||||
<result column="task_finished" jdbcType="BOOLEAN" property="taskFinished"/>
|
||||
<result column="business_data_shot" jdbcType="LONGVARCHAR" property="businessDataShot"/>
|
||||
<result column="online_form_data" jdbcType="BIT" property="onlineFormData"/>
|
||||
<result column="online_form_data" jdbcType="BOOLEAN" property="onlineFormData"/>
|
||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
|
||||
<result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||
@@ -30,7 +30,7 @@
|
||||
<select id="getRemindingMessageListByUser" resultMap="BaseResultMap">
|
||||
SELECT a.* FROM zz_flow_message a
|
||||
<where>
|
||||
a.task_finished = 0
|
||||
a.task_finished = false
|
||||
AND a.message_type = 0
|
||||
AND (a.task_assignee = #{loginName} OR EXISTS (SELECT * FROM zz_flow_message_candicate_identity b
|
||||
WHERE a.message_id = b.message_id AND b.candidate_id in
|
||||
@@ -65,7 +65,7 @@
|
||||
<select id="countRemindingMessageListByUser" resultType="java.lang.Integer">
|
||||
SELECT COUNT(1) FROM zz_flow_message a
|
||||
<where>
|
||||
a.task_finished = 0
|
||||
a.task_finished = false
|
||||
AND a.message_type = 0
|
||||
AND (a.task_assignee = #{loginName} OR EXISTS (SELECT * FROM zz_flow_message_candicate_identity b
|
||||
WHERE a.message_id = b.message_id AND b.candidate_id in
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<result column="request_arguments" jdbcType="VARCHAR" property="requestArguments"/>
|
||||
<result column="response_result" jdbcType="VARCHAR" property="responseResult"/>
|
||||
<result column="request_ip" jdbcType="VARCHAR" property="requestIp"/>
|
||||
<result column="success" jdbcType="BIT" property="success"/>
|
||||
<result column="success" jdbcType="BOOLEAN" property="success"/>
|
||||
<result column="error_msg" jdbcType="VARCHAR" property="errorMsg"/>
|
||||
<result column="tenant_id" jdbcType="BIGINT" property="tenantId"/>
|
||||
<result column="operator_id" jdbcType="BIGINT" property="operatorId"/>
|
||||
|
||||
@@ -154,22 +154,19 @@ public class OnlineColumnController {
|
||||
* 列出符合过滤条件的字段数据列表。
|
||||
*
|
||||
* @param onlineColumnDtoFilter 过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象,包含查询结果集。
|
||||
*/
|
||||
@PostMapping("/list")
|
||||
public ResponseResult<MyPageData<OnlineColumnVo>> list(
|
||||
@MyRequestBody OnlineColumnDto onlineColumnDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
|
||||
}
|
||||
OnlineColumn onlineColumnFilter = MyModelUtil.copyTo(onlineColumnDtoFilter, OnlineColumn.class);
|
||||
String orderBy = MyOrderParam.buildOrderBy(orderParam, OnlineColumn.class);
|
||||
List<OnlineColumn> onlineColumnList =
|
||||
onlineColumnService.getOnlineColumnListWithRelation(onlineColumnFilter, orderBy);
|
||||
onlineColumnService.getOnlineColumnListWithRelation(onlineColumnFilter);
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(onlineColumnList, OnlineColumn.INSTANCE));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.orangeforms.common.online.controller;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@@ -8,9 +9,7 @@ import com.alibaba.fastjson.JSONObject;
|
||||
import com.orangeforms.common.core.annotation.MyRequestBody;
|
||||
import com.orangeforms.common.core.constant.ErrorCodeEnum;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import com.orangeforms.common.core.util.ContextUtil;
|
||||
import com.orangeforms.common.core.util.MyCommonUtil;
|
||||
import com.orangeforms.common.core.util.MyPageUtil;
|
||||
import com.orangeforms.common.core.util.*;
|
||||
import com.orangeforms.common.online.util.OnlineOperationHelper;
|
||||
import com.orangeforms.common.online.dto.OnlineFilterDto;
|
||||
import com.orangeforms.common.online.model.*;
|
||||
@@ -20,7 +19,9 @@ import com.orangeforms.common.online.object.ColumnData;
|
||||
import com.orangeforms.common.online.service.*;
|
||||
import com.orangeforms.common.online.util.OnlineConstant;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -56,6 +57,8 @@ public class OnlineOperationController {
|
||||
private OnlineTableService onlineTableService;
|
||||
@Autowired
|
||||
private OnlineOperationHelper onlineOperationHelper;
|
||||
@Autowired
|
||||
private OnlineVirtualColumnService onlineVirtualColumnService;
|
||||
|
||||
/**
|
||||
* 新增数据接口。
|
||||
@@ -237,28 +240,23 @@ public class OnlineOperationController {
|
||||
@PathVariable("datasourceVariableName") String datasourceVariableName,
|
||||
@MyRequestBody(required = true) Long datasourceId,
|
||||
@MyRequestBody(required = true) String dataId) {
|
||||
String errorMessage;
|
||||
ResponseResult<OnlineDatasource> datasourceResult =
|
||||
onlineOperationHelper.verifyAndGetDatasource(datasourceId);
|
||||
if (!datasourceResult.isSuccess()) {
|
||||
return ResponseResult.errorFrom(datasourceResult);
|
||||
}
|
||||
OnlineDatasource datasource = datasourceResult.getData();
|
||||
if (!datasource.getVariableName().equals(datasourceVariableName)) {
|
||||
ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
|
||||
}
|
||||
OnlineTable masterTable = datasource.getMasterTable();
|
||||
ResponseResult<List<OnlineDatasourceRelation>> relationListResult =
|
||||
onlineOperationHelper.verifyAndGetRelationList(datasourceId, RelationType.ONE_TO_MANY);
|
||||
if (!relationListResult.isSuccess()) {
|
||||
return ResponseResult.errorFrom(relationListResult);
|
||||
}
|
||||
List<OnlineDatasourceRelation> relationList = relationListResult.getData();
|
||||
if (!onlineOperationService.delete(masterTable, relationList, dataId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
return this.doDelete(datasourceVariableName, datasourceId, CollUtil.newArrayList(dataId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除主数据接口。
|
||||
*
|
||||
* @param datasourceVariableName 数据源名称。
|
||||
* @param datasourceId 主表数据源Id。
|
||||
* @param dataIdList 待删除的数据表主键Id列表。
|
||||
* @return 应该结果。
|
||||
*/
|
||||
@PostMapping("/deleteBatchDatasource/{datasourceVariableName}")
|
||||
public ResponseResult<Void> deleteBatchDatasource(
|
||||
@PathVariable("datasourceVariableName") String datasourceVariableName,
|
||||
@MyRequestBody(required = true) Long datasourceId,
|
||||
@MyRequestBody(required = true, elementType = String.class) List<String> dataIdList) {
|
||||
return this.doDelete(datasourceVariableName, datasourceId, dataIdList);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,26 +274,25 @@ public class OnlineOperationController {
|
||||
@MyRequestBody(required = true) Long datasourceId,
|
||||
@MyRequestBody(required = true) Long relationId,
|
||||
@MyRequestBody(required = true) String dataId) {
|
||||
String errorMessage;
|
||||
OnlineDatasource datasource = onlineDatasourceService.getById(datasourceId);
|
||||
if (datasource == null) {
|
||||
errorMessage = "数据验证失败,数据源Id并不存在!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
if (!datasource.getVariableName().equals(datasourceVariableName)) {
|
||||
ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
|
||||
}
|
||||
ResponseResult<OnlineDatasourceRelation> relationResult =
|
||||
onlineOperationHelper.verifyAndGetOneToManyRelation(datasourceId, relationId);
|
||||
if (!relationResult.isSuccess()) {
|
||||
return ResponseResult.errorFrom(relationResult);
|
||||
}
|
||||
OnlineDatasourceRelation relation = relationResult.getData();
|
||||
if (!onlineOperationService.delete(relation.getSlaveTable(), null, dataId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
return this.doDelete(datasourceVariableName, datasourceId, relationId, CollUtil.newArrayList(dataId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除一对多关联表单条数据接口。
|
||||
*
|
||||
* @param datasourceVariableName 数据源名称。
|
||||
* @param datasourceId 主表数据源Id。
|
||||
* @param relationId 一对多关联Id。
|
||||
* @param dataIdList 一对多关联表主键Id列表。
|
||||
* @return 应该结果。
|
||||
*/
|
||||
@PostMapping("/deleteBatchOneToManyRelation/{datasourceVariableName}")
|
||||
public ResponseResult<Void> deleteBatchOneToManyRelation(
|
||||
@PathVariable("datasourceVariableName") String datasourceVariableName,
|
||||
@MyRequestBody(required = true) Long datasourceId,
|
||||
@MyRequestBody(required = true) Long relationId,
|
||||
@MyRequestBody(required = true, elementType = String.class) List<String> dataIdList) {
|
||||
return this.doDelete(datasourceVariableName, datasourceId, relationId, dataIdList);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -593,6 +590,66 @@ public class OnlineOperationController {
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(resultList));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据数据源Id,以及接口参数,为动态表单导出数据列表。
|
||||
*
|
||||
* @param datasourceVariableName 数据源名称。
|
||||
* @param datasourceId 数据源Id。
|
||||
* @param filterDtoList 多虑数据对象列表。
|
||||
* @param orderParam 排序对象。
|
||||
* @param exportInfoList 导出字段信息列表。
|
||||
*/
|
||||
@PostMapping("/exportByDatasourceId/{datasourceVariableName}")
|
||||
public void exportByDatasourceId(
|
||||
@PathVariable("datasourceVariableName") String datasourceVariableName,
|
||||
@MyRequestBody(required = true) Long datasourceId,
|
||||
@MyRequestBody(elementType = OnlineFilterDto.class) List<OnlineFilterDto> filterDtoList,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody(elementType = ExportInfo.class, required = true) List<ExportInfo> exportInfoList) throws IOException {
|
||||
// 1. 验证数据源及其关联
|
||||
ResponseResult<OnlineDatasource> datasourceResult =
|
||||
onlineOperationHelper.verifyAndGetDatasource(datasourceId);
|
||||
if (!datasourceResult.isSuccess()) {
|
||||
ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, datasourceResult);
|
||||
}
|
||||
OnlineDatasource datasource = datasourceResult.getData();
|
||||
if (!datasource.getVariableName().equals(datasourceVariableName)) {
|
||||
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN);
|
||||
}
|
||||
OnlineTable masterTable = datasource.getMasterTable();
|
||||
ResponseResult<List<OnlineDatasourceRelation>> relationListResult =
|
||||
onlineOperationHelper.verifyAndGetRelationList(datasourceId, null);
|
||||
if (!relationListResult.isSuccess()) {
|
||||
ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, relationListResult);
|
||||
}
|
||||
List<OnlineDatasourceRelation> allRelationList = relationListResult.getData();
|
||||
// 2. 验证数据过滤对象中的表名和字段,确保没有sql注入。
|
||||
ResponseResult<Void> filterDtoListResult = this.verifyFilterDtoList(filterDtoList);
|
||||
if (!filterDtoListResult.isSuccess()) {
|
||||
ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, filterDtoListResult);
|
||||
}
|
||||
// 3. 解析排序参数,同时确保没有sql注入。
|
||||
Map<String, OnlineTable> tableMap = new HashMap<>(4);
|
||||
tableMap.put(masterTable.getTableName(), masterTable);
|
||||
List<OnlineDatasourceRelation> oneToOneRelationList = relationListResult.getData().stream()
|
||||
.filter(r -> r.getRelationType().equals(RelationType.ONE_TO_ONE)).collect(Collectors.toList());
|
||||
if (CollUtil.isNotEmpty(oneToOneRelationList)) {
|
||||
Map<String, OnlineTable> relationTableMap = oneToOneRelationList.stream()
|
||||
.map(OnlineDatasourceRelation::getSlaveTable).collect(Collectors.toMap(OnlineTable::getTableName, c -> c));
|
||||
tableMap.putAll(relationTableMap);
|
||||
}
|
||||
ResponseResult<String> orderByResult = this.makeOrderBy(orderParam, masterTable, tableMap);
|
||||
if (!orderByResult.isSuccess()) {
|
||||
ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, orderByResult);
|
||||
}
|
||||
String orderBy = orderByResult.getData();
|
||||
List<Map<String, Object>> resultList = onlineOperationService.getMasterDataList(
|
||||
masterTable, oneToOneRelationList, allRelationList, filterDtoList, orderBy);
|
||||
Map<String, String> headerMap = this.makeExportHeaderMap(masterTable, allRelationList, exportInfoList);
|
||||
String filename = datasourceVariableName + "-" + MyDateUtil.toDateTimeString(DateTime.now()) + ".xlsx";
|
||||
ExportUtil.doExport(resultList, headerMap, filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据数据源Id和数据源关联Id,以及接口参数,为动态表单查询该一对多关联的数据列表。
|
||||
*
|
||||
@@ -655,6 +712,68 @@ public class OnlineOperationController {
|
||||
onlineOperationService.getSlaveDataList(relation, filterDtoList, orderBy);
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(resultList));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据数据源Id和数据源关联Id,以及接口参数,为动态表单查询该一对多关联的数据列表。
|
||||
*
|
||||
* @param datasourceVariableName 数据源名称。
|
||||
* @param datasourceId 数据源Id。
|
||||
* @param relationId 数据源的一对多关联Id。
|
||||
* @param filterDtoList 多虑数据对象列表。
|
||||
* @param orderParam 排序对象。
|
||||
* @param exportInfoList 导出字段信息列表。
|
||||
*/
|
||||
@PostMapping("/exportByOneToManyRelationId/{datasourceVariableName}")
|
||||
public void exportByOneToManyRelationId(
|
||||
@PathVariable("datasourceVariableName") String datasourceVariableName,
|
||||
@MyRequestBody(required = true) Long datasourceId,
|
||||
@MyRequestBody(required = true) Long relationId,
|
||||
@MyRequestBody(elementType = OnlineFilterDto.class) List<OnlineFilterDto> filterDtoList,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody(elementType = ExportInfo.class, required = true) List<ExportInfo> exportInfoList) throws IOException {
|
||||
String errorMessage;
|
||||
OnlineDatasource datasource = onlineDatasourceService.getById(datasourceId);
|
||||
if (datasource == null) {
|
||||
errorMessage = "数据验证失败,数据源Id并不存在!";
|
||||
ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST,
|
||||
ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage));
|
||||
}
|
||||
if (!datasource.getVariableName().equals(datasourceVariableName)) {
|
||||
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN);
|
||||
}
|
||||
ResponseResult<OnlineDatasourceRelation> relationResult =
|
||||
onlineOperationHelper.verifyAndGetOneToManyRelation(datasourceId, relationId);
|
||||
if (!relationResult.isSuccess()) {
|
||||
ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, relationResult);
|
||||
}
|
||||
OnlineDatasourceRelation relation = relationResult.getData();
|
||||
OnlineTable slaveTable = relation.getSlaveTable();
|
||||
// 验证数据过滤对象中的表名和字段,确保没有sql注入。
|
||||
ResponseResult<Void> filterDtoListResult = this.verifyFilterDtoList(filterDtoList);
|
||||
if (!filterDtoListResult.isSuccess()) {
|
||||
ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, filterDtoListResult);
|
||||
}
|
||||
Map<String, OnlineTable> tableMap = new HashMap<>(1);
|
||||
tableMap.put(slaveTable.getTableName(), slaveTable);
|
||||
if (CollUtil.isNotEmpty(orderParam)) {
|
||||
for (MyOrderParam.OrderInfo orderInfo : orderParam) {
|
||||
orderInfo.setFieldName(StrUtil.removePrefix(orderInfo.getFieldName(),
|
||||
relation.getVariableName() + OnlineConstant.RELATION_TABLE_COLUMN_SEPARATOR));
|
||||
}
|
||||
}
|
||||
ResponseResult<String> orderByResult = this.makeOrderBy(orderParam, slaveTable, tableMap);
|
||||
if (!orderByResult.isSuccess()) {
|
||||
ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, orderByResult);
|
||||
}
|
||||
String orderBy = orderByResult.getData();
|
||||
List<Map<String, Object>> resultList =
|
||||
onlineOperationService.getSlaveDataList(relation, filterDtoList, orderBy);
|
||||
Map<String, String> headerMap = this.makeExportHeaderMap(
|
||||
null, CollUtil.newArrayList(relation), exportInfoList);
|
||||
String filename = datasourceVariableName + "-relation-"
|
||||
+ MyDateUtil.toDateTimeString(DateTime.now()) + ".xlsx";
|
||||
ExportUtil.doExport(resultList, headerMap, filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询字典数据,并以字典的约定方式,返回数据结果集。
|
||||
@@ -690,6 +809,60 @@ public class OnlineOperationController {
|
||||
return ResponseResult.success(resultList);
|
||||
}
|
||||
|
||||
private ResponseResult<Void> doDelete(
|
||||
String datasourceVariableName, Long datasourceId, List<String> dataIdList) {
|
||||
String errorMessage;
|
||||
ResponseResult<OnlineDatasource> datasourceResult =
|
||||
onlineOperationHelper.verifyAndGetDatasource(datasourceId);
|
||||
if (!datasourceResult.isSuccess()) {
|
||||
return ResponseResult.errorFrom(datasourceResult);
|
||||
}
|
||||
OnlineDatasource datasource = datasourceResult.getData();
|
||||
if (!datasource.getVariableName().equals(datasourceVariableName)) {
|
||||
ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
|
||||
}
|
||||
OnlineTable masterTable = datasource.getMasterTable();
|
||||
ResponseResult<List<OnlineDatasourceRelation>> relationListResult =
|
||||
onlineOperationHelper.verifyAndGetRelationList(datasourceId, RelationType.ONE_TO_MANY);
|
||||
if (!relationListResult.isSuccess()) {
|
||||
return ResponseResult.errorFrom(relationListResult);
|
||||
}
|
||||
List<OnlineDatasourceRelation> relationList = relationListResult.getData();
|
||||
for (String dataId : dataIdList) {
|
||||
if (!onlineOperationService.delete(masterTable, relationList, dataId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
private ResponseResult<Void> doDelete(
|
||||
String datasourceVariableName, Long datasourceId, Long relationId, List<String> dataIdList) {
|
||||
String errorMessage;
|
||||
OnlineDatasource datasource = onlineDatasourceService.getById(datasourceId);
|
||||
if (datasource == null) {
|
||||
errorMessage = "数据验证失败,数据源Id并不存在!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
if (!datasource.getVariableName().equals(datasourceVariableName)) {
|
||||
ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
|
||||
}
|
||||
ResponseResult<OnlineDatasourceRelation> relationResult =
|
||||
onlineOperationHelper.verifyAndGetOneToManyRelation(datasourceId, relationId);
|
||||
if (!relationResult.isSuccess()) {
|
||||
return ResponseResult.errorFrom(relationResult);
|
||||
}
|
||||
OnlineDatasourceRelation relation = relationResult.getData();
|
||||
for (String dataId : dataIdList) {
|
||||
if (!onlineOperationService.delete(relation.getSlaveTable(), null, dataId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
private ResponseResult<Void> verifyFilterDtoList(List<OnlineFilterDto> filterDtoList) {
|
||||
if (CollUtil.isEmpty(filterDtoList)) {
|
||||
return ResponseResult.success();
|
||||
@@ -785,4 +958,57 @@ public class OnlineOperationController {
|
||||
}
|
||||
return ResponseResult.success(sb.toString());
|
||||
}
|
||||
|
||||
private Map<String, String> makeExportHeaderMap(
|
||||
OnlineTable masterTable,
|
||||
List<OnlineDatasourceRelation> allRelationList,
|
||||
List<ExportInfo> exportInfoList) {
|
||||
Map<String, String> headerMap = new LinkedHashMap<>(16);
|
||||
Map<Long, OnlineDatasourceRelation> allRelationMap = null;
|
||||
if (CollUtil.isNotEmpty(allRelationList)) {
|
||||
allRelationMap = allRelationList.stream()
|
||||
.collect(Collectors.toMap(OnlineDatasourceRelation::getSlaveTableId, r -> r));
|
||||
}
|
||||
for (ExportInfo exportInfo : exportInfoList) {
|
||||
if (masterTable != null && exportInfo.getTableId().equals(masterTable.getTableId())) {
|
||||
if (exportInfo.getVirtualColumnId() != null) {
|
||||
OnlineVirtualColumn virtualColumn =
|
||||
onlineVirtualColumnService.getById(exportInfo.getVirtualColumnId());
|
||||
if (virtualColumn != null) {
|
||||
headerMap.put(virtualColumn.getObjectFieldName(), exportInfo.showName);
|
||||
}
|
||||
} else {
|
||||
OnlineColumn column = masterTable.getColumnMap().get(exportInfo.getColumnId());
|
||||
if (column.getDictId() != null) {
|
||||
headerMap.put(column.getColumnName() + "__DictMap.name", exportInfo.getShowName());
|
||||
} else {
|
||||
headerMap.put(column.getColumnName(), exportInfo.getShowName());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (MapUtil.isEmpty(allRelationMap)) {
|
||||
continue;
|
||||
}
|
||||
OnlineDatasourceRelation relation = allRelationMap.get(exportInfo.getTableId());
|
||||
if (relation != null) {
|
||||
OnlineColumn column = relation.getSlaveTable().getColumnMap().get(exportInfo.getColumnId());
|
||||
String columnName = relation.getVariableName()
|
||||
+ OnlineConstant.RELATION_TABLE_COLUMN_SEPARATOR + column.getColumnName();
|
||||
if (column.getDictId() != null) {
|
||||
columnName = columnName + "__DictMap.name";
|
||||
}
|
||||
headerMap.put(columnName, exportInfo.getShowName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return headerMap;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class ExportInfo {
|
||||
private Long tableId;
|
||||
private Long columnId;
|
||||
private Long virtualColumnId;
|
||||
private String showName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,7 @@ public interface OnlineColumnMapper extends BaseDaoMapper<OnlineColumn> {
|
||||
* 获取过滤后的对象列表。
|
||||
*
|
||||
* @param onlineColumnFilter 主表过滤对象。
|
||||
* @param orderBy 排序字符串,order by从句的参数。
|
||||
* @return 对象列表。
|
||||
*/
|
||||
List<OnlineColumn> getOnlineColumnList(
|
||||
@Param("onlineColumnFilter") OnlineColumn onlineColumnFilter, @Param("orderBy") String orderBy);
|
||||
List<OnlineColumn> getOnlineColumnList(@Param("onlineColumnFilter") OnlineColumn onlineColumnFilter);
|
||||
}
|
||||
|
||||
@@ -7,18 +7,18 @@
|
||||
<result column="table_id" jdbcType="BIGINT" property="tableId"/>
|
||||
<result column="column_type" jdbcType="VARCHAR" property="columnType"/>
|
||||
<result column="full_column_type" jdbcType="VARCHAR" property="fullColumnType"/>
|
||||
<result column="primary_key" jdbcType="BIT" property="primaryKey"/>
|
||||
<result column="auto_increment" jdbcType="BIT" property="autoIncrement"/>
|
||||
<result column="nullable" jdbcType="BIT" property="nullable"/>
|
||||
<result column="primary_key" jdbcType="BOOLEAN" property="primaryKey"/>
|
||||
<result column="auto_increment" jdbcType="BOOLEAN" property="autoIncrement"/>
|
||||
<result column="nullable" jdbcType="BOOLEAN" property="nullable"/>
|
||||
<result column="column_default" jdbcType="VARCHAR" property="columnDefault"/>
|
||||
<result column="column_show_order" jdbcType="INTEGER" property="columnShowOrder"/>
|
||||
<result column="column_comment" jdbcType="VARCHAR" property="columnComment"/>
|
||||
<result column="object_field_name" jdbcType="VARCHAR" property="objectFieldName"/>
|
||||
<result column="object_field_type" jdbcType="VARCHAR" property="objectFieldType"/>
|
||||
<result column="filter_type" jdbcType="INTEGER" property="filterType"/>
|
||||
<result column="parent_key" jdbcType="BIT" property="parentKey"/>
|
||||
<result column="dept_filter" jdbcType="BIT" property="deptFilter"/>
|
||||
<result column="user_filter" jdbcType="BIT" property="userFilter"/>
|
||||
<result column="parent_key" jdbcType="BOOLEAN" property="parentKey"/>
|
||||
<result column="dept_filter" jdbcType="BOOLEAN" property="deptFilter"/>
|
||||
<result column="user_filter" jdbcType="BOOLEAN" property="userFilter"/>
|
||||
<result column="field_kind" jdbcType="INTEGER" property="fieldKind"/>
|
||||
<result column="max_file_count" jdbcType="INTEGER" property="maxFileCount"/>
|
||||
<result column="dict_id" jdbcType="BIGINT" property="dictId"/>
|
||||
@@ -49,8 +49,6 @@
|
||||
<where>
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
ORDER BY column_show_order
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
<result column="master_column_id" jdbcType="BIGINT" property="masterColumnId"/>
|
||||
<result column="slave_table_id" jdbcType="BIGINT" property="slaveTableId"/>
|
||||
<result column="slave_column_id" jdbcType="BIGINT" property="slaveColumnId"/>
|
||||
<result column="cascade_delete" jdbcType="BIT" property="cascadeDelete"/>
|
||||
<result column="left_join" jdbcType="BIT" property="leftJoin"/>
|
||||
<result column="cascade_delete" jdbcType="BOOLEAN" property="cascadeDelete"/>
|
||||
<result column="left_join" jdbcType="BOOLEAN" property="leftJoin"/>
|
||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||
</resultMap>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<result column="user_filter_column_name" jdbcType="VARCHAR" property="userFilterColumnName"/>
|
||||
<result column="dept_filter_column_name" jdbcType="VARCHAR" property="deptFilterColumnName"/>
|
||||
<result column="tenant_filter_column_name" jdbcType="VARCHAR" property="tenantFilterColumnName"/>
|
||||
<result column="tree_flag" jdbcType="BIT" property="treeFlag"/>
|
||||
<result column="tree_flag" jdbcType="BOOLEAN" property="treeFlag"/>
|
||||
<result column="dict_list_url" jdbcType="VARCHAR" property="dictListUrl"/>
|
||||
<result column="dict_ids_url" jdbcType="VARCHAR" property="dictIdsUrl"/>
|
||||
<result column="dict_data_json" jdbcType="LONGVARCHAR" property="dictDataJson"/>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<result column="page_name" jdbcType="VARCHAR" property="pageName"/>
|
||||
<result column="page_type" jdbcType="INTEGER" property="pageType"/>
|
||||
<result column="status" jdbcType="INTEGER" property="status"/>
|
||||
<result column="published" jdbcType="BIT" property="published"/>
|
||||
<result column="published" jdbcType="BOOLEAN" property="published"/>
|
||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||
</resultMap>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<id column="rule_id" jdbcType="BIGINT" property="ruleId"/>
|
||||
<result column="rule_name" jdbcType="VARCHAR" property="ruleName"/>
|
||||
<result column="rule_type" jdbcType="INTEGER" property="ruleType"/>
|
||||
<result column="builtin" jdbcType="BIT" property="builtin"/>
|
||||
<result column="builtin" jdbcType="BOOLEAN" property="builtin"/>
|
||||
<result column="pattern" jdbcType="VARCHAR" property="pattern"/>
|
||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.orangeforms.common.online.object;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 在线表单常量字典的数据结构。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2021-06-06
|
||||
*/
|
||||
@Data
|
||||
public class ConstDictInfo {
|
||||
|
||||
private List<ConstDictData> dictData;
|
||||
|
||||
@Data
|
||||
public static class ConstDictData {
|
||||
private String type;
|
||||
private Object id;
|
||||
private String name;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.orangeforms.common.online.service;
|
||||
|
||||
import com.orangeforms.common.core.base.service.IBaseService;
|
||||
import com.orangeforms.common.core.object.CallResult;
|
||||
import com.orangeforms.common.online.model.OnlineColumn;
|
||||
import com.orangeforms.common.online.model.OnlineColumnRule;
|
||||
import com.orangeforms.common.online.object.SqlTableColumn;
|
||||
@@ -105,22 +104,20 @@ public interface OnlineColumnService extends IBaseService<OnlineColumn, Long> {
|
||||
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
|
||||
* 如果需要同时获取关联数据,请移步(getOnlineColumnListWithRelation)方法。
|
||||
*
|
||||
* @param filter 过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @param filter 过滤对象。
|
||||
* @return 查询结果集。
|
||||
*/
|
||||
List<OnlineColumn> getOnlineColumnList(OnlineColumn filter, String orderBy);
|
||||
List<OnlineColumn> getOnlineColumnList(OnlineColumn filter);
|
||||
|
||||
/**
|
||||
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
|
||||
* 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
|
||||
* 如果仅仅需要获取主表数据,请移步(getOnlineColumnList),以便获取更好的查询性能。
|
||||
*
|
||||
* @param filter 主表过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @param filter 主表过滤对象。
|
||||
* @return 查询结果集。
|
||||
*/
|
||||
List<OnlineColumn> getOnlineColumnListWithRelation(OnlineColumn filter, String orderBy);
|
||||
List<OnlineColumn> getOnlineColumnListWithRelation(OnlineColumn filter);
|
||||
|
||||
/**
|
||||
* 获取指定数据表Id集合的字段对象列表。
|
||||
|
||||
@@ -8,8 +8,10 @@ import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.common.core.base.service.BaseService;
|
||||
import com.orangeforms.common.core.object.CallResult;
|
||||
import com.orangeforms.common.core.object.MyRelationParam;
|
||||
import com.orangeforms.common.core.config.CoreProperties;
|
||||
import com.orangeforms.common.core.util.RedisKeyUtil;
|
||||
import com.orangeforms.common.sequence.wrapper.IdGeneratorWrapper;
|
||||
import com.orangeforms.common.online.config.OnlineProperties;
|
||||
import com.orangeforms.common.online.dao.OnlineColumnMapper;
|
||||
import com.orangeforms.common.online.dao.OnlineColumnRuleMapper;
|
||||
import com.orangeforms.common.online.model.OnlineColumn;
|
||||
@@ -51,6 +53,8 @@ public class OnlineColumnServiceImpl extends BaseService<OnlineColumn, Long> imp
|
||||
private IdGeneratorWrapper idGenerator;
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
@Autowired
|
||||
private OnlineProperties onlineProperties;
|
||||
|
||||
/**
|
||||
* 返回当前Service的主表Mapper对象。
|
||||
@@ -168,13 +172,12 @@ public class OnlineColumnServiceImpl extends BaseService<OnlineColumn, Long> imp
|
||||
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
|
||||
* 如果需要同时获取关联数据,请移步(getOnlineColumnListWithRelation)方法。
|
||||
*
|
||||
* @param filter 过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @param filter 过滤对象。
|
||||
* @return 查询结果集。
|
||||
*/
|
||||
@Override
|
||||
public List<OnlineColumn> getOnlineColumnList(OnlineColumn filter, String orderBy) {
|
||||
return onlineColumnMapper.getOnlineColumnList(filter, orderBy);
|
||||
public List<OnlineColumn> getOnlineColumnList(OnlineColumn filter) {
|
||||
return onlineColumnMapper.getOnlineColumnList(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,13 +185,12 @@ public class OnlineColumnServiceImpl extends BaseService<OnlineColumn, Long> imp
|
||||
* 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
|
||||
* 如果仅仅需要获取主表数据,请移步(getOnlineColumnList),以便获取更好的查询性能。
|
||||
*
|
||||
* @param filter 主表过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @param filter 主表过滤对象。
|
||||
* @return 查询结果集。
|
||||
*/
|
||||
@Override
|
||||
public List<OnlineColumn> getOnlineColumnListWithRelation(OnlineColumn filter, String orderBy) {
|
||||
List<OnlineColumn> resultList = onlineColumnMapper.getOnlineColumnList(filter, orderBy);
|
||||
public List<OnlineColumn> getOnlineColumnListWithRelation(OnlineColumn filter) {
|
||||
List<OnlineColumn> resultList = onlineColumnMapper.getOnlineColumnList(filter);
|
||||
// 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。
|
||||
// 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。
|
||||
int batchSize = resultList instanceof Page ? 0 : 1000;
|
||||
@@ -325,41 +327,75 @@ public class OnlineColumnServiceImpl extends BaseService<OnlineColumn, Long> imp
|
||||
}
|
||||
|
||||
private String convertToJavaType(String columnType) {
|
||||
if ("varchar".equals(columnType)
|
||||
|| "char".equals(columnType)
|
||||
|| "text".equals(columnType)
|
||||
|| "longtext".equals(columnType)
|
||||
|| "mediumtext".equals(columnType)
|
||||
|| "tinytext".equals(columnType)) {
|
||||
return "String";
|
||||
}
|
||||
if ("int".equals(columnType)
|
||||
|| "mediumint".equals(columnType)
|
||||
|| "smallint".equals(columnType)
|
||||
|| "tinyint".equals(columnType)) {
|
||||
return "Integer";
|
||||
}
|
||||
if ("bit".equals(columnType)) {
|
||||
return "Boolean";
|
||||
}
|
||||
if ("bigint".equals(columnType)) {
|
||||
return "Long";
|
||||
}
|
||||
if ("decimal".equals(columnType)) {
|
||||
return "BigDecimal";
|
||||
}
|
||||
if ("float".equals(columnType)
|
||||
|| "double".equals(columnType)) {
|
||||
return "Double";
|
||||
}
|
||||
if ("date".equals(columnType)
|
||||
|| "datetime".equals(columnType)
|
||||
|| "timestamp".equals(columnType)
|
||||
|| "time".equals(columnType)) {
|
||||
return "Date";
|
||||
}
|
||||
if ("blob".equals(columnType)) {
|
||||
return "byte[]";
|
||||
if (onlineProperties.getDatabaseType().equals(CoreProperties.MYSQL_TYPE)) {
|
||||
if ("varchar".equals(columnType)
|
||||
|| "char".equals(columnType)
|
||||
|| "text".equals(columnType)
|
||||
|| "longtext".equals(columnType)
|
||||
|| "mediumtext".equals(columnType)
|
||||
|| "tinytext".equals(columnType)) {
|
||||
return "String";
|
||||
}
|
||||
if ("int".equals(columnType)
|
||||
|| "mediumint".equals(columnType)
|
||||
|| "smallint".equals(columnType)
|
||||
|| "tinyint".equals(columnType)) {
|
||||
return "Integer";
|
||||
}
|
||||
if ("bit".equals(columnType)) {
|
||||
return "Boolean";
|
||||
}
|
||||
if ("bigint".equals(columnType)) {
|
||||
return "Long";
|
||||
}
|
||||
if ("decimal".equals(columnType)) {
|
||||
return "BigDecimal";
|
||||
}
|
||||
if ("float".equals(columnType)
|
||||
|| "double".equals(columnType)) {
|
||||
return "Double";
|
||||
}
|
||||
if ("date".equals(columnType)
|
||||
|| "datetime".equals(columnType)
|
||||
|| "timestamp".equals(columnType)
|
||||
|| "time".equals(columnType)) {
|
||||
return "Date";
|
||||
}
|
||||
if ("blob".equals(columnType)) {
|
||||
return "byte[]";
|
||||
}
|
||||
} else if (onlineProperties.getDatabaseType().equals(CoreProperties.POSTGRESQL_TYPE)) {
|
||||
if ("varchar".equals(columnType)
|
||||
|| "char".equals(columnType)
|
||||
|| "text".equals(columnType)) {
|
||||
return "String";
|
||||
}
|
||||
if ("int4".equals(columnType)
|
||||
|| "int2".equals(columnType)
|
||||
|| "bit".equals(columnType)) {
|
||||
return "Integer";
|
||||
}
|
||||
if ("bool".equals(columnType)) {
|
||||
return "Boolean";
|
||||
}
|
||||
if ("int8".equals(columnType)) {
|
||||
return "Long";
|
||||
}
|
||||
if ("numeric".equals(columnType)) {
|
||||
return "BigDecimal";
|
||||
}
|
||||
if ("float4".equals(columnType)
|
||||
|| "float8".equals(columnType)) {
|
||||
return "Double";
|
||||
}
|
||||
if ("date".equals(columnType)
|
||||
|| "timestamp".equals(columnType)
|
||||
|| "time".equals(columnType)) {
|
||||
return "Date";
|
||||
}
|
||||
if ("bytea".equals(columnType)) {
|
||||
return "byte[]";
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Unsupported Data Type");
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.orangeforms.common.online.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.common.core.base.service.BaseService;
|
||||
import com.orangeforms.common.core.config.CoreProperties;
|
||||
import com.orangeforms.common.core.config.DataSourceContextHolder;
|
||||
import com.orangeforms.common.core.object.MyRelationParam;
|
||||
import com.orangeforms.common.sequence.wrapper.IdGeneratorWrapper;
|
||||
@@ -166,7 +169,16 @@ public class OnlineDblinkServiceImpl extends BaseService<OnlineDblink, Long> imp
|
||||
resultList.forEach(r -> {
|
||||
SqlTableColumn sqlTableColumn =
|
||||
BeanUtil.mapToBean(r, SqlTableColumn.class, false, null);
|
||||
sqlTableColumn.setAutoIncrement("auto_increment".equals(sqlTableColumn.getExtra()));
|
||||
if (onlineProperties.getDatabaseType().equals(CoreProperties.POSTGRESQL_TYPE)) {
|
||||
if (StrUtil.equalsAny(sqlTableColumn.getColumnType(), "char", "varchar")) {
|
||||
sqlTableColumn.setFullColumnType(
|
||||
sqlTableColumn.getColumnType() + "(" + sqlTableColumn.getStringPrecision() + ")");
|
||||
} else {
|
||||
sqlTableColumn.setFullColumnType(sqlTableColumn.getColumnType());
|
||||
}
|
||||
} else if (onlineProperties.getDatabaseType().equals(CoreProperties.MYSQL_TYPE)) {
|
||||
sqlTableColumn.setAutoIncrement("auto_increment".equals(sqlTableColumn.getExtra()));
|
||||
}
|
||||
columnList.add(sqlTableColumn);
|
||||
});
|
||||
return columnList;
|
||||
@@ -191,9 +203,18 @@ public class OnlineDblinkServiceImpl extends BaseService<OnlineDblink, Long> imp
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
SqlTableColumn sqlTableColumn =
|
||||
BeanUtil.mapToBean(result, SqlTableColumn.class, false, null);
|
||||
sqlTableColumn.setAutoIncrement("auto_increment".equals(sqlTableColumn.getExtra()));
|
||||
SqlTableColumn sqlTableColumn = BeanUtil.mapToBean(
|
||||
result, SqlTableColumn.class, false, CopyOptions.create().ignoreCase());
|
||||
if (onlineProperties.getDatabaseType().equals(CoreProperties.POSTGRESQL_TYPE)) {
|
||||
if (StrUtil.equalsAny(sqlTableColumn.getColumnType(), "char", "varchar")) {
|
||||
sqlTableColumn.setFullColumnType(
|
||||
sqlTableColumn.getColumnType() + "(" + sqlTableColumn.getStringPrecision() + ")");
|
||||
} else {
|
||||
sqlTableColumn.setFullColumnType(sqlTableColumn.getColumnType());
|
||||
}
|
||||
} else if (onlineProperties.getDatabaseType().equals(CoreProperties.MYSQL_TYPE)) {
|
||||
sqlTableColumn.setAutoIncrement("auto_increment".equals(sqlTableColumn.getExtra()));
|
||||
}
|
||||
return sqlTableColumn;
|
||||
} finally {
|
||||
DataSourceContextHolder.unset(originalType);
|
||||
|
||||
@@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.orangeforms.common.core.annotation.MyDataSourceResolver;
|
||||
import com.orangeforms.common.core.config.CoreProperties;
|
||||
@@ -19,6 +20,7 @@ import com.orangeforms.common.datafilter.constant.DataPermRuleType;
|
||||
import com.orangeforms.common.datafilter.config.DataFilterProperties;
|
||||
import com.orangeforms.common.online.config.OnlineProperties;
|
||||
import com.orangeforms.common.online.model.constant.*;
|
||||
import com.orangeforms.common.online.object.ConstDictInfo;
|
||||
import com.orangeforms.common.online.service.OnlineVirtualColumnService;
|
||||
import com.orangeforms.common.online.util.OnlineOperationHelper;
|
||||
import com.orangeforms.common.sequence.wrapper.IdGeneratorWrapper;
|
||||
@@ -75,14 +77,14 @@ public class OnlineOperationServiceImpl implements OnlineOperationService {
|
||||
|
||||
/**
|
||||
* 聚合返回数据中,聚合键的常量字段名。
|
||||
* 如select groupColumn groupedKey, max(aggregationColumn) aggregatedValue。
|
||||
* 如select groupColumn grouped_key, max(aggregationColumn) aggregated_value。
|
||||
*/
|
||||
private static final String KEY_NAME = "groupedKey";
|
||||
private static final String KEY_NAME = "grouped_key";
|
||||
/**
|
||||
* 聚合返回数据中,聚合值的常量字段名。
|
||||
* 如select groupColumn groupedKey, max(aggregationColumn) aggregatedValue。
|
||||
* 如select groupColumn grouped_key, max(aggregationColumn) aggregated_value。
|
||||
*/
|
||||
private static final String VALUE_NAME = "aggregatedValue";
|
||||
private static final String VALUE_NAME = "aggregated_value";
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
@@ -556,8 +558,10 @@ public class OnlineOperationServiceImpl implements OnlineOperationService {
|
||||
if (CollUtil.isEmpty(dictIdSet)) {
|
||||
return;
|
||||
}
|
||||
List<OnlineDict> dictList = onlineDictService.getOnlineDictList(dictIdSet)
|
||||
.stream().filter(d -> d.getDictType() == DictType.TABLE).collect(Collectors.toList());
|
||||
List<OnlineDict> allDictList = onlineDictService.getOnlineDictList(dictIdSet);
|
||||
List<OnlineDict> dictList = allDictList.stream()
|
||||
.filter(d -> d.getDictType() == DictType.TABLE || d.getDictType() == DictType.CUSTOM)
|
||||
.collect(Collectors.toList());
|
||||
for (OnlineDict dict : dictList) {
|
||||
Collection<String> columnNameList = dictColumnMap.get(dict.getDictId());
|
||||
for (String columnName : columnNameList) {
|
||||
@@ -571,27 +575,38 @@ public class OnlineOperationServiceImpl implements OnlineOperationService {
|
||||
if (CollUtil.isEmpty(dictIdDataSet)) {
|
||||
continue;
|
||||
}
|
||||
String selectFields = this.makeDictSelectFields(dict, true);
|
||||
List<OnlineFilterDto> filterList = new LinkedList<>();
|
||||
if (StrUtil.isNotBlank(dict.getDeletedColumnName())) {
|
||||
OnlineFilterDto filter = new OnlineFilterDto();
|
||||
filter.setColumnName(dict.getDeletedColumnName());
|
||||
filter.setColumnValue(GlobalDeletedFlag.NORMAL);
|
||||
filterList.add(filter);
|
||||
}
|
||||
OnlineFilterDto inlistFilter = new OnlineFilterDto();
|
||||
inlistFilter.setColumnName(dict.getKeyColumnName());
|
||||
inlistFilter.setColumnValueList(dictIdDataSet);
|
||||
inlistFilter.setFilterType(FieldFilterType.IN_LIST_FILTER);
|
||||
filterList.add(inlistFilter);
|
||||
List<Map<String, Object>> dictResultList =
|
||||
onlineOperationMapper.getDictList(dict.getTableName(), selectFields, filterList, null);
|
||||
if (CollUtil.isEmpty(dictResultList)) {
|
||||
continue;
|
||||
}
|
||||
Map<Object, Object> dictResultMap = new HashMap<>(dictResultList.size());
|
||||
for (Map<String, Object> dictResult : dictResultList) {
|
||||
dictResultMap.put(dictResult.get("id"), dictResult.get("name"));
|
||||
Map<Object, Object> dictResultMap;
|
||||
if (dict.getDictType().equals(DictType.CUSTOM)) {
|
||||
ConstDictInfo dictInfo =
|
||||
JSONObject.parseObject(dict.getDictDataJson(), ConstDictInfo.class);
|
||||
List<ConstDictInfo.ConstDictData> dictDataList = dictInfo.getDictData();
|
||||
dictResultMap = new HashMap<>(dictDataList.size());
|
||||
for (ConstDictInfo.ConstDictData dictData : dictDataList) {
|
||||
dictResultMap.put(dictData.getId(), dictData.getName());
|
||||
}
|
||||
} else {
|
||||
String selectFields = this.makeDictSelectFields(dict, true);
|
||||
List<OnlineFilterDto> filterList = new LinkedList<>();
|
||||
if (StrUtil.isNotBlank(dict.getDeletedColumnName())) {
|
||||
OnlineFilterDto filter = new OnlineFilterDto();
|
||||
filter.setColumnName(dict.getDeletedColumnName());
|
||||
filter.setColumnValue(GlobalDeletedFlag.NORMAL);
|
||||
filterList.add(filter);
|
||||
}
|
||||
OnlineFilterDto inlistFilter = new OnlineFilterDto();
|
||||
inlistFilter.setColumnName(dict.getKeyColumnName());
|
||||
inlistFilter.setColumnValueList(dictIdDataSet);
|
||||
inlistFilter.setFilterType(FieldFilterType.IN_LIST_FILTER);
|
||||
filterList.add(inlistFilter);
|
||||
List<Map<String, Object>> dictResultList =
|
||||
onlineOperationMapper.getDictList(dict.getTableName(), selectFields, filterList, null);
|
||||
if (CollUtil.isEmpty(dictResultList)) {
|
||||
continue;
|
||||
}
|
||||
dictResultMap = new HashMap<>(dictResultList.size());
|
||||
for (Map<String, Object> dictResult : dictResultList) {
|
||||
dictResultMap.put(dictResult.get("id"), dictResult.get("name"));
|
||||
}
|
||||
}
|
||||
String dictKeyName = columnName + "__DictMap";
|
||||
for (Map<String, Object> result : resultList) {
|
||||
@@ -664,32 +679,32 @@ public class OnlineOperationServiceImpl implements OnlineOperationService {
|
||||
.append(column.getColumnName())
|
||||
.append(" AS ")
|
||||
.append(intString)
|
||||
.append(") ")
|
||||
.append(") \"")
|
||||
.append(relationVariableName)
|
||||
.append(OnlineConstant.RELATION_TABLE_COLUMN_SEPARATOR)
|
||||
.append(column.getColumnName())
|
||||
.append(",");
|
||||
.append("\",");
|
||||
} else if ("date".equals(column.getColumnType())) {
|
||||
selectFieldBuider
|
||||
.append("CAST(")
|
||||
.append(slaveTable.getTableName())
|
||||
.append(".")
|
||||
.append(column.getColumnName())
|
||||
.append(" AS CHAR(10)) ")
|
||||
.append(" AS CHAR(10)) \"")
|
||||
.append(relationVariableName)
|
||||
.append(OnlineConstant.RELATION_TABLE_COLUMN_SEPARATOR)
|
||||
.append(column.getColumnName())
|
||||
.append(",");
|
||||
.append("\",");
|
||||
} else {
|
||||
selectFieldBuider
|
||||
.append(slaveTable.getTableName())
|
||||
.append(".")
|
||||
.append(column.getColumnName())
|
||||
.append(" ")
|
||||
.append(" \"")
|
||||
.append(relationVariableName)
|
||||
.append(OnlineConstant.RELATION_TABLE_COLUMN_SEPARATOR)
|
||||
.append(column.getColumnName())
|
||||
.append(",");
|
||||
.append("\",");
|
||||
}
|
||||
}
|
||||
return selectFieldBuider.substring(0, selectFieldBuider.length() - 1);
|
||||
@@ -718,32 +733,32 @@ public class OnlineOperationServiceImpl implements OnlineOperationService {
|
||||
.append(column.getColumnName())
|
||||
.append(" AS ")
|
||||
.append(intString)
|
||||
.append(") ")
|
||||
.append(") \"")
|
||||
.append(relation.getVariableName())
|
||||
.append(OnlineConstant.RELATION_TABLE_COLUMN_SEPARATOR)
|
||||
.append(column.getColumnName())
|
||||
.append(",");
|
||||
.append("\",");
|
||||
} else if ("date".equals(column.getColumnType())) {
|
||||
selectFieldBuider
|
||||
.append("CAST(")
|
||||
.append(slaveTable.getTableName())
|
||||
.append(".")
|
||||
.append(column.getColumnName())
|
||||
.append(" AS CHAR(10)) ")
|
||||
.append(" AS CHAR(10)) \"")
|
||||
.append(relation.getVariableName())
|
||||
.append(OnlineConstant.RELATION_TABLE_COLUMN_SEPARATOR)
|
||||
.append(column.getColumnName())
|
||||
.append(",");
|
||||
.append("\",");
|
||||
} else {
|
||||
selectFieldBuider
|
||||
.append(slaveTable.getTableName())
|
||||
.append(".")
|
||||
.append(column.getColumnName())
|
||||
.append(" ")
|
||||
.append(" \"")
|
||||
.append(relation.getVariableName())
|
||||
.append(OnlineConstant.RELATION_TABLE_COLUMN_SEPARATOR)
|
||||
.append(column.getColumnName())
|
||||
.append(",");
|
||||
.append("\",");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -762,18 +777,18 @@ public class OnlineOperationServiceImpl implements OnlineOperationService {
|
||||
.append(column.getColumnName())
|
||||
.append(" AS ")
|
||||
.append(intString)
|
||||
.append(") ")
|
||||
.append(") \"")
|
||||
.append(column.getColumnName())
|
||||
.append(",");
|
||||
.append("\",");
|
||||
} else if ("date".equals(column.getColumnType())) {
|
||||
selectFieldBuider
|
||||
.append("CAST(")
|
||||
.append(masterTable.getTableName())
|
||||
.append(".")
|
||||
.append(column.getColumnName())
|
||||
.append(" AS CHAR(10)) ")
|
||||
.append(" AS CHAR(10)) \"")
|
||||
.append(column.getColumnName())
|
||||
.append(",");
|
||||
.append("\",");
|
||||
} else {
|
||||
selectFieldBuider
|
||||
.append(masterTable.getTableName())
|
||||
@@ -787,10 +802,10 @@ public class OnlineOperationServiceImpl implements OnlineOperationService {
|
||||
|
||||
private String makeDictSelectFields(OnlineDict onlineDict, boolean ignoreParentId) {
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
sb.append(onlineDict.getKeyColumnName()).append(" id, ");
|
||||
sb.append(onlineDict.getValueColumnName()).append(" name");
|
||||
sb.append(onlineDict.getKeyColumnName()).append(" \"id\", ");
|
||||
sb.append(onlineDict.getValueColumnName()).append(" \"name\"");
|
||||
if (!ignoreParentId && onlineDict.getTreeFlag()) {
|
||||
sb.append(", ").append(onlineDict.getParentKeyColumnName()).append(" parentId");
|
||||
sb.append(", ").append(onlineDict.getParentKeyColumnName()).append(" \"parentId\"");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.orangeforms.common.online.util;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
@@ -114,10 +115,6 @@ public class OnlineOperationHelper {
|
||||
if (relation == null || !relation.getDatasourceId().equals(datasourceId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
if (!relation.getRelationType().equals(RelationType.ONE_TO_MANY)) {
|
||||
errorMessage = "数据验证失败,数据源关联 [" + relation.getRelationName() + " ] 不是一对多关联,不能调用该接口!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
OnlineTable slaveTable = onlineTableService.getOnlineTableFromCache(relation.getSlaveTableId());
|
||||
if (slaveTable == null) {
|
||||
errorMessage = "数据验证失败,数据源关联 [" + relation.getRelationName() + " ] 引用的从表不存在!";
|
||||
@@ -173,6 +170,13 @@ public class OnlineOperationHelper {
|
||||
continue;
|
||||
}
|
||||
Object value = tableData.get(column.getColumnName());
|
||||
if (value != null) {
|
||||
if ("Long".equals(column.getObjectFieldType())) {
|
||||
value = Long.valueOf(value.toString());
|
||||
} else if ("Date".equals(column.getObjectFieldType())) {
|
||||
value = Convert.toDate(value);
|
||||
}
|
||||
}
|
||||
// 对于主键数据的处理。
|
||||
if (column.getPrimaryKey()) {
|
||||
// 如果是更新则必须包含主键参数。
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<spring-boot.version>2.3.10.RELEASE</spring-boot.version>
|
||||
<spring-boot-admin.version>2.3.1</spring-boot-admin.version>
|
||||
<spring-boot.version>2.5.8</spring-boot.version>
|
||||
<spring-boot-admin.version>2.5.5</spring-boot-admin.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
|
||||
Binary file not shown.
@@ -216,7 +216,7 @@ const SysOnlineRuleType = new DictionaryBase('验证规则类型', [
|
||||
symbol: 'MOBILE'
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
id: 100,
|
||||
name: '自定义验证',
|
||||
symbol: 'CUSTOM'
|
||||
}
|
||||
@@ -381,6 +381,11 @@ const SysCustomWidgetOperationType = new DictionaryBase('操作类型', [
|
||||
name: '导出',
|
||||
symbol: 'EXPORT'
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: '批量删除',
|
||||
symbol: 'BATCH_DELETE'
|
||||
},
|
||||
{
|
||||
id: 20,
|
||||
name: '自定义操作',
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<div class="header-menu" style="flex-grow: 1;">
|
||||
<el-dropdown trigger="click" style="margin-right: 10px;" @command="handleMessage">
|
||||
<el-badge is-dot :hidden="(getMessageCount || {}).totalCount == null || (getMessageCount || {}).totalCount <= 0"
|
||||
style="height: 180x; line-height: 18px; cursor: pointer;">
|
||||
style="height: 18px; line-height: 18px; cursor: pointer;">
|
||||
<i class="el-icon-bell" style="font-size: 18px;" />
|
||||
</el-badge>
|
||||
<el-dropdown-menu slot="dropdown" style="min-width: 130px;">
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
v-for="operation in getTableOperation(false)" :key="operation.id"
|
||||
:plain="operation.plain"
|
||||
:type="operation.btnType"
|
||||
@click.stop="onOperationClick(operation)">
|
||||
@click.stop="onOperationClick(operation)"
|
||||
>
|
||||
{{operation.name}}
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -22,7 +23,8 @@
|
||||
:style="{height: (widgetConfig.tableInfo.height != null && widgetConfig.tableInfo.height !== '') ? widgetConfig.tableInfo.height + 'px' : undefined}"
|
||||
:height="(widgetConfig.tableInfo.height != null && widgetConfig.tableInfo.height !== '') ? widgetConfig.tableInfo.height + 'px' : undefined"
|
||||
:data="tableWidget.dataList" :row-key="primaryColumnName"
|
||||
@sort-change="tableWidget.onSortChange">
|
||||
@sort-change="tableWidget.onSortChange" @selection-change="onTableSelectionChange">
|
||||
<el-table-column v-if="hasBatchDelete" header-align="center" align="center" type="selection" width="55px" />
|
||||
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="tableWidget.getTableIndex" />
|
||||
<template v-for="tableColumn in widgetConfig.tableColumnList">
|
||||
<!-- Boolean类型的字段,使用el-tag去显示 -->
|
||||
@@ -187,10 +189,14 @@ export default {
|
||||
false,
|
||||
this.widgetConfig.tableInfo.orderFieldName,
|
||||
this.widgetConfig.tableInfo.ascending
|
||||
)
|
||||
),
|
||||
selectRows: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onTableSelectionChange (values) {
|
||||
this.selectRows = values;
|
||||
},
|
||||
onViewWorkOrder (row) {
|
||||
this.$emit('viewWOrkOrder', row, this.widgetConfig);
|
||||
},
|
||||
@@ -206,6 +212,39 @@ export default {
|
||||
getTableWidget () {
|
||||
return this.tableWidget;
|
||||
},
|
||||
batchDelete () {
|
||||
if (!Array.isArray(this.selectRows) || this.selectRows.length <= 0) {
|
||||
this.$message.error('请选择要删除的数据!');
|
||||
return;
|
||||
}
|
||||
this.$confirm('是否删除选中数据?').then(res => {
|
||||
if (this.formType === this.SysOnlineFormType.FLOW) { // 工作流表单页面批量删除
|
||||
let selectIdList = this.selectRows.map(item => item.__cascade_add_id__);
|
||||
this.tableWidget.dataList = this.tableWidget.dataList.filter(item => {
|
||||
return selectIdList.indexOf(item.__cascade_add_id__) === -1;
|
||||
});
|
||||
} else {
|
||||
let params = {
|
||||
datasourceId: this.widgetConfig.datasource.datasourceId,
|
||||
relationId: this.widgetConfig.relation ? this.widgetConfig.relation.relationId : undefined,
|
||||
dataIdList: this.selectRows.map(item => {
|
||||
return item[this.primaryColumnName];
|
||||
})
|
||||
}
|
||||
|
||||
let httpCall;
|
||||
if (params.relationId) {
|
||||
httpCall = this.doUrl('/admin/online/onlineOperation/deleteBatchOneToManyRelation/' + this.widgetConfig.datasource.variableName, 'post', params);
|
||||
} else {
|
||||
httpCall = this.doUrl('/admin/online/onlineOperation/deleteBatchDatasource/' + this.widgetConfig.datasource.variableName, 'post', params);
|
||||
}
|
||||
httpCall.then(res => {
|
||||
this.tableWidget.refreshTable();
|
||||
}).catch(e => {
|
||||
});
|
||||
}
|
||||
}).catch(e => {});
|
||||
},
|
||||
setTableWidget (tableWidget) {
|
||||
// 如果正在读取数据,等待读取完毕再刷新
|
||||
let timer = setInterval(() => {
|
||||
@@ -219,7 +258,43 @@ export default {
|
||||
}, 30);
|
||||
},
|
||||
onOperationClick (operation, row) {
|
||||
this.$emit('operationClick', operation, row, this.widgetConfig);
|
||||
if (operation.type === this.SysCustomWidgetOperationType.BATCH_DELETE) {
|
||||
this.batchDelete();
|
||||
} else if (operation.type === this.SysCustomWidgetOperationType.EXPORT) {
|
||||
this.export(operation);
|
||||
} else {
|
||||
this.$emit('operationClick', operation, row, this.widgetConfig);
|
||||
}
|
||||
},
|
||||
export (operation) {
|
||||
this.$confirm('是否导出表格数据?').then(res => {
|
||||
if (this.formType === this.SysOnlineFormType.FLOW) {
|
||||
this.$message.error('工作流不支持导出!');
|
||||
} else {
|
||||
let queryParams = this.getTableQueryParams ? this.getTableQueryParams(this.widgetConfig) : undefined;
|
||||
|
||||
let params = {
|
||||
datasourceId: this.widgetConfig.datasource.datasourceId,
|
||||
relationId: this.widgetConfig.relation ? this.widgetConfig.relation.relationId : undefined,
|
||||
filterDtoList: queryParams,
|
||||
exportInfoList: (operation.exportColumnList || []).sort((val1, val2) => {
|
||||
return val1.showOrder - val2.showOrder;
|
||||
})
|
||||
}
|
||||
console.log(params);
|
||||
let httpCall;
|
||||
if (params.relationId) {
|
||||
httpCall = this.download('/admin/online/onlineOperation/exportByOneToManyRelationId/' + this.widgetConfig.datasource.variableName, params, this.widgetConfig.showName + '.xls');
|
||||
} else {
|
||||
httpCall = this.download('/admin/online/onlineOperation/exportByDatasourceId/' + this.widgetConfig.datasource.variableName, params, this.widgetConfig.showName + '.xls');
|
||||
}
|
||||
httpCall.then(res => {
|
||||
this.$message.success('导出成功!');
|
||||
}).catch(e => {
|
||||
this.$message.error(e);
|
||||
});
|
||||
}
|
||||
}).catch(e => {});
|
||||
},
|
||||
loadTableDictValue (tableData) {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -496,6 +571,14 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasBatchDelete () {
|
||||
for (let i = 0; i < this.widgetConfig.operationList.length; i++) {
|
||||
if (this.widgetConfig.operationList[i].type === this.SysCustomWidgetOperationType.BATCH_DELETE && this.widgetConfig.operationList[i].enabled) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
buildFlowParam () {
|
||||
let flowParam = {};
|
||||
if (this.flowData) {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" v-if="!formData.rowOperation">
|
||||
<el-form-item label="操作名称" prop="btnType">
|
||||
<el-form-item label="按钮类型" prop="btnType">
|
||||
<el-select v-model="formData.btnType">
|
||||
<el-option label="primary" value="primary" />
|
||||
<el-option label="success" value="success" />
|
||||
@@ -42,6 +42,35 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" v-show="formData.type === SysCustomWidgetOperationType.EXPORT" style="margin-bottom: 20px;">
|
||||
<el-table ref="expoerColumnTable" :data="tableColumnTree" row-key="id" header-cell-class-name="table-header-gray" height="400px"
|
||||
:default-expand-all="true" @selection-change="onExportColumnChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55px" :selectable="(row) => row.isColumn">
|
||||
<template slot="header">
|
||||
<span>AAA</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column type="index" width="55px" />
|
||||
<el-table-column label="导出字段" prop="variableName">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.variableName}}</span>
|
||||
<el-tag style="margin-left: 10px;" size="mini" type="danger" v-if="scope.row.aggregationColumnId">聚合字段</el-tag>
|
||||
<el-tag style="margin-left: 10px;" size="mini" type="success" v-if="scope.row.isTable && scope.row.relationType != null">一对一关联</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="显示名称" prop="showName" width="250px">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-if="scope.row.isColumn" size="mini" :disabled="!exportColumnIsSelected(scope.row)" v-model="scope.row.showName" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="显示顺序" width="150px">
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-if="scope.row.isColumn" size="mini" :disabled="!exportColumnIsSelected(scope.row)" v-model="scope.row.showOrder" controls-position="right" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-row class="no-scroll flex-box" type="flex" justify="end">
|
||||
<el-button type="primary" :size="defaultFormItemSize" :plain="true"
|
||||
@@ -60,7 +89,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { findItemFromList } from '@/utils';
|
||||
export default {
|
||||
props: {
|
||||
rowData: {
|
||||
@@ -69,6 +98,9 @@ export default {
|
||||
formList: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
tableList: {
|
||||
type: Array
|
||||
}
|
||||
},
|
||||
data () {
|
||||
@@ -82,8 +114,11 @@ export default {
|
||||
builtin: false,
|
||||
rowOperation: true,
|
||||
btnClass: 'table-btn primary',
|
||||
formId: undefined
|
||||
formId: undefined,
|
||||
exportColumnList: []
|
||||
},
|
||||
tableColumnTree: [],
|
||||
exportColumn: [],
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: '操作按钮名称不能为空', trigger: 'blur' }
|
||||
@@ -94,6 +129,19 @@ export default {
|
||||
methods: {
|
||||
onCancel (isSuccess) {
|
||||
if (this.observer != null) {
|
||||
if (this.formData.type === this.SysCustomWidgetOperationType.EXPORT) {
|
||||
this.formData.exportColumnList = (this.exportColumn || []).map(column => {
|
||||
return column ? {
|
||||
tableId: column.table.tableId,
|
||||
columnId: column.columnId,
|
||||
virtualColumnId: column.aggregationColumnId,
|
||||
showName: column.showName,
|
||||
showOrder: column.showOrder
|
||||
} : undefined;
|
||||
});
|
||||
} else {
|
||||
this.formData.exportColumnList = [];
|
||||
}
|
||||
this.observer.cancel(isSuccess, this.formData);
|
||||
}
|
||||
},
|
||||
@@ -102,6 +150,46 @@ export default {
|
||||
if (!valid) return;
|
||||
this.onCancel(true);
|
||||
});
|
||||
},
|
||||
onExportColumnChange (value) {
|
||||
this.exportColumn = value;
|
||||
},
|
||||
exportColumnIsSelected (row) {
|
||||
if (Array.isArray(this.exportColumn)) {
|
||||
return this.exportColumn.indexOf(row) !== -1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
getTableColumnTree () {
|
||||
this.tableColumnTree = [];
|
||||
let selectedRows = [];
|
||||
if (Array.isArray(this.tableList)) {
|
||||
this.tableColumnTree = this.tableList.map(item => {
|
||||
return {
|
||||
variableName: item.tableName,
|
||||
id: item.tableId,
|
||||
isTable: true,
|
||||
relationType: item.relationType,
|
||||
children: (item.columnList || []).map(column => {
|
||||
let columnInfo = findItemFromList(this.formData.exportColumnList, column.aggregationColumnId, 'virtualColumnId');
|
||||
if (columnInfo == null) columnInfo = findItemFromList(this.formData.exportColumnList, column.columnId, 'columnId');
|
||||
let temp = {
|
||||
...column,
|
||||
id: column.aggregationColumnId || column.columnId,
|
||||
table: item,
|
||||
variableName: column.columnName,
|
||||
showName: (columnInfo || {}).showName || column.columnComment,
|
||||
showOrder: (columnInfo || {}).showOrder || 0,
|
||||
isColumn: true
|
||||
};
|
||||
if (columnInfo != null) selectedRows.push(temp);
|
||||
return temp;
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
return selectedRows;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -116,10 +204,19 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.exportColumn = [];
|
||||
if (this.rowData != null) {
|
||||
this.formData = {
|
||||
...this.rowData
|
||||
}
|
||||
if (this.formData.type === this.SysCustomWidgetOperationType.EXPORT) {
|
||||
let selectedRows = this.getTableColumnTree();
|
||||
this.$nextTick(() => {
|
||||
selectedRows.forEach(row => {
|
||||
this.$refs.expoerColumnTable.toggleRowSelection(row);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,8 +487,10 @@
|
||||
<el-input-number v-model="currentWidgetItem.tableInfo.optionColumnWidth" placeholder="请输入表格高度,单位px" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" style="border-top: 1px solid #EBEEF5;">
|
||||
<el-table :data="currentWidgetItem.operationList" :show-header="false">
|
||||
<el-col v-if="formConfig.formType !== this.SysOnlineFormType.WORK_ORDER"
|
||||
:span="24" style="border-top: 1px solid #EBEEF5;"
|
||||
>
|
||||
<el-table :data="getCurrentWidgetOperationList" :show-header="false">
|
||||
<el-table-column label="操作" width="45px">
|
||||
<template slot-scope="scope">
|
||||
<el-button class="table-btn delete" type="text" icon="el-icon-remove-outline"
|
||||
@@ -503,7 +505,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="是否启动" prop="enabled" width="70px">
|
||||
<template slot-scope="scope">
|
||||
<el-switch v-model="scope.row.enabled" />
|
||||
<el-switch v-model="scope.row.enabled" @change="onTableOperationEnableChange(scope.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作类型" prop="type" width="90px">
|
||||
@@ -973,12 +975,23 @@ export default {
|
||||
});
|
||||
}).catch(e => {});
|
||||
},
|
||||
onTableOperationEnableChange (row) {
|
||||
let operation = findItemFromList(this.currentWidgetItem.operationList, row.type, 'type');
|
||||
this.currentWidgetItem.operationList = this.currentWidgetItem.operationList.map(item => {
|
||||
return (item.id === row.id) ? row : item;
|
||||
});
|
||||
if (operation == null) {
|
||||
this.currentWidgetItem.operationList.unshift(row);
|
||||
}
|
||||
},
|
||||
onAddTableOperation (operation) {
|
||||
this.$dialog.show(operation ? '编辑操作' : '新建操作', EditWidgetTableOperation, {
|
||||
area: '600px'
|
||||
area: '900px',
|
||||
offset: '100px'
|
||||
}, {
|
||||
rowData: operation,
|
||||
formList: this.formList.filter(item => item.formId !== this.form.formId)
|
||||
formList: this.formList.filter(item => item.formId !== this.form.formId),
|
||||
tableList: this.getWidgetColumnTableList(this.currentWidgetItem.table)
|
||||
}).then(res => {
|
||||
if (operation == null) {
|
||||
let maxId = 0;
|
||||
@@ -1384,6 +1397,30 @@ export default {
|
||||
getMasterTable () {
|
||||
return this.tableList[0];
|
||||
},
|
||||
getCurrentWidgetOperationList () {
|
||||
if (this.currentWidgetItem == null) return [];
|
||||
// 非内置操作
|
||||
let otherOperation = (this.currentWidgetItem.operationList || []).filter(item => {
|
||||
let operation = findItemFromList(defaultWidgetAttributes.table.operationList, item.type, 'type');
|
||||
return operation == null;
|
||||
}).map(item => {
|
||||
return {
|
||||
...item
|
||||
}
|
||||
});
|
||||
// 内置操作
|
||||
let operationList = (defaultWidgetAttributes.table.operationList || []).filter(item => {
|
||||
return this.formConfig.formType === this.SysOnlineFormType.FLOW ? item.type !== this.SysCustomWidgetOperationType.EXPORT : true;
|
||||
}).map(item => {
|
||||
let operation = findItemFromList(this.currentWidgetItem.operationList, item.type, 'type');
|
||||
if (operation == null) operation = item;
|
||||
operation.id = item.id;
|
||||
return {
|
||||
...operation
|
||||
}
|
||||
});
|
||||
return operationList.concat(otherOperation);
|
||||
},
|
||||
getFormParameterList () {
|
||||
if (this.getMasterTable != null) {
|
||||
return this.getMasterTable.columnList.filter(item => {
|
||||
|
||||
@@ -133,20 +133,28 @@ const defaultWidgetAttributes = {
|
||||
titleColor: '#409EFF',
|
||||
tableColumnList: [],
|
||||
operationList: [
|
||||
/**
|
||||
* 暂时去掉导出操作,等支持后再开启
|
||||
{
|
||||
id: 0,
|
||||
type: SysCustomWidgetOperationType.EXPORT,
|
||||
name: '导出',
|
||||
enabled: true,
|
||||
enabled: false,
|
||||
builtin: true,
|
||||
rowOperation: false,
|
||||
btnType: 'primary',
|
||||
plain: true,
|
||||
formId: undefined
|
||||
},
|
||||
*/
|
||||
{
|
||||
id: 4,
|
||||
type: SysCustomWidgetOperationType.BATCH_DELETE,
|
||||
name: '批量删除',
|
||||
enabled: false,
|
||||
builtin: true,
|
||||
rowOperation: false,
|
||||
btnType: 'danger',
|
||||
plain: true,
|
||||
formId: undefined
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
type: SysCustomWidgetOperationType.ADD,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<el-form ref="dictData" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
|
||||
label-width="100px" :size="defaultFormItemSize" label-position="right" @submit.native.prevent>
|
||||
<el-form-item label="字典键类型">
|
||||
<el-radio-group v-model="formData.type">
|
||||
<el-radio-group v-model="formData.type" :disabled="value != null">
|
||||
<el-radio-button label="Integer">整数</el-radio-button>
|
||||
<el-radio-button label="String">字符串</el-radio-button>
|
||||
</el-radio-group>
|
||||
@@ -66,6 +66,8 @@ export default {
|
||||
onSubmit () {
|
||||
this.$refs.dictData.validate(valid => {
|
||||
if (!valid) return;
|
||||
if (this.formData.type === 'Integer') this.formData.id = Number.parseInt(this.formData.id);
|
||||
if (this.formData.type === 'String') this.formData.id = this.formData.id.toString();
|
||||
this.$emit('save', this.formData, this.value);
|
||||
this.isShow = false;
|
||||
});
|
||||
|
||||
@@ -5,7 +5,12 @@
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="关联名称" prop="relationName">
|
||||
<el-input class="input-item" v-model="formData.relationName" />
|
||||
<el-input class="input-item" v-model="formData.relationName" :clearable="true" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="关联标识" prop="variableName">
|
||||
<el-input class="input-item" v-model="formData.variableName" :clearable="true" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
@@ -51,7 +56,8 @@
|
||||
<el-form-item label="从表关联字段" prop="slaveColumnId">
|
||||
<el-select class="input-item" v-model="formData.slaveColumnId" :clearable="true" filterable
|
||||
placeholder="关联从表" :loading="slaveColumnIdWidget.loading"
|
||||
@visible-change="slaveColumnIdWidget.onVisibleChange">
|
||||
@visible-change="slaveColumnIdWidget.onVisibleChange"
|
||||
>
|
||||
<el-option v-for="item in slaveColumnIdWidget.dropdownList" :key="item.columnId" :value="item.columnId" :label="item.columnName">
|
||||
<span>{{item.columnName}}</span>
|
||||
</el-option>
|
||||
@@ -135,6 +141,9 @@ export default {
|
||||
rules: {
|
||||
relationName: [
|
||||
{required: true, message: '请输入关联名称', trigger: 'blur'}
|
||||
],
|
||||
variableName: [
|
||||
{required: true, message: '请输入关联标识', trigger: 'blur'}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -148,11 +157,6 @@ export default {
|
||||
onSubmit () {
|
||||
this.$refs.formEditOnlinePageDatasourceRelation.validate((valid) => {
|
||||
if (!valid) return;
|
||||
let masterColumn = findItemFromList(this.masterColumnIdWidget.dropdownList, this.formData.masterColumnId, 'columnId');
|
||||
let slaveTable = findItemFromList(this.slaveTableIdWidget.dropdownList, this.formData.slaveTableId, 'id');
|
||||
let slaveColumn = findItemFromList(this.slaveColumnIdWidget.dropdownList, this.formData.slaveColumnId, 'columnId');
|
||||
if (!this.isEdit) this.formData.variableName = masterColumn.columnName + '_' + slaveTable.name + '_' + slaveColumn.columnName + 'Relation';
|
||||
|
||||
let params = {
|
||||
onlineDatasourceRelationDto: {
|
||||
datasourceId: this.datasource.datasourceId,
|
||||
@@ -326,6 +330,19 @@ export default {
|
||||
reject(e);
|
||||
});
|
||||
});
|
||||
},
|
||||
buildRelationVariableName () {
|
||||
console.log(this.formData.variableName);
|
||||
if (this.formData.variableName == null || this.formData.variableName === '') {
|
||||
let masterColumn = findItemFromList(this.masterColumnIdWidget.dropdownList, this.formData.masterColumnId, 'columnId');
|
||||
let slaveTable = findItemFromList(this.slaveTableIdWidget.dropdownList, this.formData.slaveTableId, 'id');
|
||||
let slaveColumn = findItemFromList(this.slaveColumnIdWidget.dropdownList, this.formData.slaveColumnId, 'columnId');
|
||||
console.log(masterColumn, slaveTable, slaveColumn);
|
||||
if (masterColumn && slaveTable && slaveColumn) {
|
||||
this.formData.variableName = masterColumn.columnName + '_' + slaveTable.name + '_' + slaveColumn.columnName;
|
||||
console.log(this.formData.variableName);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -336,6 +353,14 @@ export default {
|
||||
return this.datasource.validTableList;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'formData.slaveColumnId': {
|
||||
handler (newValue) {
|
||||
console.log(newValue);
|
||||
this.buildRelationVariableName();
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
if (this.isEdit) {
|
||||
OnlineDatasourceRelationController.view(this, {
|
||||
|
||||
@@ -367,7 +367,7 @@ const OnlineFormMixins = {
|
||||
}
|
||||
break;
|
||||
case this.SysOnlineRuleType.CUSTOM:
|
||||
return { type: 'string', pattern: new RegExp(rule.data.pattern), message: rule.data.message, trigger: 'blur' };
|
||||
return { type: 'string', pattern: new RegExp(rule.onlineRule.pattern), message: rule.data.message, trigger: 'blur' };
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -119,7 +119,13 @@ export default {
|
||||
}
|
||||
},
|
||||
onTableOperationClick (operation, row, widget) {
|
||||
this.handlerOperation(operation, row, widget);
|
||||
if (operation.type === this.SysCustomWidgetOperationType.BATCH_DELETE) {
|
||||
this.$refs[this.formConfig.formQueryTable.variableName].batchDelete();
|
||||
} else if (operation.type === this.SysCustomWidgetOperationType.EXPORT) {
|
||||
this.$refs[this.formConfig.formQueryTable.variableName].export(operation);
|
||||
} else {
|
||||
this.handlerOperation(operation, row, widget);
|
||||
}
|
||||
},
|
||||
onResume () {
|
||||
let key = this.$route.fullPath;
|
||||
|
||||
@@ -168,13 +168,11 @@ export default {
|
||||
if (!valid) return reject();
|
||||
let tempObj = {};
|
||||
let that = this;
|
||||
let oneToOneRelationObj = {};
|
||||
let hasMasterData = false;
|
||||
function getFlowWidgetData (widget) {
|
||||
if (widget == null || widget.readOnly || widget.disabled) return;
|
||||
if (widget.relation == null) {
|
||||
if (tempObj.masterData == null) tempObj.masterData = {};
|
||||
tempObj.masterData[widget.column.columnName] = that.formData[that.getWidgetFieldName(widget)];
|
||||
tempObj.masterData.__maasterTable__ = widget.table;
|
||||
} else {
|
||||
if (widget.relation != null) {
|
||||
if (tempObj.slaveData == null) tempObj.slaveData = {};
|
||||
if (widget.widgetType === that.SysCustomWidgetType.Table) {
|
||||
let tableData = that.getRelationTableData(widget);
|
||||
@@ -182,13 +180,10 @@ export default {
|
||||
tempObj.slaveData[widget.relation.relationId] = tableData;
|
||||
}
|
||||
} else {
|
||||
let value = that.formData[that.getWidgetFieldName(widget)];
|
||||
if (value != null && widget.column != null) {
|
||||
if (tempObj.slaveData[widget.relation.relationId] == null) tempObj.slaveData[widget.relation.relationId] = {};
|
||||
tempObj.slaveData[widget.relation.relationId][widget.column.columnName] = value;
|
||||
if (tempObj.slaveData[widget.relation.relationId]['__slaveWidget__'] == null) tempObj.slaveData[widget.relation.relationId]['__slaveWidget__'] = widget;
|
||||
}
|
||||
oneToOneRelationObj[widget.relation.relationId] = widget.relation;
|
||||
}
|
||||
} else {
|
||||
hasMasterData = true;
|
||||
}
|
||||
|
||||
if (Array.isArray(widget.childWidgetList)) {
|
||||
@@ -197,44 +192,30 @@ export default {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 一对多关联数据
|
||||
if (Array.isArray(this.formConfig.formWidgetList)) {
|
||||
this.formConfig.formWidgetList.forEach(widget => {
|
||||
getFlowWidgetData(widget);
|
||||
});
|
||||
}
|
||||
|
||||
if (tempObj.masterData != null && tempObj.masterData.__maasterTable__ != null) {
|
||||
let primaryColumn = null;
|
||||
if (Array.isArray(tempObj.masterData.__maasterTable__.columnList)) {
|
||||
primaryColumn = tempObj.masterData.__maasterTable__.columnList.filter(column => {
|
||||
return column.primaryKey;
|
||||
})[0];
|
||||
}
|
||||
if (primaryColumn != null && this.formData[primaryColumn.columnName] != null) {
|
||||
tempObj.masterData[primaryColumn.columnName] = this.formData[primaryColumn.columnName];
|
||||
}
|
||||
delete tempObj.masterData.__maasterTable__;
|
||||
}
|
||||
|
||||
if (tempObj.slaveData != null) {
|
||||
Object.keys(tempObj.slaveData).map(key => {
|
||||
let slaveObj = tempObj.slaveData[key];
|
||||
let primaryColumn = null;
|
||||
if (slaveObj != null && slaveObj.__slaveWidget__ != null && slaveObj.__slaveWidget__.table != null) {
|
||||
if (Array.isArray(slaveObj.__slaveWidget__.table.columnList)) {
|
||||
primaryColumn = slaveObj.__slaveWidget__.table.columnList.filter(column => {
|
||||
return column.primaryKey;
|
||||
})[0];
|
||||
}
|
||||
let widget = slaveObj.__slaveWidget__;
|
||||
if (primaryColumn != null && this.formData[widget.relation.variableName + '__' + (widget.column || {}).columnName] != null) {
|
||||
slaveObj[primaryColumn.columnName] = this.formData[widget.relation.variableName + '__' + (widget.column || {}).columnName]
|
||||
}
|
||||
delete slaveObj.__slaveWidget__;
|
||||
}
|
||||
// 主表数据
|
||||
if (hasMasterData && this.masterTable) {
|
||||
this.masterTable.columnList.forEach(column => {
|
||||
if (tempObj.masterData == null) tempObj.masterData = {};
|
||||
tempObj.masterData[column.columnName] = this.formData[column.columnName];
|
||||
});
|
||||
}
|
||||
// 一对一关联数据
|
||||
Object.keys(oneToOneRelationObj).forEach(relationId => {
|
||||
let relation = oneToOneRelationObj[relationId];
|
||||
if (relation && relation.slaveTable && Array.isArray(relation.slaveTable.columnList)) {
|
||||
relation.slaveTable.columnList.forEach(column => {
|
||||
let value = that.formData[relation.variableName + '__' + (column || {}).columnName];
|
||||
if (tempObj.slaveData[relationId] == null) tempObj.slaveData[relationId] = {};
|
||||
tempObj.slaveData[relationId][column.columnName] = value;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
resolve(tempObj);
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="上级菜单">
|
||||
<el-cascader :options="menuTree" v-model="parentMenuPath" :props="menuProps" placeholder="选择父菜单"
|
||||
:disabled="!canEditParent || isEdit" :clearable="true" :change-on-select="true" :size="defaultFormItemSize"
|
||||
:clearable="true" :change-on-select="true" :size="defaultFormItemSize"
|
||||
@change="onParentMenuChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -180,12 +180,13 @@ export default {
|
||||
}
|
||||
},
|
||||
onParentMenuChange (value, isInit) {
|
||||
if (!isInit) this.formData.menuType = undefined;
|
||||
this.parentMenuType = undefined;
|
||||
if (Array.isArray(value) && value.length > 0) {
|
||||
let node = findTreeNode(this.menuTree, value[value.length - 1], 'menuId');
|
||||
if (node) this.parentMenuType = node.menuType;
|
||||
}
|
||||
// 父菜单切换后判断可用菜单类型是否改变,如果改变则清空
|
||||
if (!isInit && this.getValidMenuType.map(item => item.id).indexOf(this.formData.menuType) === -1) this.formData.menuType = undefined;
|
||||
},
|
||||
onCancel (isSuccess) {
|
||||
if (this.observer != null) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<el-row type="flex" justify="space-between" style="margin-bottom: 15px;">
|
||||
<el-radio-group size="small" v-model="currentPage" style="min-width: 350px;">
|
||||
<el-radio-group size="small" v-model="currentPage" style="min-width: 400px;">
|
||||
<el-radio-button label="formInfo">表单信息</el-radio-button>
|
||||
<el-radio-button v-if="processInstanceId == null || isRuntime || isRuntime === 'true'" label="copyInfo">抄送设置</el-radio-button>
|
||||
<el-radio-button v-if="processInstanceId != null" label="flowProcess">流程图</el-radio-button>
|
||||
|
||||
@@ -180,7 +180,7 @@ export default {
|
||||
this.getMasterData(operation.type, (res || {}).assignee).then(formData => {
|
||||
FlowOperationController.startAndTakeUserTask(this, {
|
||||
processDefinitionKey: this.processDefinitionKey,
|
||||
masterData: formData.masterData,
|
||||
masterData: formData.masterData || {},
|
||||
slaveData: formData.slaveData,
|
||||
taskVariableData: formData.taskVariableData,
|
||||
flowTaskCommentDto: {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="上级菜单">
|
||||
<el-cascader :options="menuTree" v-model="parentMenuPath" :props="menuProps" placeholder="选择父菜单"
|
||||
:disabled="!canEditParent || isEdit" :clearable="true" :change-on-select="true" :size="defaultFormItemSize"
|
||||
:clearable="true" :change-on-select="true" :size="defaultFormItemSize"
|
||||
@change="onParentMenuChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -143,12 +143,13 @@ export default {
|
||||
}
|
||||
},
|
||||
onParentMenuChange (value, isInit) {
|
||||
if (!isInit) this.formData.menuType = undefined;
|
||||
this.parentMenuType = undefined;
|
||||
if (Array.isArray(value) && value.length > 0) {
|
||||
let node = findTreeNode(this.menuTree, value[value.length - 1], 'menuId');
|
||||
if (node) this.parentMenuType = node.menuType;
|
||||
}
|
||||
// 父菜单切换后判断可用菜单类型是否改变,如果改变则清空
|
||||
if (!isInit && this.getValidMenuType.map(item => item.id).indexOf(this.formData.menuType) === -1) this.formData.menuType = undefined;
|
||||
},
|
||||
onCancel (isSuccess) {
|
||||
if (this.observer != null) {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package com.orangeforms.operationlogconsumer;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
@@ -10,8 +11,9 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@SpringCloudApplication
|
||||
@ComponentScan("com.orangeforms")
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication
|
||||
public class OperationLogConsumerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package com.orangeforms.courseclassservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@@ -11,9 +12,9 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@SpringCloudApplication
|
||||
@EnableFeignClients(basePackages = "com.orangeforms")
|
||||
@ComponentScan("com.orangeforms")
|
||||
@EnableFeignClients(basePackages = "com.orangeforms")
|
||||
@SpringBootApplication
|
||||
public class CourseClassApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
</if>
|
||||
<if test="studentFilter.searchString != null and studentFilter.searchString != ''">
|
||||
<bind name = "safeStudentSearchString" value = "'%' + studentFilter.searchString + '%'" />
|
||||
AND CONCAT(COALESCE(zz_student.login_mobile,''), COALESCE(zz_student.student_name,'')) LIKE #{safeStudentSearchString}
|
||||
AND CONCAT(IFNULL(zz_student.login_mobile,''), IFNULL(zz_student.student_name,'')) LIKE #{safeStudentSearchString}
|
||||
</if>
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
@@ -5,9 +5,9 @@ import com.orangeforms.gateway.filter.AuthenticationPostFilter;
|
||||
import com.orangeforms.gateway.filter.AuthenticationPreFilter;
|
||||
import com.orangeforms.gateway.filter.RequestLogFilter;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -19,8 +19,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
|
||||
@SpringCloudApplication
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
|
||||
public class GatewayApplication {
|
||||
|
||||
@RestController
|
||||
|
||||
@@ -22,10 +22,14 @@ public class CorsConfig {
|
||||
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(new PathPatternParser());
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
if (StringUtils.isNotBlank(appConfig.getCredentialIpList())) {
|
||||
String[] credentialIpList = StringUtils.split(appConfig.getCredentialIpList(), ",");
|
||||
if (credentialIpList.length > 0) {
|
||||
for (String ip : credentialIpList) {
|
||||
config.addAllowedOrigin(ip);
|
||||
if ("*".equals(appConfig.getCredentialIpList())) {
|
||||
config.addAllowedOriginPattern("*");
|
||||
} else {
|
||||
String[] credentialIpList = StringUtils.split(appConfig.getCredentialIpList(), ",");
|
||||
if (credentialIpList.length > 0) {
|
||||
for (String ip : credentialIpList) {
|
||||
config.addAllowedOrigin(ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
config.addAllowedHeader("*");
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package com.orangeforms.statsservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@@ -11,9 +12,9 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@SpringCloudApplication
|
||||
@EnableFeignClients(basePackages = "com.orangeforms")
|
||||
@ComponentScan("com.orangeforms")
|
||||
@EnableFeignClients(basePackages = "com.orangeforms")
|
||||
@SpringBootApplication
|
||||
public class StatsApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.orangeforms.upmsservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@@ -13,10 +13,10 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
|
||||
@SpringCloudApplication
|
||||
@EnableFeignClients(basePackages = "com.orangeforms")
|
||||
@ComponentScan("com.orangeforms")
|
||||
@EnableFeignClients(basePackages = "com.orangeforms")
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
|
||||
public class UpmsApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -26,7 +26,7 @@ public interface SysDeptRelationMapper extends BaseDaoMapper<SysDeptRelation> {
|
||||
/**
|
||||
* 批量插入部门关联数据。
|
||||
* 由于目前版本(3.4.1)的Mybatis Plus没有提供真正的批量插入,为了保证效率需要自己实现。
|
||||
* 目前我们仅仅给出MySQL的insert list实现作为参考,其他数据库需要自行修改。
|
||||
* 目前我们仅仅给出MySQL和PostgresSQL的insert list实现作为参考,其他数据库需要自行修改。
|
||||
*
|
||||
* @param deptRelationList 部门关联关系数据列表。
|
||||
*/
|
||||
|
||||
@@ -2,8 +2,8 @@ package com.orangeforms.common.core.base.client;
|
||||
|
||||
import com.orangeforms.common.core.constant.ErrorCodeEnum;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import feign.hystrix.FallbackFactory;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@ package com.orangeforms.common.core.base.controller;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.orangeforms.common.core.base.mapper.BaseModelMapper;
|
||||
import com.orangeforms.common.core.base.service.IBaseService;
|
||||
import com.orangeforms.common.core.config.CoreProperties;
|
||||
import com.orangeforms.common.core.constant.AggregationKind;
|
||||
import com.orangeforms.common.core.constant.AggregationType;
|
||||
import com.orangeforms.common.core.constant.ErrorCodeEnum;
|
||||
@@ -19,6 +21,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -42,6 +45,8 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
public abstract class BaseController<M, V, K extends Serializable> {
|
||||
|
||||
@Autowired
|
||||
private CoreProperties coreProperties;
|
||||
/**
|
||||
* 当前Service关联的主Model实体对象的Class。
|
||||
*/
|
||||
@@ -245,7 +250,42 @@ public abstract class BaseController<M, V, K extends Serializable> {
|
||||
}
|
||||
}
|
||||
M filter = queryParam.getFilterDto(modelClass);
|
||||
if (StrUtil.isNotBlank(queryParam.getInFilterField())
|
||||
&& CollUtil.isNotEmpty(queryParam.getInFilterValues())) {
|
||||
if (queryParam.getCriteriaList() == null) {
|
||||
queryParam.setCriteriaList(new LinkedList<>());
|
||||
}
|
||||
MyWhereCriteria whereCriteria = new MyWhereCriteria();
|
||||
whereCriteria.setFieldName(queryParam.getInFilterField());
|
||||
whereCriteria.setOperatorType(MyWhereCriteria.OPERATOR_IN);
|
||||
whereCriteria.setValue(queryParam.getInFilterValues());
|
||||
queryParam.getCriteriaList().add(whereCriteria);
|
||||
}
|
||||
String whereClause = MyWhereCriteria.makeCriteriaString(queryParam.getCriteriaList(), modelClass);
|
||||
if (CollUtil.isNotEmpty(queryParam.getSearchStringFieldList())
|
||||
&& StrUtil.isNotBlank(queryParam.getSearchStringValue())) {
|
||||
String tableName = MyModelUtil.mapToTableName(modelClass);
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
if (StrUtil.isNotBlank(whereClause)) {
|
||||
sb.append(" AND ");
|
||||
}
|
||||
sb.append(" CONCAT(");
|
||||
for (int i = 0; i < queryParam.getSearchStringFieldList().size(); i++) {
|
||||
String fieldName = queryParam.getSearchStringFieldList().get(i);
|
||||
String columnName = MyModelUtil.mapToColumnInfo(fieldName, modelClass).getFirst();
|
||||
if (coreProperties.isMySql()) {
|
||||
sb.append("IFNULL(");
|
||||
} else if (coreProperties.isPostgresql()) {
|
||||
sb.append("COALESCE(");
|
||||
}
|
||||
sb.append(tableName).append(".").append(columnName).append(", '')");
|
||||
if (i != queryParam.getSearchStringFieldList().size() - 1) {
|
||||
sb.append(", ");
|
||||
}
|
||||
}
|
||||
sb.append(") LIKE ").append("'").append(queryParam.getSearchStringValue()).append("'");
|
||||
whereClause = whereClause + sb.toString();
|
||||
}
|
||||
String orderBy = MyOrderParam.buildOrderBy(queryParam.getOrderParam(), modelClass);
|
||||
MyPageParam pageParam = queryParam.getPageParam();
|
||||
if (pageParam != null) {
|
||||
@@ -364,9 +404,9 @@ public abstract class BaseController<M, V, K extends Serializable> {
|
||||
for (Map.Entry<Object, Set<Object>> entry : param.getGroupedInFilterValues().entrySet()) {
|
||||
StringBuilder groupedSelectList = new StringBuilder(64);
|
||||
if (stringKey) {
|
||||
groupedSelectList.append("'").append(entry.getKey()).append("' ");
|
||||
groupedSelectList.append("'").append(entry.getKey()).append("' as ");
|
||||
} else {
|
||||
groupedSelectList.append(entry.getKey()).append(" ");
|
||||
groupedSelectList.append(entry.getKey()).append(" as ");
|
||||
}
|
||||
groupedSelectList.append(MyAggregationParam.KEY_NAME).append(", ").append(selectList);
|
||||
MyWhereCriteria criteria = new MyWhereCriteria();
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.orangeforms.common.core.object.TokenData;
|
||||
import com.orangeforms.common.core.util.ContextUtil;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -17,6 +18,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration
|
||||
public class FeignConfig implements RequestInterceptor {
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void apply(RequestTemplate requestTemplate) {
|
||||
// 对于非servlet请求发起的远程调用,由于无法获取到标识用户身份的TokenData,因此需要略过下面的HEADER注入。
|
||||
|
||||
@@ -19,13 +19,13 @@ public class MyAggregationParam {
|
||||
* 聚合返回数据中,聚合键的常量字段名。
|
||||
* 如select groupColumn groupedKey, max(aggregationColumn) aggregatedValue。
|
||||
*/
|
||||
public static final String KEY_NAME = "groupedKey";
|
||||
public static final String KEY_NAME = "grouped_key";
|
||||
|
||||
/**
|
||||
* 聚合返回数据中,聚合值的常量字段名。
|
||||
* 如select groupColumn groupedKey, max(aggregationColumn) aggregatedValue。
|
||||
*/
|
||||
public static final String VALUE_NAME = "aggregatedValue";
|
||||
public static final String VALUE_NAME = "aggregated_value";
|
||||
|
||||
/**
|
||||
* 聚合计算是否使用数据权限进行过滤。true表示数据过滤将产生作用,否则SQL中不会包含数据过滤。
|
||||
|
||||
@@ -61,6 +61,16 @@ public class MyQueryParam {
|
||||
*/
|
||||
private Boolean withDict = false;
|
||||
|
||||
/**
|
||||
* 参与模糊搜索的Java字段列表。
|
||||
*/
|
||||
private List<String> searchStringFieldList;
|
||||
|
||||
/**
|
||||
* 模糊搜索的字符串值,该值要包含百分号,这样可以精确控制搜索参数中百分号的配置。
|
||||
*/
|
||||
private String searchStringValue;
|
||||
|
||||
/**
|
||||
* 缺省构造函数。
|
||||
*/
|
||||
|
||||
@@ -43,6 +43,12 @@ public class MyDateUtil {
|
||||
private static final DateTimeFormatter DATETIME_PARSE_FORMATTER =
|
||||
DateTimeFormat.forPattern(MyDateUtil.COMMON_DATETIME_FORMAT);
|
||||
|
||||
/**
|
||||
* 缺省短日期时间格式化器,提前获取提升运行时效率。
|
||||
*/
|
||||
private static final DateTimeFormatter DATETIME_SHORT_PARSE_FORMATTER =
|
||||
DateTimeFormat.forPattern(MyDateUtil.COMMON_SHORT_DATETIME_FORMAT);
|
||||
|
||||
/**
|
||||
* 获取一天的开始时间的字符串格式,如2019-08-03 00:00:00.000。
|
||||
*
|
||||
@@ -144,6 +150,16 @@ public class MyDateUtil {
|
||||
return DATETIME_PARSE_FORMATTER.parseDateTime(dateTimeString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将缺省格式的(不包含毫秒的)日期时间字符串解析为日期对象。
|
||||
*
|
||||
* @param dateTimeString 待解析的字符串。
|
||||
* @return 解析后的日期对象。
|
||||
*/
|
||||
public static DateTime toDateTimeWithoutMs(String dateTimeString) {
|
||||
return DATETIME_SHORT_PARSE_FORMATTER.parseDateTime(dateTimeString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 截取时间到天。如2019-10-03 01:20:30 转换为 2019-10-03 00:00:00。
|
||||
* 由于没有字符串的中间转换,因此效率更高。
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<result column="request_arguments" jdbcType="VARCHAR" property="requestArguments"/>
|
||||
<result column="response_result" jdbcType="VARCHAR" property="responseResult"/>
|
||||
<result column="request_ip" jdbcType="VARCHAR" property="requestIp"/>
|
||||
<result column="success" jdbcType="BIT" property="success"/>
|
||||
<result column="success" jdbcType="BOOLEAN" property="success"/>
|
||||
<result column="error_msg" jdbcType="VARCHAR" property="errorMsg"/>
|
||||
<result column="tenant_id" jdbcType="BIGINT" property="tenantId"/>
|
||||
<result column="operator_id" jdbcType="BIGINT" property="operatorId"/>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package com.orangeforms.uaaadmin;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
@@ -10,8 +11,9 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@SpringCloudApplication
|
||||
@ComponentScan("com.orangeforms")
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication
|
||||
public class UaaAdminApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -24,10 +24,14 @@ public class CorsConfig {
|
||||
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
|
||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
if (StringUtils.isNotBlank(applicationConfig.getCredentialIpList())) {
|
||||
String[] credentialIpList = StringUtils.split(applicationConfig.getCredentialIpList(), ",");
|
||||
if (credentialIpList.length > 0) {
|
||||
for (String ip : credentialIpList) {
|
||||
corsConfiguration.addAllowedOrigin(ip);
|
||||
if ("*".equals(applicationConfig.getCredentialIpList())) {
|
||||
corsConfiguration.addAllowedOriginPattern("*");
|
||||
} else {
|
||||
String[] credentialIpList = StringUtils.split(applicationConfig.getCredentialIpList(), ",");
|
||||
if (credentialIpList.length > 0) {
|
||||
for (String ip : credentialIpList) {
|
||||
corsConfiguration.addAllowedOrigin(ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
corsConfiguration.addAllowedHeader("*");
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.orangeforms.uaaadmin.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.common.core.base.service.BaseService;
|
||||
import com.orangeforms.common.core.constant.GlobalDeletedFlag;
|
||||
import com.orangeforms.common.core.object.MyRelationParam;
|
||||
import com.orangeforms.common.core.util.MyModelUtil;
|
||||
import com.orangeforms.common.sequence.wrapper.IdGeneratorWrapper;
|
||||
@@ -54,6 +54,7 @@ public class SysUaaUserServiceImpl extends BaseService<SysUaaUser, Long> impleme
|
||||
sysUaaUser.setUserId(idGenerator.nextLongId());
|
||||
sysUaaUser.setPassword(passwordEncoder.encode(sysUaaUser.getPassword()));
|
||||
MyModelUtil.fillCommonsForInsert(sysUaaUser);
|
||||
sysUaaUser.setDeletedFlag(GlobalDeletedFlag.NORMAL);
|
||||
sysUaaUserMapper.insert(sysUaaUser);
|
||||
return sysUaaUser;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-oauth2</artifactId>
|
||||
<version>2.2.5.RELEASE</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.security.oauth</groupId>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package com.orangeforms.uaaauth;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
@@ -10,8 +11,9 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@SpringCloudApplication
|
||||
@ComponentScan("com.orangeforms")
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication
|
||||
public class UaaAuthApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
|
||||
<spring-cloud-alibaba.version>2.2.5.RELEASE</spring-cloud-alibaba.version>
|
||||
<spring-boot.version>2.3.10.RELEASE</spring-boot.version>
|
||||
<spring-boot-admin.version>2.3.1</spring-boot-admin.version>
|
||||
<spring-cloud.version>2020.0.4</spring-cloud.version>
|
||||
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
|
||||
<spring-boot.version>2.5.8</spring-boot.version>
|
||||
<spring-boot-admin.version>2.5.5</spring-boot-admin.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
@@ -59,6 +59,10 @@
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||
</dependency>
|
||||
<!-- freemarker 模板引擎模块 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -180,14 +184,9 @@
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-httpclient</artifactId>
|
||||
</dependency>
|
||||
<!--断路器依赖-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
|
||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
<!-- api参数验证 -->
|
||||
<dependency>
|
||||
|
||||
@@ -42,7 +42,7 @@ spring:
|
||||
|
||||
# feign 配置
|
||||
feign:
|
||||
hystrix:
|
||||
sentinel:
|
||||
enabled: true
|
||||
httpclient:
|
||||
enabled: true
|
||||
@@ -66,22 +66,9 @@ feign:
|
||||
response:
|
||||
enabled: true
|
||||
|
||||
hystrix:
|
||||
command:
|
||||
default:
|
||||
execution:
|
||||
isolation:
|
||||
strategy: SEMAPHORE
|
||||
thread:
|
||||
timeoutInMilliseconds: 30000
|
||||
shareSecurityContext: true
|
||||
|
||||
#请求处理的超时时间
|
||||
ribbon:
|
||||
ReadTimeout: 7000
|
||||
ConnectTimeout: 3000
|
||||
MaxAutoRetries: 1
|
||||
MaxAutoRetriesNextServer: 1
|
||||
common-core:
|
||||
# 可选值为 mysql / postgresql
|
||||
databaseType: mysql
|
||||
|
||||
swagger:
|
||||
# 当enabled为false的时候,则可禁用swagger。
|
||||
@@ -116,8 +103,7 @@ management:
|
||||
# keys-to-sanitize:
|
||||
keys-to-sanitize: password
|
||||
server:
|
||||
servlet:
|
||||
context-path: "/"
|
||||
base-path: "/"
|
||||
|
||||
# 存储session数据的Redis,所有服务均需要,因此放到公共配置中。
|
||||
# 根据实际情况,该Redis也可以用于存储其他数据。
|
||||
|
||||
@@ -33,27 +33,15 @@ spring:
|
||||
- Path=/admin/upms/**
|
||||
filters:
|
||||
- StripPrefix=2
|
||||
- name: Hystrix
|
||||
args:
|
||||
name: default
|
||||
fallbackUri: forward:/fallback
|
||||
- id: course-class
|
||||
uri: lb://course-class
|
||||
predicates:
|
||||
- Path=/admin/CourseClass/**
|
||||
filters:
|
||||
- StripPrefix=2
|
||||
- name: Hystrix
|
||||
args:
|
||||
name: default
|
||||
fallbackUri: forward:/fallback
|
||||
- id: stats
|
||||
uri: lb://stats
|
||||
predicates:
|
||||
- Path=/admin/stats/**
|
||||
filters:
|
||||
- StripPrefix=2
|
||||
- name: Hystrix
|
||||
args:
|
||||
name: default
|
||||
fallbackUri: forward:/fallback
|
||||
|
||||
@@ -11,19 +11,6 @@
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO `zz_data_sync_producer_update_mark` VALUES (1,0,CURDATE());
|
||||
COMMIT;
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- 管理员账号数据
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `zz_sys_dept` VALUES(1293376634891538435,NULL,'公司总部',1,1293376634887344128,CURDATE(),1293376634887344128,CURDATE(),1);
|
||||
INSERT INTO `zz_sys_user` VALUES(1293376634887344128,'admin','管理员',1293376634891538435,NULL,0,0,1293376634887344128,CURDATE(),1293376634887344128,CURDATE(),1);
|
||||
INSERT INTO `zz_sys_dept_relation` VALUES(1293376634891538435,1293376634891538435);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- 全部菜单数据
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
DELETE FROM `zz_data_sync_producer_update_mark` WHERE id = 1;
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- 全部菜单数据
|
||||
-- ----------------------------
|
||||
|
||||
@@ -314,4 +314,17 @@ CREATE TABLE `zz_data_sync_producer_update_mark` (
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='数据同步生产者消息流水表的高水标记表';
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO `zz_data_sync_producer_update_mark` VALUES (1,0,CURDATE());
|
||||
COMMIT;
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- 管理员账号数据
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `zz_sys_dept` VALUES(1293376634891538435,NULL,'公司总部',1,1293376634887344128,CURDATE(),1293376634887344128,CURDATE(),1);
|
||||
INSERT INTO `zz_sys_user` VALUES(1293376634887344128,'admin','管理员',1293376634891538435,NULL,0,0,1293376634887344128,CURDATE(),1293376634887344128,CURDATE(),1);
|
||||
INSERT INTO `zz_sys_dept_relation` VALUES(1293376634891538435,1293376634891538435);
|
||||
COMMIT;
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package com.orangeforms.operationlogconsumer;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
@@ -10,8 +11,9 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@SpringCloudApplication
|
||||
@ComponentScan("com.orangeforms")
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication
|
||||
public class OperationLogConsumerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package com.orangeforms.courseclassservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@@ -11,9 +12,9 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@SpringCloudApplication
|
||||
@EnableFeignClients(basePackages = "com.orangeforms")
|
||||
@ComponentScan("com.orangeforms")
|
||||
@EnableFeignClients(basePackages = "com.orangeforms")
|
||||
@SpringBootApplication
|
||||
public class CourseClassApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
</if>
|
||||
<if test="studentFilter.searchString != null and studentFilter.searchString != ''">
|
||||
<bind name = "safeStudentSearchString" value = "'%' + studentFilter.searchString + '%'" />
|
||||
AND CONCAT(COALESCE(zz_student.login_mobile,''), COALESCE(zz_student.student_name,'')) LIKE #{safeStudentSearchString}
|
||||
AND CONCAT(IFNULL(zz_student.login_mobile,''), IFNULL(zz_student.student_name,'')) LIKE #{safeStudentSearchString}
|
||||
</if>
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
@@ -5,9 +5,9 @@ import com.orangeforms.gateway.filter.AuthenticationPostFilter;
|
||||
import com.orangeforms.gateway.filter.AuthenticationPreFilter;
|
||||
import com.orangeforms.gateway.filter.RequestLogFilter;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -19,8 +19,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
|
||||
@SpringCloudApplication
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
|
||||
public class GatewayApplication {
|
||||
|
||||
@RestController
|
||||
|
||||
@@ -22,10 +22,14 @@ public class CorsConfig {
|
||||
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(new PathPatternParser());
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
if (StringUtils.isNotBlank(appConfig.getCredentialIpList())) {
|
||||
String[] credentialIpList = StringUtils.split(appConfig.getCredentialIpList(), ",");
|
||||
if (credentialIpList.length > 0) {
|
||||
for (String ip : credentialIpList) {
|
||||
config.addAllowedOrigin(ip);
|
||||
if ("*".equals(appConfig.getCredentialIpList())) {
|
||||
config.addAllowedOriginPattern("*");
|
||||
} else {
|
||||
String[] credentialIpList = StringUtils.split(appConfig.getCredentialIpList(), ",");
|
||||
if (credentialIpList.length > 0) {
|
||||
for (String ip : credentialIpList) {
|
||||
config.addAllowedOrigin(ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
config.addAllowedHeader("*");
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package com.orangeforms.statsservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@@ -11,9 +12,9 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@SpringCloudApplication
|
||||
@EnableFeignClients(basePackages = "com.orangeforms")
|
||||
@ComponentScan("com.orangeforms")
|
||||
@EnableFeignClients(basePackages = "com.orangeforms")
|
||||
@SpringBootApplication
|
||||
public class StatsApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.orangeforms.upmsservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@@ -13,10 +13,10 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
|
||||
@SpringCloudApplication
|
||||
@EnableFeignClients(basePackages = "com.orangeforms")
|
||||
@ComponentScan("com.orangeforms")
|
||||
@EnableFeignClients(basePackages = "com.orangeforms")
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
|
||||
public class UpmsApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -26,7 +26,7 @@ public interface SysDeptRelationMapper extends BaseDaoMapper<SysDeptRelation> {
|
||||
/**
|
||||
* 批量插入部门关联数据。
|
||||
* 由于目前版本(3.4.1)的Mybatis Plus没有提供真正的批量插入,为了保证效率需要自己实现。
|
||||
* 目前我们仅仅给出MySQL的insert list实现作为参考,其他数据库需要自行修改。
|
||||
* 目前我们仅仅给出MySQL和PostgresSQL的insert list实现作为参考,其他数据库需要自行修改。
|
||||
*
|
||||
* @param deptRelationList 部门关联关系数据列表。
|
||||
*/
|
||||
|
||||
@@ -2,8 +2,8 @@ package com.orangeforms.common.core.base.client;
|
||||
|
||||
import com.orangeforms.common.core.constant.ErrorCodeEnum;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import feign.hystrix.FallbackFactory;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@ package com.orangeforms.common.core.base.controller;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.orangeforms.common.core.base.mapper.BaseModelMapper;
|
||||
import com.orangeforms.common.core.base.service.IBaseService;
|
||||
import com.orangeforms.common.core.config.CoreProperties;
|
||||
import com.orangeforms.common.core.constant.AggregationKind;
|
||||
import com.orangeforms.common.core.constant.AggregationType;
|
||||
import com.orangeforms.common.core.constant.ErrorCodeEnum;
|
||||
@@ -19,6 +21,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -42,6 +45,8 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
public abstract class BaseController<M, V, K extends Serializable> {
|
||||
|
||||
@Autowired
|
||||
private CoreProperties coreProperties;
|
||||
/**
|
||||
* 当前Service关联的主Model实体对象的Class。
|
||||
*/
|
||||
@@ -245,7 +250,42 @@ public abstract class BaseController<M, V, K extends Serializable> {
|
||||
}
|
||||
}
|
||||
M filter = queryParam.getFilterDto(modelClass);
|
||||
if (StrUtil.isNotBlank(queryParam.getInFilterField())
|
||||
&& CollUtil.isNotEmpty(queryParam.getInFilterValues())) {
|
||||
if (queryParam.getCriteriaList() == null) {
|
||||
queryParam.setCriteriaList(new LinkedList<>());
|
||||
}
|
||||
MyWhereCriteria whereCriteria = new MyWhereCriteria();
|
||||
whereCriteria.setFieldName(queryParam.getInFilterField());
|
||||
whereCriteria.setOperatorType(MyWhereCriteria.OPERATOR_IN);
|
||||
whereCriteria.setValue(queryParam.getInFilterValues());
|
||||
queryParam.getCriteriaList().add(whereCriteria);
|
||||
}
|
||||
String whereClause = MyWhereCriteria.makeCriteriaString(queryParam.getCriteriaList(), modelClass);
|
||||
if (CollUtil.isNotEmpty(queryParam.getSearchStringFieldList())
|
||||
&& StrUtil.isNotBlank(queryParam.getSearchStringValue())) {
|
||||
String tableName = MyModelUtil.mapToTableName(modelClass);
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
if (StrUtil.isNotBlank(whereClause)) {
|
||||
sb.append(" AND ");
|
||||
}
|
||||
sb.append(" CONCAT(");
|
||||
for (int i = 0; i < queryParam.getSearchStringFieldList().size(); i++) {
|
||||
String fieldName = queryParam.getSearchStringFieldList().get(i);
|
||||
String columnName = MyModelUtil.mapToColumnInfo(fieldName, modelClass).getFirst();
|
||||
if (coreProperties.isMySql()) {
|
||||
sb.append("IFNULL(");
|
||||
} else if (coreProperties.isPostgresql()) {
|
||||
sb.append("COALESCE(");
|
||||
}
|
||||
sb.append(tableName).append(".").append(columnName).append(", '')");
|
||||
if (i != queryParam.getSearchStringFieldList().size() - 1) {
|
||||
sb.append(", ");
|
||||
}
|
||||
}
|
||||
sb.append(") LIKE ").append("'").append(queryParam.getSearchStringValue()).append("'");
|
||||
whereClause = whereClause + sb.toString();
|
||||
}
|
||||
String orderBy = MyOrderParam.buildOrderBy(queryParam.getOrderParam(), modelClass);
|
||||
MyPageParam pageParam = queryParam.getPageParam();
|
||||
if (pageParam != null) {
|
||||
@@ -364,9 +404,9 @@ public abstract class BaseController<M, V, K extends Serializable> {
|
||||
for (Map.Entry<Object, Set<Object>> entry : param.getGroupedInFilterValues().entrySet()) {
|
||||
StringBuilder groupedSelectList = new StringBuilder(64);
|
||||
if (stringKey) {
|
||||
groupedSelectList.append("'").append(entry.getKey()).append("' ");
|
||||
groupedSelectList.append("'").append(entry.getKey()).append("' as ");
|
||||
} else {
|
||||
groupedSelectList.append(entry.getKey()).append(" ");
|
||||
groupedSelectList.append(entry.getKey()).append(" as ");
|
||||
}
|
||||
groupedSelectList.append(MyAggregationParam.KEY_NAME).append(", ").append(selectList);
|
||||
MyWhereCriteria criteria = new MyWhereCriteria();
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.orangeforms.common.core.object.TokenData;
|
||||
import com.orangeforms.common.core.util.ContextUtil;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -17,6 +18,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration
|
||||
public class FeignConfig implements RequestInterceptor {
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void apply(RequestTemplate requestTemplate) {
|
||||
// 对于非servlet请求发起的远程调用,由于无法获取到标识用户身份的TokenData,因此需要略过下面的HEADER注入。
|
||||
|
||||
@@ -19,13 +19,13 @@ public class MyAggregationParam {
|
||||
* 聚合返回数据中,聚合键的常量字段名。
|
||||
* 如select groupColumn groupedKey, max(aggregationColumn) aggregatedValue。
|
||||
*/
|
||||
public static final String KEY_NAME = "groupedKey";
|
||||
public static final String KEY_NAME = "grouped_key";
|
||||
|
||||
/**
|
||||
* 聚合返回数据中,聚合值的常量字段名。
|
||||
* 如select groupColumn groupedKey, max(aggregationColumn) aggregatedValue。
|
||||
*/
|
||||
public static final String VALUE_NAME = "aggregatedValue";
|
||||
public static final String VALUE_NAME = "aggregated_value";
|
||||
|
||||
/**
|
||||
* 聚合计算是否使用数据权限进行过滤。true表示数据过滤将产生作用,否则SQL中不会包含数据过滤。
|
||||
|
||||
@@ -61,6 +61,16 @@ public class MyQueryParam {
|
||||
*/
|
||||
private Boolean withDict = false;
|
||||
|
||||
/**
|
||||
* 参与模糊搜索的Java字段列表。
|
||||
*/
|
||||
private List<String> searchStringFieldList;
|
||||
|
||||
/**
|
||||
* 模糊搜索的字符串值,该值要包含百分号,这样可以精确控制搜索参数中百分号的配置。
|
||||
*/
|
||||
private String searchStringValue;
|
||||
|
||||
/**
|
||||
* 缺省构造函数。
|
||||
*/
|
||||
|
||||
@@ -43,6 +43,12 @@ public class MyDateUtil {
|
||||
private static final DateTimeFormatter DATETIME_PARSE_FORMATTER =
|
||||
DateTimeFormat.forPattern(MyDateUtil.COMMON_DATETIME_FORMAT);
|
||||
|
||||
/**
|
||||
* 缺省短日期时间格式化器,提前获取提升运行时效率。
|
||||
*/
|
||||
private static final DateTimeFormatter DATETIME_SHORT_PARSE_FORMATTER =
|
||||
DateTimeFormat.forPattern(MyDateUtil.COMMON_SHORT_DATETIME_FORMAT);
|
||||
|
||||
/**
|
||||
* 获取一天的开始时间的字符串格式,如2019-08-03 00:00:00.000。
|
||||
*
|
||||
@@ -144,6 +150,16 @@ public class MyDateUtil {
|
||||
return DATETIME_PARSE_FORMATTER.parseDateTime(dateTimeString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将缺省格式的(不包含毫秒的)日期时间字符串解析为日期对象。
|
||||
*
|
||||
* @param dateTimeString 待解析的字符串。
|
||||
* @return 解析后的日期对象。
|
||||
*/
|
||||
public static DateTime toDateTimeWithoutMs(String dateTimeString) {
|
||||
return DATETIME_SHORT_PARSE_FORMATTER.parseDateTime(dateTimeString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 截取时间到天。如2019-10-03 01:20:30 转换为 2019-10-03 00:00:00。
|
||||
* 由于没有字符串的中间转换,因此效率更高。
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<result column="request_arguments" jdbcType="VARCHAR" property="requestArguments"/>
|
||||
<result column="response_result" jdbcType="VARCHAR" property="responseResult"/>
|
||||
<result column="request_ip" jdbcType="VARCHAR" property="requestIp"/>
|
||||
<result column="success" jdbcType="BIT" property="success"/>
|
||||
<result column="success" jdbcType="BOOLEAN" property="success"/>
|
||||
<result column="error_msg" jdbcType="VARCHAR" property="errorMsg"/>
|
||||
<result column="tenant_id" jdbcType="BIGINT" property="tenantId"/>
|
||||
<result column="operator_id" jdbcType="BIGINT" property="operatorId"/>
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
|
||||
<spring-cloud-alibaba.version>2.2.5.RELEASE</spring-cloud-alibaba.version>
|
||||
<spring-boot.version>2.3.10.RELEASE</spring-boot.version>
|
||||
<spring-boot-admin.version>2.3.1</spring-boot-admin.version>
|
||||
<spring-cloud.version>2020.0.4</spring-cloud.version>
|
||||
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
|
||||
<spring-boot.version>2.5.8</spring-boot.version>
|
||||
<spring-boot-admin.version>2.5.5</spring-boot-admin.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
@@ -59,6 +59,10 @@
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||
</dependency>
|
||||
<!-- freemarker 模板引擎模块 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -180,14 +184,9 @@
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-httpclient</artifactId>
|
||||
</dependency>
|
||||
<!--断路器依赖-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
|
||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
<!-- api参数验证 -->
|
||||
<dependency>
|
||||
|
||||
@@ -42,7 +42,7 @@ spring:
|
||||
|
||||
# feign 配置
|
||||
feign:
|
||||
hystrix:
|
||||
sentinel:
|
||||
enabled: true
|
||||
httpclient:
|
||||
enabled: true
|
||||
@@ -66,22 +66,9 @@ feign:
|
||||
response:
|
||||
enabled: true
|
||||
|
||||
hystrix:
|
||||
command:
|
||||
default:
|
||||
execution:
|
||||
isolation:
|
||||
strategy: SEMAPHORE
|
||||
thread:
|
||||
timeoutInMilliseconds: 30000
|
||||
shareSecurityContext: true
|
||||
|
||||
#请求处理的超时时间
|
||||
ribbon:
|
||||
ReadTimeout: 7000
|
||||
ConnectTimeout: 3000
|
||||
MaxAutoRetries: 1
|
||||
MaxAutoRetriesNextServer: 1
|
||||
common-core:
|
||||
# 可选值为 mysql / postgresql
|
||||
databaseType: mysql
|
||||
|
||||
swagger:
|
||||
# 当enabled为false的时候,则可禁用swagger。
|
||||
@@ -116,8 +103,7 @@ management:
|
||||
# keys-to-sanitize:
|
||||
keys-to-sanitize: password
|
||||
server:
|
||||
servlet:
|
||||
context-path: "/"
|
||||
base-path: "/"
|
||||
|
||||
# 存储session数据的Redis,所有服务均需要,因此放到公共配置中。
|
||||
# 根据实际情况,该Redis也可以用于存储其他数据。
|
||||
|
||||
@@ -33,27 +33,15 @@ spring:
|
||||
- Path=/admin/upms/**
|
||||
filters:
|
||||
- StripPrefix=2
|
||||
- name: Hystrix
|
||||
args:
|
||||
name: default
|
||||
fallbackUri: forward:/fallback
|
||||
- id: course-class
|
||||
uri: lb://course-class
|
||||
predicates:
|
||||
- Path=/admin/CourseClass/**
|
||||
filters:
|
||||
- StripPrefix=2
|
||||
- name: Hystrix
|
||||
args:
|
||||
name: default
|
||||
fallbackUri: forward:/fallback
|
||||
- id: stats
|
||||
uri: lb://stats
|
||||
predicates:
|
||||
- Path=/admin/stats/**
|
||||
filters:
|
||||
- StripPrefix=2
|
||||
- name: Hystrix
|
||||
args:
|
||||
name: default
|
||||
fallbackUri: forward:/fallback
|
||||
|
||||
@@ -11,19 +11,6 @@
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO `zz_data_sync_producer_update_mark` VALUES (1,0,CURDATE());
|
||||
COMMIT;
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- 管理员账号数据
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `zz_sys_dept` VALUES(1293376634891538435,NULL,'公司总部',1,1293376634887344128,CURDATE(),1293376634887344128,CURDATE(),1);
|
||||
INSERT INTO `zz_sys_user` VALUES(1293376634887344128,'admin','$2a$10$vBEU0Zgx2X0crltvKEoxnOWF3O1eKIuVI9EJngv/dn5BGKMi6SH3.','管理员',1293376634891538435,NULL,0,0,1293376634887344128,CURDATE(),1293376634887344128,CURDATE(),1);
|
||||
INSERT INTO `zz_sys_dept_relation` VALUES(1293376634891538435,1293376634891538435);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- 全部菜单数据
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
DELETE FROM `zz_data_sync_producer_update_mark` WHERE id = 1;
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- 全部菜单数据
|
||||
-- ----------------------------
|
||||
|
||||
@@ -315,4 +315,17 @@ CREATE TABLE `zz_data_sync_producer_update_mark` (
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='数据同步生产者消息流水表的高水标记表';
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO `zz_data_sync_producer_update_mark` VALUES (1,0,CURDATE());
|
||||
COMMIT;
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- 管理员账号数据
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `zz_sys_dept` VALUES(1293376634891538435,NULL,'公司总部',1,1293376634887344128,CURDATE(),1293376634887344128,CURDATE(),1);
|
||||
INSERT INTO `zz_sys_user` VALUES(1293376634887344128,'admin','$2a$10$CDcvRR6vbruoSPkiorYaEueAwdLKNhBfPdj0dypAHot21SWDlFx8m','管理员',1293376634891538435,NULL,0,0,1293376634887344128,CURDATE(),1293376634887344128,CURDATE(),1);
|
||||
INSERT INTO `zz_sys_dept_relation` VALUES(1293376634891538435,1293376634891538435);
|
||||
COMMIT;
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="上级菜单">
|
||||
<el-cascader :options="menuTree" v-model="parentMenuPath" :props="menuProps" placeholder="选择父菜单"
|
||||
:disabled="!canEditParent || isEdit" :clearable="true" :change-on-select="true" :size="defaultFormItemSize"
|
||||
:clearable="true" :change-on-select="true" :size="defaultFormItemSize"
|
||||
@change="onParentMenuChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -143,12 +143,13 @@ export default {
|
||||
}
|
||||
},
|
||||
onParentMenuChange (value, isInit) {
|
||||
if (!isInit) this.formData.menuType = undefined;
|
||||
this.parentMenuType = undefined;
|
||||
if (Array.isArray(value) && value.length > 0) {
|
||||
let node = findTreeNode(this.menuTree, value[value.length - 1], 'menuId');
|
||||
if (node) this.parentMenuType = node.menuType;
|
||||
}
|
||||
// 父菜单切换后判断可用菜单类型是否改变,如果改变则清空
|
||||
if (!isInit && this.getValidMenuType.map(item => item.id).indexOf(this.formData.menuType) === -1) this.formData.menuType = undefined;
|
||||
},
|
||||
onCancel (isSuccess) {
|
||||
if (this.observer != null) {
|
||||
|
||||
26
orange-demo-single-pg/orange-demo-single-pg-service/.gitignore
vendored
Normal file
26
orange-demo-single-pg/orange-demo-single-pg-service/.gitignore
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
/.mvn/*
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/build/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
@@ -0,0 +1,17 @@
|
||||
### 服务接口文档
|
||||
---
|
||||
- Knife4j
|
||||
- 服务启动后,Knife4j的文档入口地址 [http://localhost:8082/doc.html#/plus](http://localhost:8082/doc.html#/plus)
|
||||
- Postman
|
||||
- 无需启动服务,即可将当前工程的接口导出成Postman格式。在工程的common/common-tools/模块下,找到ExportApiApp文件,并执行main函数。
|
||||
|
||||
### 服务启动环境依赖
|
||||
---
|
||||
|
||||
执行docker-compose up -d 命令启动下面依赖的服务。
|
||||
执行docker-compose down 命令停止下面服务。
|
||||
|
||||
- Redis
|
||||
- 版本:4
|
||||
- 端口: 6379
|
||||
- 推荐客户端工具 [AnotherRedisDesktopManager](https://github.com/qishibo/AnotherRedisDesktopManager)
|
||||
@@ -0,0 +1,93 @@
|
||||
<?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">
|
||||
<parent>
|
||||
<groupId>com.orangeforms</groupId>
|
||||
<artifactId>DemoSinglePg</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>application-webadmin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<name>application</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.anji-plus</groupId>
|
||||
<artifactId>spring-boot-starter-captcha</artifactId>
|
||||
<version>${ajcaptcha.version}</version>
|
||||
</dependency>
|
||||
<!-- aj-captcha 依赖data-redis作为缓存 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- 业务组件依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.orangeforms</groupId>
|
||||
<artifactId>common-redis</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.orangeforms</groupId>
|
||||
<artifactId>common-log</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.orangeforms</groupId>
|
||||
<artifactId>common-sequence</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.orangeforms</groupId>
|
||||
<artifactId>common-datafilter</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.orangeforms</groupId>
|
||||
<artifactId>common-swagger</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*.*</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*.xml</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.orangeforms.webadmin;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
/**
|
||||
* 应用服务启动类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2022-02-20
|
||||
*/
|
||||
@EnableAsync
|
||||
@SpringBootApplication
|
||||
@ComponentScan("com.orangeforms")
|
||||
public class WebAdminApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(WebAdminApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.orangeforms.webadmin.app.util;
|
||||
|
||||
import com.anji.captcha.service.CaptchaCacheService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 对于分布式部署的应用,我们建议应用自己实现CaptchaCacheService,比如用Redis,参考service/spring-boot代码示例。
|
||||
* 如果应用是单点的,也没有使用redis,那默认使用内存。
|
||||
* 内存缓存只适合单节点部署的应用,否则验证码生产与验证在节点之间信息不同步,导致失败。
|
||||
*
|
||||
* ☆☆☆ SPI: 在resources目录新建META-INF.services文件夹(两层),参考当前服务resources。
|
||||
* @author lide1202@hotmail.com
|
||||
* @date 2020-05-12
|
||||
*/
|
||||
public class CaptchaCacheServiceRedisImpl implements CaptchaCacheService {
|
||||
|
||||
@Override
|
||||
public String type() {
|
||||
return "redis";
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Override
|
||||
public void set(String key, String value, long expiresInSeconds) {
|
||||
stringRedisTemplate.opsForValue().set(key, value, expiresInSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(String key) {
|
||||
return stringRedisTemplate.hasKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String key) {
|
||||
stringRedisTemplate.delete(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(String key) {
|
||||
return stringRedisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long increment(String key, long val) {
|
||||
return stringRedisTemplate.opsForValue().increment(key,val);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.orangeforms.webadmin.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 应用程序自定义的程序属性配置文件。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2022-02-20
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "application")
|
||||
public class ApplicationConfig {
|
||||
|
||||
/**
|
||||
* token的Http Request Header的key
|
||||
*/
|
||||
private String tokenHeaderKey;
|
||||
/**
|
||||
* token在过期之前,但是已经需要被刷新时,response返回的header信息的key。
|
||||
*/
|
||||
private String refreshedTokenHeaderKey;
|
||||
/**
|
||||
* token 加密用的密钥,该值的长度最少10个字符(过短会报错)。
|
||||
*/
|
||||
private String tokenSigningKey;
|
||||
/**
|
||||
* 令牌的过期时间,单位毫秒
|
||||
*/
|
||||
private Long expiration;
|
||||
/**
|
||||
* 用户密码被重置之后的缺省密码
|
||||
*/
|
||||
private String defaultUserPassword;
|
||||
/**
|
||||
* 上传文件的基础目录
|
||||
*/
|
||||
private String uploadFileBaseDir;
|
||||
/**
|
||||
* 授信ip列表,没有填写表示全部信任。多个ip之间逗号分隔,如: http://10.10.10.1:8080,http://10.10.10.2:8080
|
||||
*/
|
||||
private String credentialIpList;
|
||||
/**
|
||||
* Session的用户权限在Redis中的过期时间(秒)。
|
||||
* 缺省值是 one day
|
||||
*/
|
||||
private int sessionExpiredSeconds = 86400;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.orangeforms.webadmin.config;
|
||||
|
||||
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* 数据源配置Bean对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2022-02-20
|
||||
*/
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
@MapperScan(value = {"com.orangeforms.webadmin.*.dao", "com.orangeforms.common.*.dao"})
|
||||
public class DataSourceConfig {
|
||||
|
||||
@Bean(initMethod = "init", destroyMethod = "close")
|
||||
@Primary
|
||||
@ConfigurationProperties(prefix = "spring.datasource.druid")
|
||||
public DataSource druidDataSource() {
|
||||
return DruidDataSourceBuilder.create().build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.orangeforms.webadmin.config;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 这里主要配置Web的各种过滤器和监听器等Servlet容器组件。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2022-02-20
|
||||
*/
|
||||
@Configuration
|
||||
public class FilterConfig {
|
||||
|
||||
/**
|
||||
* 配置Ajax跨域过滤器。
|
||||
*/
|
||||
@Bean
|
||||
public CorsFilter corsFilterRegistration(ApplicationConfig applicationConfig) {
|
||||
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
|
||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
if (StringUtils.isNotBlank(applicationConfig.getCredentialIpList())) {
|
||||
if ("*".equals(applicationConfig.getCredentialIpList())) {
|
||||
corsConfiguration.addAllowedOriginPattern("*");
|
||||
} else {
|
||||
String[] credentialIpList = StringUtils.split(applicationConfig.getCredentialIpList(), ",");
|
||||
if (credentialIpList.length > 0) {
|
||||
for (String ip : credentialIpList) {
|
||||
corsConfiguration.addAllowedOrigin(ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
corsConfiguration.addAllowedHeader("*");
|
||||
corsConfiguration.addAllowedMethod("*");
|
||||
corsConfiguration.addExposedHeader(applicationConfig.getRefreshedTokenHeaderKey());
|
||||
corsConfiguration.setAllowCredentials(true);
|
||||
configSource.registerCorsConfiguration("/**", corsConfiguration);
|
||||
}
|
||||
return new CorsFilter(configSource);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<Filter> characterEncodingFilterRegistration() {
|
||||
FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>(
|
||||
new org.springframework.web.filter.CharacterEncodingFilter());
|
||||
filterRegistrationBean.addUrlPatterns("/*");
|
||||
filterRegistrationBean.addInitParameter("encoding", StandardCharsets.UTF_8.name());
|
||||
// forceEncoding强制response也被编码,另外即使request中已经设置encoding,forceEncoding也会重新设置
|
||||
filterRegistrationBean.addInitParameter("forceEncoding", "true");
|
||||
filterRegistrationBean.setAsyncSupported(true);
|
||||
return filterRegistrationBean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.orangeforms.webadmin.config;
|
||||
|
||||
import com.orangeforms.webadmin.interceptor.AuthenticationInterceptor;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* 所有的项目拦截器都在这里集中配置
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2022-02-20
|
||||
*/
|
||||
@Configuration
|
||||
public class InterceptorConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new AuthenticationInterceptor()).addPathPatterns("/admin/**");
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user