parent
da5ace3397
commit
c5965b10d8
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,28 +0,0 @@
|
|||||||
INSERT INTO SYS_DICT_ITEM(ID, DICT_ID, ITEM_TEXT, ITEM_VALUE, DESCRIPTION, SORT_ORDER, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME) VALUES ('1334440962954936321', '1209733563293962241', 'MYSQL5.7', '4', NULL, '1', '1', 'admin', '2020-12-03 18:16:02', 'admin', '2020-12-03 18:16:02');
|
|
||||||
UPDATE SYS_DICT_ITEM SET ITEM_TEXT = 'MySQL5.5' WHERE ID = '1209733775114702850';
|
|
||||||
UPDATE SYS_DICT_ITEM SET SORT_ORDER = '3' WHERE ID = '1209733839933476865';
|
|
||||||
UPDATE SYS_DICT_ITEM SET SORT_ORDER = '4' WHERE ID = '1209733903020003330';
|
|
||||||
|
|
||||||
ALTER TABLE `sys_gateway_route`
|
|
||||||
CHANGE COLUMN `persist` `persistable` int(3) NULL DEFAULT NULL COMMENT '是否为保留数据:0-否 1-是' AFTER `strip_prefix`;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `test_online_link`;
|
|
||||||
CREATE TABLE `test_online_link` (
|
|
||||||
`id` varchar(32) NOT NULL,
|
|
||||||
`pid` varchar(32) DEFAULT NULL COMMENT 'pid',
|
|
||||||
`name` varchar(255) DEFAULT NULL COMMENT 'name',
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
||||||
INSERT INTO `test_online_link` VALUES ('1', NULL, '中国');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('10', '8', '庐阳区');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('11', '7', '黄山市');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('2', '1', '山东省');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('3', '2', '济南市');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('4', '3', '历城区');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('5', '3', '长青区');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('6', '2', '青岛市');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('7', '1', '安徽省');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('8', '7', '合肥市');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('9', '8', '包河区');
|
|
||||||
|
|
||||||
update ONL_CGFORM_FIELD set DB_TYPE = 'Date' WHERE DB_TYPE = 'date';
|
|
||||||
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
|||||||
package org.jeecg.boot.starter.redis.listener;
|
package org.jeecg.common.modules.redis.listener;
|
||||||
|
|
||||||
import org.jeecg.common.base.BaseMap;
|
import org.jeecg.common.base.BaseMap;
|
||||||
|
|
||||||
@ -1,16 +1,17 @@
|
|||||||
package org.jeecg.boot.starter.redis.service;
|
package org.jeecg.common.modules.redis.receiver;
|
||||||
|
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.jeecg.boot.starter.redis.listener.JeecgRedisListerer;
|
|
||||||
import org.jeecg.common.base.BaseMap;
|
import org.jeecg.common.base.BaseMap;
|
||||||
import org.jeecg.common.constant.GlobalConstants;
|
import org.jeecg.common.constant.GlobalConstants;
|
||||||
|
import org.jeecg.common.modules.redis.listener.JeecgRedisListerer;
|
||||||
import org.jeecg.common.util.SpringContextHolder;
|
import org.jeecg.common.util.SpringContextHolder;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.Map;
|
/**
|
||||||
|
* @author zyf
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Data
|
@Data
|
||||||
public class RedisReceiver {
|
public class RedisReceiver {
|
||||||
@ -0,0 +1,221 @@
|
|||||||
|
package org.jeecg.common.modules.redis.writer;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.dao.PessimisticLockingFailureException;
|
||||||
|
import org.springframework.data.redis.cache.RedisCacheWriter;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnection;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
|
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
|
||||||
|
import org.springframework.data.redis.core.types.Expiration;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 该类参照 DefaultRedisCacheWriter 重写了 remove 方法实现通配符*删除
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class JeecgRedisCacheWriter implements RedisCacheWriter {
|
||||||
|
|
||||||
|
private final RedisConnectionFactory connectionFactory;
|
||||||
|
private final Duration sleepTime;
|
||||||
|
|
||||||
|
public JeecgRedisCacheWriter(RedisConnectionFactory connectionFactory) {
|
||||||
|
this(connectionFactory, Duration.ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JeecgRedisCacheWriter(RedisConnectionFactory connectionFactory, Duration sleepTime) {
|
||||||
|
Assert.notNull(connectionFactory, "ConnectionFactory must not be null!");
|
||||||
|
Assert.notNull(sleepTime, "SleepTime must not be null!");
|
||||||
|
this.connectionFactory = connectionFactory;
|
||||||
|
this.sleepTime = sleepTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(String name, byte[] key, byte[] value, @Nullable Duration ttl) {
|
||||||
|
Assert.notNull(name, "Name must not be null!");
|
||||||
|
Assert.notNull(key, "Key must not be null!");
|
||||||
|
Assert.notNull(value, "Value must not be null!");
|
||||||
|
this.execute(name, (connection) -> {
|
||||||
|
if (shouldExpireWithin(ttl)) {
|
||||||
|
connection.set(key, value, Expiration.from(ttl.toMillis(), TimeUnit.MILLISECONDS), SetOption.upsert());
|
||||||
|
} else {
|
||||||
|
connection.set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "OK";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] get(String name, byte[] key) {
|
||||||
|
Assert.notNull(name, "Name must not be null!");
|
||||||
|
Assert.notNull(key, "Key must not be null!");
|
||||||
|
return (byte[])this.execute(name, (connection) -> {
|
||||||
|
return connection.get(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] putIfAbsent(String name, byte[] key, byte[] value, @Nullable Duration ttl) {
|
||||||
|
Assert.notNull(name, "Name must not be null!");
|
||||||
|
Assert.notNull(key, "Key must not be null!");
|
||||||
|
Assert.notNull(value, "Value must not be null!");
|
||||||
|
return (byte[])this.execute(name, (connection) -> {
|
||||||
|
if (this.isLockingCacheWriter()) {
|
||||||
|
this.doLock(name, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object var7;
|
||||||
|
try {
|
||||||
|
boolean put;
|
||||||
|
if (shouldExpireWithin(ttl)) {
|
||||||
|
put = connection.set(key, value, Expiration.from(ttl), SetOption.ifAbsent());
|
||||||
|
} else {
|
||||||
|
put = connection.setNX(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!put) {
|
||||||
|
byte[] var11 = connection.get(key);
|
||||||
|
return var11;
|
||||||
|
}
|
||||||
|
|
||||||
|
var7 = null;
|
||||||
|
} finally {
|
||||||
|
if (this.isLockingCacheWriter()) {
|
||||||
|
this.doUnlock(name, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return (byte[])var7;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(String name, byte[] key) {
|
||||||
|
Assert.notNull(name, "Name must not be null!");
|
||||||
|
Assert.notNull(key, "Key must not be null!");
|
||||||
|
String keyString = new String(key);
|
||||||
|
log.info("redis remove key:" + keyString);
|
||||||
|
if(keyString!=null && keyString.endsWith("*")){
|
||||||
|
execute(name, connection -> {
|
||||||
|
// 获取某个前缀所拥有的所有的键,某个前缀开头,后面肯定是*
|
||||||
|
Set<byte[]> keys = connection.keys(key);
|
||||||
|
int delNum = 0;
|
||||||
|
for (byte[] keyByte : keys) {
|
||||||
|
delNum += connection.del(keyByte);
|
||||||
|
}
|
||||||
|
return delNum;
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
this.execute(name, (connection) -> {
|
||||||
|
return connection.del(new byte[][]{key});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clean(String name, byte[] pattern) {
|
||||||
|
Assert.notNull(name, "Name must not be null!");
|
||||||
|
Assert.notNull(pattern, "Pattern must not be null!");
|
||||||
|
this.execute(name, (connection) -> {
|
||||||
|
boolean wasLocked = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (this.isLockingCacheWriter()) {
|
||||||
|
this.doLock(name, connection);
|
||||||
|
wasLocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[][] keys = (byte[][])((Set)Optional.ofNullable(connection.keys(pattern)).orElse(Collections.emptySet())).toArray(new byte[0][]);
|
||||||
|
if (keys.length > 0) {
|
||||||
|
connection.del(keys);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (wasLocked && this.isLockingCacheWriter()) {
|
||||||
|
this.doUnlock(name, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return "OK";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void lock(String name) {
|
||||||
|
this.execute(name, (connection) -> {
|
||||||
|
return this.doLock(name, connection);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock(String name) {
|
||||||
|
this.executeLockFree((connection) -> {
|
||||||
|
this.doUnlock(name, connection);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean doLock(String name, RedisConnection connection) {
|
||||||
|
return connection.setNX(createCacheLockKey(name), new byte[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long doUnlock(String name, RedisConnection connection) {
|
||||||
|
return connection.del(new byte[][]{createCacheLockKey(name)});
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean doCheckLock(String name, RedisConnection connection) {
|
||||||
|
return connection.exists(createCacheLockKey(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLockingCacheWriter() {
|
||||||
|
return !this.sleepTime.isZero() && !this.sleepTime.isNegative();
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T execute(String name, Function<RedisConnection, T> callback) {
|
||||||
|
RedisConnection connection = this.connectionFactory.getConnection();
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.checkAndPotentiallyWaitUntilUnlocked(name, connection);
|
||||||
|
return callback.apply(connection);
|
||||||
|
} finally {
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeLockFree(Consumer<RedisConnection> callback) {
|
||||||
|
RedisConnection connection = this.connectionFactory.getConnection();
|
||||||
|
|
||||||
|
try {
|
||||||
|
callback.accept(connection);
|
||||||
|
} finally {
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAndPotentiallyWaitUntilUnlocked(String name, RedisConnection connection) {
|
||||||
|
if (this.isLockingCacheWriter()) {
|
||||||
|
try {
|
||||||
|
while(this.doCheckLock(name, connection)) {
|
||||||
|
Thread.sleep(this.sleepTime.toMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (InterruptedException var4) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new PessimisticLockingFailureException(String.format("Interrupted while waiting to unlock cache %s", name), var4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean shouldExpireWithin(@Nullable Duration ttl) {
|
||||||
|
return ttl != null && !ttl.isZero() && !ttl.isNegative();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] createCacheLockKey(String name) {
|
||||||
|
return (name + "~lock").getBytes(StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
//package org.jeecg.modules.demo.xxljob;
|
||||||
|
//
|
||||||
|
//import com.xxl.job.core.biz.model.ReturnT;
|
||||||
|
//import com.xxl.job.core.handler.annotation.XxlJob;
|
||||||
|
//import lombok.extern.slf4j.Slf4j;
|
||||||
|
//import org.springframework.stereotype.Component;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
///**
|
||||||
|
// * xxl-job定时任务测试
|
||||||
|
// */
|
||||||
|
//@Component
|
||||||
|
//@Slf4j
|
||||||
|
//public class TestJobHandler {
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 简单任务
|
||||||
|
// *
|
||||||
|
// * @param params
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
//
|
||||||
|
// @XxlJob(value = "testJob")
|
||||||
|
// public ReturnT<String> demoJobHandler(String params) {
|
||||||
|
// log.info("我是demo服务里的定时任务testJob,我执行了...............................");
|
||||||
|
// return ReturnT.SUCCESS;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void init() {
|
||||||
|
// log.info("init");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void destroy() {
|
||||||
|
// log.info("destory");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
//
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
<#list columns as po>
|
||||||
|
<#if po.isShow == 'Y'>
|
||||||
|
<#if po.fieldName != 'id'>
|
||||||
|
<#if po.defaultVal??>
|
||||||
|
<#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int">
|
||||||
|
${po.fieldName}:${po.defaultVal},
|
||||||
|
<#else>
|
||||||
|
${po.fieldName}:"${po.defaultVal}",
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
<#list sub.colums as po>
|
||||||
|
<#if po.isShow == 'Y'>
|
||||||
|
<#if po.fieldName != 'id'>
|
||||||
|
<#if po.defaultVal??>
|
||||||
|
<#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int">
|
||||||
|
${po.fieldName}:${po.defaultVal},
|
||||||
|
<#else>
|
||||||
|
${po.fieldName}:"${po.defaultVal}",
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
@ -1,66 +1,57 @@
|
|||||||
<#include "../utils.ftl">
|
<#include "../utils.ftl">
|
||||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||||
<#if po.fieldName != 'id'>
|
<#if po.fieldName != 'id'>
|
||||||
${po.fieldName}: {
|
${po.fieldName}: [
|
||||||
<#if po.defaultVal??>
|
<#assign fieldValidType = po.fieldValidType!''>
|
||||||
<#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int">
|
|
||||||
initialValue:${po.defaultVal},
|
|
||||||
<#else>
|
|
||||||
initialValue:"${po.defaultVal}",
|
|
||||||
</#if>
|
|
||||||
</#if>
|
|
||||||
rules: [
|
|
||||||
<#assign fieldValidType = po.fieldValidType!''>
|
|
||||||
<#-- 非空校验 -->
|
<#-- 非空校验 -->
|
||||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||||
{ required: true, message: '请输入${po.filedComment}!'},
|
{ required: true, message: '请输入${po.filedComment}!'},
|
||||||
<#elseif fieldValidType!=''>
|
<#elseif fieldValidType!=''>
|
||||||
{ required: false},
|
{ required: false},
|
||||||
</#if>
|
</#if>
|
||||||
<#-- 唯一校验 -->
|
<#-- 唯一校验 -->
|
||||||
<#if fieldValidType == 'only'>
|
<#if fieldValidType == 'only'>
|
||||||
{ validator: (rule, value, callback) => validateDuplicateValue(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}', value, this.model.id, callback)},
|
{ validator: (rule, value, callback) => validateDuplicateValue(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}', value, this.model.id, callback)},
|
||||||
<#-- 6到16位数字 -->
|
<#-- 6到16位数字 -->
|
||||||
<#elseif fieldValidType == 'n6-16'>
|
<#elseif fieldValidType == 'n6-16'>
|
||||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||||
<#-- 6到16位任意字符 -->
|
<#-- 6到16位任意字符 -->
|
||||||
<#elseif fieldValidType == '*6-16'>
|
<#elseif fieldValidType == '*6-16'>
|
||||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||||
<#-- 6到18位字符串 -->
|
<#-- 6到18位字符串 -->
|
||||||
<#elseif fieldValidType == 's6-18'>
|
<#elseif fieldValidType == 's6-18'>
|
||||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||||
<#-- 网址 -->
|
<#-- 网址 -->
|
||||||
<#elseif fieldValidType == 'url'>
|
<#elseif fieldValidType == 'url'>
|
||||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||||
<#-- 电子邮件 -->
|
<#-- 电子邮件 -->
|
||||||
<#elseif fieldValidType == 'e'>
|
<#elseif fieldValidType == 'e'>
|
||||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||||
<#-- 手机号码 -->
|
<#-- 手机号码 -->
|
||||||
<#elseif fieldValidType == 'm'>
|
<#elseif fieldValidType == 'm'>
|
||||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||||
<#-- 邮政编码 -->
|
<#-- 邮政编码 -->
|
||||||
<#elseif fieldValidType == 'p'>
|
<#elseif fieldValidType == 'p'>
|
||||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||||
<#-- 字母 -->
|
<#-- 字母 -->
|
||||||
<#elseif fieldValidType == 's'>
|
<#elseif fieldValidType == 's'>
|
||||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||||
<#-- 数字 -->
|
<#-- 数字 -->
|
||||||
<#elseif fieldValidType == 'n'>
|
<#elseif fieldValidType == 'n'>
|
||||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||||
<#-- 整数 -->
|
<#-- 整数 -->
|
||||||
<#elseif fieldValidType == 'z'>
|
<#elseif fieldValidType == 'z'>
|
||||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||||
<#-- 金额 -->
|
<#-- 金额 -->
|
||||||
<#elseif fieldValidType == 'money'>
|
<#elseif fieldValidType == 'money'>
|
||||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||||
<#-- 正则校验 -->
|
<#-- 正则校验 -->
|
||||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||||
<#-- 无校验 -->
|
<#-- 无校验 -->
|
||||||
<#else>
|
<#else>
|
||||||
<#t>
|
<#t>
|
||||||
|
</#if>
|
||||||
|
],
|
||||||
</#if>
|
</#if>
|
||||||
]
|
|
||||||
},
|
|
||||||
</#if>
|
|
||||||
</#if>
|
</#if>
|
||||||
@ -0,0 +1,146 @@
|
|||||||
|
<template>
|
||||||
|
<a-spin :spinning="confirmLoading">
|
||||||
|
<!-- 主表单区域 -->
|
||||||
|
<a-form-model ref="form" :model="model" :rules="validatorRules">
|
||||||
|
<#list columns as po><#rt/>
|
||||||
|
<#if po_index % 2 == 0 ><#rt/>
|
||||||
|
<a-row>
|
||||||
|
<#if po.fieldName !='id'>
|
||||||
|
<#list [po_index, po_index+1] as idx><#rt/>
|
||||||
|
<#if idx lt columns?size>
|
||||||
|
<a-col :xs="24" :sm="12">
|
||||||
|
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="${columns[idx].fieldName}" label="${columns[idx].filedComment}">
|
||||||
|
<#if columns[idx].fieldType =='date'>
|
||||||
|
<a-date-picker placeholder="请输入${columns[idx].filedComment}" style="width:100%" v-model="model.${columns[idx].fieldName}"/>
|
||||||
|
<#elseif columns[idx].fieldType =='datetime'>
|
||||||
|
<a-date-picker placeholder="请输入${columns[idx].filedComment}" style="width:100%" :showTime="true" valueFormat="YYYY-MM-DD HH:mm:ss" v-model="model.${columns[idx].fieldName}"/>
|
||||||
|
<#elseif "int,decimal,double,"?contains(columns[idx].fieldType)>
|
||||||
|
<a-input-number placeholder="请输入${columns[idx].filedComment}" style="width:100%" v-model="model.${columns[idx].fieldName}"/>
|
||||||
|
<#else>
|
||||||
|
<a-input placeholder="请输入${columns[idx].filedComment}" v-model="model.${columns[idx].fieldName}"/>
|
||||||
|
</#if>
|
||||||
|
</a-form-model-item>
|
||||||
|
</a-col>
|
||||||
|
</#if>
|
||||||
|
</#list><#rt/>
|
||||||
|
</#if><#rt/>
|
||||||
|
</a-row>
|
||||||
|
</#if><#rt/>
|
||||||
|
</#list>
|
||||||
|
</a-form-model>
|
||||||
|
|
||||||
|
<!-- 子表单区域 -->
|
||||||
|
<a-tabs v-model="activeKey" @change="handleChangeTabs">
|
||||||
|
<#list subTables as sub><#rt/>
|
||||||
|
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index}]" :forceRender="true">
|
||||||
|
<j-editable-table
|
||||||
|
:ref="refKeys[${sub_index}]"
|
||||||
|
:loading="${sub.entityName?uncap_first}Table.loading"
|
||||||
|
:columns="${sub.entityName?uncap_first}Table.columns"
|
||||||
|
:dataSource="${sub.entityName?uncap_first}Table.dataSource"
|
||||||
|
:maxHeight="300"
|
||||||
|
:rowNumber="true"
|
||||||
|
:rowSelection="true"
|
||||||
|
:actionButton="true"/>
|
||||||
|
</a-tab-pane>
|
||||||
|
</#list>
|
||||||
|
</a-tabs>
|
||||||
|
</a-spin>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||||
|
import { JEditableTableModelMixin } from '@/mixins/JEditableTableModelMixin'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: '${entityName}Form',
|
||||||
|
mixins: [JEditableTableModelMixin],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 新增时子表默认添加几行空数据
|
||||||
|
addDefaultRowNum: 1,
|
||||||
|
model: {
|
||||||
|
//设置默认值
|
||||||
|
},
|
||||||
|
validatorRules: {
|
||||||
|
<#list columns as po>
|
||||||
|
<#if po.fieldName !='id'>
|
||||||
|
<#if po.nullable =='N'>
|
||||||
|
${po.fieldName}: [{ required: true, message: '请输入${po.filedComment}!' }],
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
},
|
||||||
|
refKeys: [<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>],
|
||||||
|
activeKey: '${subTables[0].entityName?uncap_first}',
|
||||||
|
<#list subTables as sub><#rt/>
|
||||||
|
// ${sub.ftlDescription}
|
||||||
|
${sub.entityName?uncap_first}Table: {
|
||||||
|
loading: false,
|
||||||
|
dataSource: [],
|
||||||
|
columns: [
|
||||||
|
<#list sub.colums as col><#rt/>
|
||||||
|
<#if col.filedComment !='外键'>
|
||||||
|
{
|
||||||
|
title: '${col.filedComment}',
|
||||||
|
key: '${col.fieldName}',
|
||||||
|
<#if col.fieldType =='date'>
|
||||||
|
type: FormTypes.date,
|
||||||
|
<#elseif col.fieldType =='datetime'>
|
||||||
|
type: FormTypes.datetime,
|
||||||
|
<#elseif "int,decimal,double,"?contains(col.fieldType)>
|
||||||
|
type: FormTypes.inputNumber,
|
||||||
|
<#else>
|
||||||
|
type: FormTypes.input,
|
||||||
|
</#if>
|
||||||
|
defaultValue: '',
|
||||||
|
placeholder: '请输入${'$'}{title}',
|
||||||
|
<#if col.nullable =='N'>
|
||||||
|
validateRules: [{ required: true, message: '${'$'}{title}不能为空' }],
|
||||||
|
</#if>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
]
|
||||||
|
},
|
||||||
|
</#list>
|
||||||
|
url: {
|
||||||
|
add: "/${entityPackage}/${entityName?uncap_first}/add",
|
||||||
|
edit: "/${entityPackage}/${entityName?uncap_first}/edit",
|
||||||
|
<#list subTables as sub><#rt/>
|
||||||
|
${sub.entityName?uncap_first}: {
|
||||||
|
list: '/${entityPackage}/${entityName?uncap_first}/query${sub.entityName}ByMainId'
|
||||||
|
},
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 调用完edit()方法之后会自动调用此方法 */
|
||||||
|
editAfter() {
|
||||||
|
// 加载子表数据
|
||||||
|
if (this.model.id) {
|
||||||
|
let params = { id: this.model.id }
|
||||||
|
<#list subTables as sub><#rt/>
|
||||||
|
this.requestSubTableData(this.url.${sub.entityName?uncap_first}.list, params, this.${sub.entityName?uncap_first}Table)
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 整理成formData */
|
||||||
|
classifyIntoFormData(allValues) {
|
||||||
|
let main = Object.assign(this.model, allValues.formValue)
|
||||||
|
return {
|
||||||
|
...main, // 展开
|
||||||
|
<#list subTables as sub><#rt/>
|
||||||
|
${sub.entityName?uncap_first}List: allValues.tablesValue[${sub_index}].values,
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package org.jeecg.boot.starter.lock.annotation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zyf
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 防止重复提交的注解
|
||||||
|
*
|
||||||
|
* @author 2019年6月18日
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.METHOD})
|
||||||
|
@Documented
|
||||||
|
public @interface JRepeat {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 超时时间
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int lockTime();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* redis 锁key的
|
||||||
|
*
|
||||||
|
* @return redis 锁key
|
||||||
|
*/
|
||||||
|
String lockKey() default "";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue