mirror of https://github.com/jeecgboot/jeecg-boot
zhangdaiscott
4 years ago
131 changed files with 3851 additions and 43841 deletions
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
@ -0,0 +1,81 @@
|
||||
|
||||
-- redis监控菜单sql |
||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_route`, `is_leaf`, `keep_alive`, `hidden`, `description`, `status`, `del_flag`, `rule_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `internal_or_external`) VALUES ('1352200630711652354', 'f0675b52d89100ee88472b6800754a08', 'redis监控', '{{ window._CONFIG[\'domianURL\'] }}/jmreport/view/1352160857479581696', 'layouts/IframePageView', NULL, NULL, '1', NULL, '1', '1.00', '0', '', '1', '1', '0', '0', NULL, '1', '0', '0', 'admin', '2021-01-21 18:25:28', 'admin', '2021-01-22 16:49:43', '0'); |
||||
|
||||
|
||||
|
||||
-- 新增开关字典 |
||||
INSERT INTO `sys_dict` (`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `type`) VALUES ('1356445645198135298', '开关', 'is_open', '', '0', 'admin', '2021-02-02 11:33:38', 'admin', '2021-02-02 15:28:12', '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 ('1356445705549975553', '1356445645198135298', '是', 'Y', '', '1', '1', 'admin', '2021-02-02 11:33:52', NULL, NULL); |
||||
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 ('1356445754212290561', '1356445645198135298', '否', 'N', '', '1', '1', 'admin', '2021-02-02 11:34:04', NULL, NULL); |
||||
-- author:liusq----date:20210202----for: 新增开关字典 |
||||
|
||||
|
||||
-- 是否字典 |
||||
INSERT INTO `sys_dict`(`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `type`) VALUES ('a7adbcd86c37f7dbc9b66945c82ef9e6', '1是0否', 'yn', '', 0, 'admin', '2019-05-22 19:29:29', NULL, NULL, 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 ('51222413e5906cdaf160bb5c86fb827c', 'a7adbcd86c37f7dbc9b66945c82ef9e6', '是', '1', '', 1, 1, 'admin', '2019-05-22 19:29:45', NULL, NULL); |
||||
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 ('c5700a71ad08994d18ad1dacc37a71a9', 'a7adbcd86c37f7dbc9b66945c82ef9e6', '否', '0', '', 1, 1, 'admin', '2019-05-22 19:29:55', NULL, NULL); |
||||
-- author:scott----date:20210202----for: 是否字典 |
||||
|
||||
|
||||
-- 精简积木报表的示例表,由22个减至4个---- |
||||
drop table rep_demo_dadong; |
||||
drop table rep_demo_daibu; |
||||
drop table rep_demo_deliveryorder; |
||||
drop table rep_demo_huizong; |
||||
drop table rep_demo_income; |
||||
drop table rep_demo_jiehsao; |
||||
drop table rep_demo_kaoqin; |
||||
drop table rep_demo_salesrate; |
||||
drop table rep_demo_xiaoshou; |
||||
drop table xianlu1_wxtl; |
||||
drop table xianlu_wxtl; |
||||
drop table yanshi_duozu; |
||||
drop table yanshi_jdcx; |
||||
drop table yanshi_qipaosandian; |
||||
drop table yanshi_sandian; |
||||
drop table yanshi_tima; |
||||
drop table yanshi_wxtl; |
||||
drop table yanshi_yipan; |
||||
alter table yanshi_dxtj rename to rep_demo_dxtj; |
||||
delete from jimu_report_data_source where report_id in ('1331429368098066432','1333962561053396992','1334028738995818496','1334074491629867008','1337271712059887616','1339478701846433792','1339859143477039104','8e69f5396643b199c92d6f401be4d833'); |
||||
delete from jimu_report_db where jimu_report_id in('1331429368098066432','1333962561053396992','1334028738995818496','1334074491629867008','1337271712059887616','1339478701846433792','1339859143477039104','8e69f5396643b199c92d6f401be4d833'); |
||||
delete from jimu_report_db_param where jimu_report_head_id in ('1331429368098066432','1333962561053396992','1334028738995818496','1334074491629867008','1337271712059887616','1339478701846433792','1339859143477039104','8e69f5396643b199c92d6f401be4d833'); |
||||
delete from jimu_report_db_field where jimu_report_db_id not in (select id from jimu_report_db); |
||||
delete from jimu_report where id in ('1331429368098066432','1333962561053396992','1334028738995818496','1334074491629867008','1337271712059887616','1339478701846433792','1339859143477039104','8e69f5396643b199c92d6f401be4d833'); |
||||
|
||||
|
||||
-- 添加一对多JVxeTable案例 |
||||
INSERT INTO sys_permission (`id`, `parent_id`, `name`, `url`, `component`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_route`, `is_leaf`, `keep_alive`, `hidden`, `description`, `status`, `del_flag`, `rule_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `internal_or_external`) VALUES ('1365187528377102337', '2a470fc0c3954d9dbb61de6d80846549', '一对多JVxeTable', '/jeecg/JeecgOrderMainListForJVxeTable', 'jeecg/JeecgOrderMainListForJVxeTable', NULL, NULL, 1, NULL, '1', 2.00, 0, NULL, 1, 1, 0, 0, NULL, '1', 0, 0, 'admin', '2021-02-26 14:30:45', 'admin', '2021-02-26 14:32:05', 0); |
||||
|
||||
-- 积木权限表 |
||||
CREATE TABLE `jimu_report_share` ( |
||||
`id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键', |
||||
`report_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '在线excel设计器id', |
||||
`preview_url` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '预览地址', |
||||
`preview_lock` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '密码锁', |
||||
`last_update_time` datetime(0) NULL DEFAULT NULL COMMENT '最后更新时间', |
||||
`term_of_validity` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '有效期(0:永久有效,1:1天,2:7天)', |
||||
`status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否过期(0未过期,1已过期)', |
||||
PRIMARY KEY (`id`) USING BTREE |
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '积木报表预览权限表'; |
||||
|
||||
|
||||
-- 积木报表链接表 |
||||
CREATE TABLE `jimu_report_link` ( |
||||
`id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键id', |
||||
`report_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '积木设计器id', |
||||
`parameter` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '参数', |
||||
`eject_type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '弹出方式(0 当前页面 1 新窗口)', |
||||
`link_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '链接名称', |
||||
`api_method` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求方法0-get,1-post', |
||||
`link_type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '链接方式(0 网络报表 1 网络连接 2 图表联动)', |
||||
`api_url` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '外网api', |
||||
PRIMARY KEY (`id`) USING BTREE |
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '超链接配置表'; |
||||
|
||||
|
||||
update jimu_report_link set link_type = '0'; |
||||
|
||||
|
||||
|
@ -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; |
||||
|
@ -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 lombok.Data; |
||||
import org.jeecg.boot.starter.redis.listener.JeecgRedisListerer; |
||||
import org.jeecg.common.base.BaseMap; |
||||
import org.jeecg.common.constant.GlobalConstants; |
||||
import org.jeecg.common.modules.redis.listener.JeecgRedisListerer; |
||||
import org.jeecg.common.util.SpringContextHolder; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author zyf |
||||
*/ |
||||
@Component |
||||
@Data |
||||
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,38 @@
|
||||
package org.jeecg.config.init; |
||||
|
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
import org.jeecgframework.codegenerate.database.CodegenDatasourceConfig; |
||||
import org.springframework.beans.factory.annotation.Value; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
/** |
||||
* @Description: 代码生成器,自定义DB配置 |
||||
* 【加了此类,则online模式DB连接,使用平台的配置,jeecg_database.properties配置无效; |
||||
* 但是使用GUI模式代码生成,还是走jeecg_database.properties配置】 |
||||
* @author: scott |
||||
* @date: 2021年02月18日 16:30 |
||||
*/ |
||||
@Slf4j |
||||
@Configuration |
||||
public class CodeGenerateDbConfig { |
||||
@Value("${spring.datasource.dynamic.datasource.master.url:}") |
||||
private String url; |
||||
@Value("${spring.datasource.dynamic.datasource.master.username:}") |
||||
private String username; |
||||
@Value("${spring.datasource.dynamic.datasource.master.password:}") |
||||
private String password; |
||||
@Value("${spring.datasource.dynamic.datasource.master.driver-class-name:}") |
||||
private String driverClassName; |
||||
|
||||
|
||||
@Bean |
||||
public CodeGenerateDbConfig initCodeGenerateDbConfig() { |
||||
if(StringUtils.isNotBlank(url)){ |
||||
CodegenDatasourceConfig.initDbConfig(driverClassName,url, username, password); |
||||
log.info(" 代码生成器数据库连接,使用application.yml的DB配置 ###################"); |
||||
} |
||||
return null; |
||||
} |
||||
} |
@ -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"> |
||||
<#if po.isShow == 'Y' && poHasCheck(po)> |
||||
<#if po.fieldName != 'id'> |
||||
${po.fieldName}: { |
||||
<#if po.defaultVal??> |
||||
<#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.fieldName != 'id'> |
||||
${po.fieldName}: [ |
||||
<#assign fieldValidType = po.fieldValidType!''> |
||||
<#-- 非空校验 --> |
||||
<#if po.nullable == 'N' || fieldValidType == '*'> |
||||
<#if po.nullable == 'N' || fieldValidType == '*'> |
||||
{ required: true, message: '请输入${po.filedComment}!'}, |
||||
<#elseif fieldValidType!=''> |
||||
<#elseif fieldValidType!=''> |
||||
{ 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)}, |
||||
<#-- 6到16位数字 --> |
||||
<#elseif fieldValidType == 'n6-16'> |
||||
<#-- 6到16位数字 --> |
||||
<#elseif fieldValidType == 'n6-16'> |
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, |
||||
<#-- 6到16位任意字符 --> |
||||
<#elseif fieldValidType == '*6-16'> |
||||
<#-- 6到16位任意字符 --> |
||||
<#elseif fieldValidType == '*6-16'> |
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, |
||||
<#-- 6到18位字符串 --> |
||||
<#elseif fieldValidType == 's6-18'> |
||||
<#-- 6到18位字符串 --> |
||||
<#elseif fieldValidType == 's6-18'> |
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, |
||||
<#-- 网址 --> |
||||
<#elseif fieldValidType == 'url'> |
||||
<#-- 网址 --> |
||||
<#elseif fieldValidType == 'url'> |
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, |
||||
<#-- 电子邮件 --> |
||||
<#elseif fieldValidType == 'e'> |
||||
<#-- 电子邮件 --> |
||||
<#elseif fieldValidType == 'e'> |
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}, |
||||
<#-- 手机号码 --> |
||||
<#elseif fieldValidType == 'm'> |
||||
<#-- 手机号码 --> |
||||
<#elseif fieldValidType == 'm'> |
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, |
||||
<#-- 邮政编码 --> |
||||
<#elseif fieldValidType == 'p'> |
||||
<#-- 邮政编码 --> |
||||
<#elseif fieldValidType == 'p'> |
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'}, |
||||
<#-- 字母 --> |
||||
<#elseif fieldValidType == 's'> |
||||
<#-- 字母 --> |
||||
<#elseif fieldValidType == 's'> |
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, |
||||
<#-- 数字 --> |
||||
<#elseif fieldValidType == 'n'> |
||||
<#-- 数字 --> |
||||
<#elseif fieldValidType == 'n'> |
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}, |
||||
<#-- 整数 --> |
||||
<#elseif fieldValidType == 'z'> |
||||
<#-- 整数 --> |
||||
<#elseif fieldValidType == 'z'> |
||||
{ 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: '请输入正确的金额!'}, |
||||
<#-- 正则校验 --> |
||||
<#elseif fieldValidType != '' && fieldValidType != '*'> |
||||
<#-- 正则校验 --> |
||||
<#elseif fieldValidType != '' && fieldValidType != '*'> |
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'}, |
||||
<#-- 无校验 --> |
||||
<#else> |
||||
<#t> |
||||
<#-- 无校验 --> |
||||
<#else> |
||||
<#t> |
||||
</#if> |
||||
], |
||||
</#if> |
||||
] |
||||
}, |
||||
</#if> |
||||
</#if> |
@ -0,0 +1,513 @@
|
||||
<#include "/common/utils.ftl"> |
||||
<template> |
||||
<a-spin :spinning="confirmLoading"> |
||||
<j-form-container :disabled="formDisabled"> |
||||
<!-- 主表单区域 --> |
||||
<a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail"> |
||||
<a-row> |
||||
<#assign form_popup = false> |
||||
<#assign form_cat_tree = false> |
||||
<#assign form_cat_back = ""> |
||||
<#assign form_span = 24> |
||||
<#list columns as po> |
||||
<#if po.isShow =='Y' && po.fieldName != 'id'> |
||||
<#assign form_field_dictCode=""> |
||||
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> |
||||
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> |
||||
<#elseif po.dictField?default("")?trim?length gt 1> |
||||
<#assign form_field_dictCode="${po.dictField}"> |
||||
</#if> |
||||
<#if po.classType =='textarea'> |
||||
<a-col :span="24"> |
||||
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2" prop="${autoStringSuffixForModel(po)}"> |
||||
<#else> |
||||
<a-col :xs="24" :sm="12"> |
||||
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="${autoStringSuffixForModel(po)}"> |
||||
</#if> |
||||
<#if po.classType =='date'> |
||||
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='datetime'> |
||||
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='time'> |
||||
<j-time placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='popup'> |
||||
<#assign form_popup=true> |
||||
<j-popup |
||||
v-model="model.${po.fieldName}" |
||||
field="${po.fieldName}" |
||||
org-fields="${po.dictField}" |
||||
dest-fields="${Format.underlineToHump(po.dictText)}" |
||||
code="${po.dictTable}" |
||||
@input="popupCallback" |
||||
<#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='sel_depart'> |
||||
<j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='switch'> |
||||
<j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch> |
||||
<#elseif po.classType =='pca'> |
||||
<j-area-linkage type="cascader" v-model="model.${po.fieldName}" placeholder="请输入省市区" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='markdown'> |
||||
<j-markdown-editor v-model="model.${autoStringSuffixForModel(po)}" id="${po.fieldName}"></j-markdown-editor> |
||||
<#elseif po.classType =='password'> |
||||
<a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='sel_user'> |
||||
<j-select-user-by-dep v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='textarea'> |
||||
<a-textarea v-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType=='list' || po.classType=='radio'> |
||||
<j-dict-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'> |
||||
<j-multi-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType=='sel_search'> |
||||
<j-search-select-tag v-model="model.${po.fieldName}" dict="${form_field_dictCode}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType=='cat_tree'> |
||||
<#assign form_cat_tree = true> |
||||
<j-category-select v-model="model.${po.fieldName}" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${dashedToCamel(po.dictText)}" @change="handleCategoryChange"</#if> <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#if po.dictText?default("")?trim?length gt 1> |
||||
<#assign form_cat_back = "${po.dictText}"> |
||||
</#if> |
||||
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> |
||||
<a-input-number v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType=='file'> |
||||
<j-upload v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if> <#if po.uploadnum??>:number=${po.uploadnum}</#if>></j-upload> |
||||
<#elseif po.classType=='image'> |
||||
<j-image-upload isMultiple <#if po.uploadnum??>:number=${po.uploadnum}</#if> v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>></j-image-upload> |
||||
<#elseif po.classType=='umeditor'> |
||||
<j-editor v-model="model.${autoStringSuffixForModel(po)}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType == 'sel_tree'> |
||||
<j-tree-select |
||||
ref="treeSelect" |
||||
placeholder="请选择${po.filedComment}" |
||||
v-model="model.${po.fieldName}" |
||||
<#if po.dictText??> |
||||
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> |
||||
dict="${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}" |
||||
<#elseif po.dictText?split(',')[1]??> |
||||
pidField="${po.dictText?split(',')[1]}" |
||||
<#elseif po.dictText?split(',')[3]??> |
||||
hasChildField="${po.dictText?split(',')[3]}" |
||||
</#if> |
||||
</#if> |
||||
pidValue="${po.dictField}" |
||||
<#if po.readonly=='Y'>disabled</#if>> |
||||
</j-tree-select> |
||||
<#else> |
||||
<a-input v-model="model.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input> |
||||
</#if> |
||||
</a-form-model-item> |
||||
</a-col> |
||||
</#if> |
||||
</#list> |
||||
</a-row> |
||||
</a-form-model> |
||||
</j-form-container> |
||||
<!-- 子表单区域 --> |
||||
<a-tabs v-model="activeKey" @change="handleChangeTabs"> |
||||
<#list subTables as sub><#rt/> |
||||
<#if sub.foreignRelationType =='1'> |
||||
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index}]" :forceRender="true"> |
||||
<${Format.humpToShortbar(sub.entityName)}-form ref="${sub.entityName?uncap_first}Form" @validateError="validateError" :disabled="formDisabled"></${Format.humpToShortbar(sub.entityName)}-form> |
||||
</a-tab-pane> |
||||
|
||||
<#else> |
||||
<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" |
||||
:disabled="formDisabled" |
||||
:rowNumber="true" |
||||
:rowSelection="true" |
||||
:actionButton="true"/> |
||||
</a-tab-pane> |
||||
</#if> |
||||
</#list> |
||||
</a-tabs> |
||||
<a-row v-if="showFlowSubmitButton" style="text-align: center;width: 100%;margin-top: 16px;"><a-button @click="handleOk">提 交</a-button></a-row> |
||||
</a-spin> |
||||
</template> |
||||
|
||||
<script> |
||||
|
||||
import { FormTypes,getRefPromise,VALIDATE_NO_PASSED } from '@/utils/JEditableTableUtil' |
||||
import { JEditableTableModelMixin } from '@/mixins/JEditableTableModelMixin' |
||||
import { validateDuplicateValue } from '@/utils/util' |
||||
<#list subTables as sub> |
||||
<#if sub.foreignRelationType =='1'> |
||||
import ${sub.entityName}Form from './${sub.entityName}Form.vue' |
||||
</#if> |
||||
</#list> |
||||
|
||||
export default { |
||||
name: '${entityName}Form', |
||||
mixins: [JEditableTableModelMixin], |
||||
components: { |
||||
<#list subTables as sub> |
||||
<#if sub.foreignRelationType =='1'> |
||||
${sub.entityName}Form, |
||||
</#if> |
||||
</#list> |
||||
}, |
||||
data() { |
||||
return { |
||||
labelCol: { |
||||
xs: { span: 24 }, |
||||
sm: { span: 6 }, |
||||
}, |
||||
wrapperCol: { |
||||
xs: { span: 24 }, |
||||
sm: { span: 16 }, |
||||
}, |
||||
labelCol2: { |
||||
xs: { span: 24 }, |
||||
sm: { span: 3 }, |
||||
}, |
||||
wrapperCol2: { |
||||
xs: { span: 24 }, |
||||
sm: { span: 20 }, |
||||
}, |
||||
model:{ |
||||
<#include "/common/init/initValue.ftl"> |
||||
}, |
||||
<#include "/common/validatorRulesTemplate/main.ftl"> |
||||
// 新增时子表默认添加几行空数据 |
||||
addDefaultRowNum: 1, |
||||
refKeys: [<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>], |
||||
tableKeys:[<#list subTables as sub><#if sub.foreignRelationType =='0'>'${sub.entityName?uncap_first}', </#if></#list>], |
||||
activeKey: '${subTables[0].entityName?uncap_first}', |
||||
<#list subTables as sub><#rt/> |
||||
// ${sub.ftlDescription} |
||||
${sub.entityName?uncap_first}Table: { |
||||
loading: false, |
||||
dataSource: [], |
||||
columns: [ |
||||
<#if sub.foreignRelationType =='0'> |
||||
<#assign popupBackFields = ""> |
||||
|
||||
<#-- 循环子表的列 开始 --> |
||||
<#list sub.colums as col><#rt/> |
||||
<#if col.isShow =='Y'> |
||||
<#if col.filedComment !='外键' > |
||||
{ |
||||
title: '${col.filedComment}', |
||||
key: '${autoStringSuffixForModel(col)}', |
||||
<#if col.classType =='date'> |
||||
type: FormTypes.date, |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif col.classType =='datetime'> |
||||
type: FormTypes.datetime, |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif "int,decimal,double,"?contains(col.classType)> |
||||
type: FormTypes.inputNumber, |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif col.classType =='list' || col.classType =='radio'> |
||||
type: FormTypes.select, |
||||
<#if col.dictTable?default("")?trim?length gt 1> |
||||
dictCode:"${col.dictTable},${col.dictText},${col.dictField}", |
||||
<#else> |
||||
dictCode:"${col.dictField}", |
||||
</#if> |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif col.classType =='list_multi' || col.classType =='checkbox'> |
||||
type: FormTypes.list_multi, |
||||
<#if col.dictTable?default("")?trim?length gt 1> |
||||
dictCode:"${col.dictTable},${col.dictText},${col.dictField}", |
||||
<#else> |
||||
dictCode:"${col.dictField}", |
||||
</#if> |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif col.classType =='switch'> |
||||
type: FormTypes.checkbox, |
||||
<#if col.dictField == 'is_open'> |
||||
customValue: ['Y', 'N'], |
||||
<#else> |
||||
customValue: ${col.dictField}, |
||||
</#if> |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif col.classType =='sel_search'> |
||||
type: FormTypes.sel_search, |
||||
<#if col.dictTable?default("")?trim?length gt 1> |
||||
dictCode:"${col.dictTable},${col.dictText},${col.dictField}", |
||||
<#else> |
||||
dictCode:"${col.dictField}", |
||||
</#if> |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif col.classType =='image'> |
||||
type: FormTypes.image, |
||||
token:true, |
||||
responseName:"message", |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#if col.uploadnum??> |
||||
number: ${col.uploadnum}, |
||||
</#if> |
||||
<#elseif col.classType =='file'> |
||||
type: FormTypes.file, |
||||
token:true, |
||||
responseName:"message", |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#if col.uploadnum??> |
||||
number: ${col.uploadnum}, |
||||
</#if> |
||||
<#elseif col.classType =='popup'> |
||||
<#if popupBackFields?length gt 0> |
||||
<#assign popupBackFields = "${popupBackFields}"+","+"${col.dictText}"> |
||||
<#else> |
||||
<#assign popupBackFields = "${col.dictText}"> |
||||
</#if> |
||||
type: FormTypes.popup, |
||||
popupCode:"${col.dictTable}", |
||||
destFields:"${col.dictText}", |
||||
orgFields:"${col.dictField}", |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#else> |
||||
type: FormTypes.input, |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
</#if> |
||||
<#if col.classType =='list_multi' || col.classType =='checkbox'> |
||||
width:"250px", |
||||
<#else> |
||||
width:"200px", |
||||
</#if> |
||||
<#if col.classType =='file'> |
||||
placeholder: '请选择文件', |
||||
<#else> |
||||
placeholder: '请输入${'$'}{title}', |
||||
</#if> |
||||
<#if col.defaultVal??> |
||||
<#if col.fieldDbType=="BigDecimal" || col.fieldDbType=="double" || col.fieldDbType=="int"> |
||||
defaultValue:${col.defaultVal}, |
||||
<#else> |
||||
defaultValue:"${col.defaultVal}", |
||||
</#if> |
||||
<#else> |
||||
defaultValue:'', |
||||
</#if> |
||||
<#-- 子表的校验 --> |
||||
<#assign subFieldValidType = col.fieldValidType!''> |
||||
<#-- 非空校验 --> |
||||
<#if col.nullable == 'N' || subFieldValidType == '*'> |
||||
validateRules: [{ required: true, message: '${'$'}{title}不能为空' }], |
||||
<#-- 其他情况下,只要有值就被认为是正则校验 --> |
||||
<#elseif subFieldValidType?length gt 0> |
||||
<#assign subMessage = '格式不正确'> |
||||
<#if subFieldValidType == 'only' > |
||||
<#assign subMessage = '不能重复'> |
||||
</#if> |
||||
validateRules: [{ pattern: "${subFieldValidType}", message: "${'$'}{title}${subMessage}" }], |
||||
</#if> |
||||
}, |
||||
</#if> |
||||
</#if> |
||||
</#list> |
||||
<#-- 循环子表的列 结束 --> |
||||
|
||||
<#-- 处理popup的隐藏列 --> |
||||
<#if popupBackFields?length gt 0> |
||||
<#list popupBackFields?split(",") as item> |
||||
<#if item?length gt 0> |
||||
<#assign tempItemFlag = true> |
||||
|
||||
<#list sub.colums as col> |
||||
<#if col.isShow =='Y' && col.fieldName == item> |
||||
<#assign tempItemFlag = false> |
||||
</#if> |
||||
</#list> |
||||
<#if tempItemFlag> |
||||
{ |
||||
title: '${item}', |
||||
key: '${item}', |
||||
type:"hidden" |
||||
}, |
||||
</#if> |
||||
</#if> |
||||
</#list> |
||||
</#if> |
||||
</#if> |
||||
] |
||||
}, |
||||
</#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> |
||||
} |
||||
} |
||||
}, |
||||
props: { |
||||
//流程表单data |
||||
formData: { |
||||
type: Object, |
||||
default: ()=>{}, |
||||
required: false |
||||
}, |
||||
//表单模式:false流程表单 true普通表单 |
||||
formBpm: { |
||||
type: Boolean, |
||||
default: false, |
||||
required: false |
||||
}, |
||||
//表单禁用 |
||||
disabled: { |
||||
type: Boolean, |
||||
default: false, |
||||
required: false |
||||
} |
||||
}, |
||||
computed: { |
||||
formDisabled(){ |
||||
if(this.formBpm===true){ |
||||
if(this.formData.disabled===false){ |
||||
return false |
||||
} |
||||
return true |
||||
} |
||||
return this.disabled |
||||
}, |
||||
showFlowSubmitButton(){ |
||||
if(this.formBpm===true){ |
||||
if(this.formData.disabled===false){ |
||||
return true |
||||
} |
||||
} |
||||
return false |
||||
} |
||||
}, |
||||
created () { |
||||
//如果是流程中表单,则需要加载流程表单data |
||||
this.showFlowData(); |
||||
}, |
||||
methods: { |
||||
addBefore(){ |
||||
<#list subTables as sub><#rt/> |
||||
<#if sub.foreignRelationType =='1'> |
||||
this.$refs.${sub.entityName?uncap_first}Form.clearFormData() |
||||
<#else> |
||||
this.${sub.entityName?uncap_first}Table.dataSource=[] |
||||
</#if> |
||||
</#list> |
||||
}, |
||||
getAllTable() { |
||||
let values = this.tableKeys.map(key => getRefPromise(this, key)) |
||||
return Promise.all(values) |
||||
}, |
||||
/** 调用完edit()方法之后会自动调用此方法 */ |
||||
editAfter() { |
||||
this.$nextTick(() => { |
||||
<#list subTables as sub><#rt/> |
||||
<#if sub.foreignRelationType =='1'> |
||||
this.$refs.${sub.entityName?uncap_first}Form.initFormData(this.url.${sub.entityName?uncap_first}.list,this.model.id) |
||||
</#if> |
||||
</#list> |
||||
}) |
||||
// 加载子表数据 |
||||
if (this.model.id) { |
||||
let params = { id: this.model.id } |
||||
<#list subTables as sub><#rt/> |
||||
<#if sub.foreignRelationType =='0'> |
||||
this.requestSubTableData(this.url.${sub.entityName?uncap_first}.list, params, this.${sub.entityName?uncap_first}Table) |
||||
</#if> |
||||
</#list> |
||||
} |
||||
}, |
||||
//校验所有一对一子表表单 |
||||
validateSubForm(allValues){ |
||||
return new Promise((resolve,reject)=>{ |
||||
Promise.all([ |
||||
<#list subTables as sub><#rt/> |
||||
<#if sub.foreignRelationType =='1'> |
||||
this.$refs.${sub.entityName?uncap_first}Form.validate(${sub_index}), |
||||
</#if> |
||||
</#list> |
||||
]).then(() => { |
||||
resolve(allValues) |
||||
}).catch(e => { |
||||
if (e.error === VALIDATE_NO_PASSED) { |
||||
// 如果有未通过表单验证的子表,就自动跳转到它所在的tab |
||||
this.activeKey = e.index == null ? this.activeKey : this.refKeys[e.index] |
||||
} else { |
||||
console.error(e) |
||||
} |
||||
}) |
||||
}) |
||||
}, |
||||
/** 整理成formData */ |
||||
classifyIntoFormData(allValues) { |
||||
let main = Object.assign(this.model, allValues.formValue) |
||||
|
||||
return { |
||||
...main, // 展开 |
||||
<#assign subManyIndex = 0> |
||||
<#list subTables as sub><#rt/> |
||||
<#if sub.foreignRelationType =='0'> |
||||
${sub.entityName?uncap_first}List: allValues.tablesValue[${subManyIndex}].values, |
||||
<#assign subManyIndex = subManyIndex+1> |
||||
<#else> |
||||
${sub.entityName?uncap_first}List: this.$refs.${sub.entityName?uncap_first}Form.getFormData(), |
||||
</#if> |
||||
</#list> |
||||
} |
||||
}, |
||||
//渲染流程表单数据 |
||||
showFlowData(){ |
||||
if(this.formBpm === true){ |
||||
let params = {id:this.formData.dataId}; |
||||
getAction(this.url.queryById,params).then((res)=>{ |
||||
if(res.success){ |
||||
this.edit (res.result); |
||||
} |
||||
}) |
||||
} |
||||
}, |
||||
validateError(msg){ |
||||
this.$message.error(msg) |
||||
}, |
||||
close() { |
||||
this.visible = false |
||||
this.$emit('close') |
||||
this.$refs.form.clearValidate(); |
||||
}, |
||||
<#if form_popup> |
||||
popupCallback(value,row){ |
||||
this.model = Object.assign(this.model, row); |
||||
}, |
||||
</#if> |
||||
<#if form_cat_tree> |
||||
handleCategoryChange(value,backObj){ |
||||
this.model = Object.assign(this.model, backObj); |
||||
} |
||||
</#if> |
||||
|
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
</style> |
@ -0,0 +1,490 @@
|
||||
<#include "/common/utils.ftl"> |
||||
<template> |
||||
<a-spin :spinning="confirmLoading"> |
||||
<#assign form_popup = false> |
||||
<#assign form_cat_tree = false> |
||||
<#assign form_cat_back = ""> |
||||
<#assign form_span = 24> |
||||
|
||||
<a-tabs v-model="activeKey" @change="handleChangeTabs"> |
||||
<!--主表区域 --> |
||||
<a-tab-pane tab="${tableVo.ftlDescription}" :key="refKeys[0]" :forceRender="true"> |
||||
<a-form-model ref="form" :model="model" :rules="validatorRules"> |
||||
<a-row> |
||||
<#list columns as po> |
||||
<#if po.isShow =='Y' && po.fieldName != 'id'> |
||||
<#assign form_field_dictCode=""> |
||||
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> |
||||
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> |
||||
<#elseif po.dictField?default("")?trim?length gt 1> |
||||
<#assign form_field_dictCode="${po.dictField}"> |
||||
</#if> |
||||
<#if po.classType =='textarea'> |
||||
<a-col :span="24"> |
||||
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2" prop="${autoStringSuffixForModel(po)}"> |
||||
<#else> |
||||
<a-col :xs="24" :sm="12"> |
||||
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="${autoStringSuffixForModel(po)}"> |
||||
</#if> |
||||
<#if po.classType =='date'> |
||||
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='datetime'> |
||||
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='time'> |
||||
<j-time placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='popup'> |
||||
<#assign form_popup=true> |
||||
<j-popup |
||||
v-model="model.${po.fieldName}" |
||||
field="${po.fieldName}" |
||||
org-fields="${po.dictField}" |
||||
dest-fields="${Format.underlineToHump(po.dictText)}" |
||||
code="${po.dictTable}" |
||||
@input="popupCallback" |
||||
<#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='sel_depart'> |
||||
<j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='switch'> |
||||
<j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch> |
||||
<#elseif po.classType =='pca'> |
||||
<j-area-linkage type="cascader" v-model="model.${po.fieldName}" placeholder="请输入省市区" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='markdown'> |
||||
<j-markdown-editor v-model="model.${autoStringSuffixForModel(po)}" id="${po.fieldName}"></j-markdown-editor> |
||||
<#elseif po.classType =='password'> |
||||
<a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='sel_user'> |
||||
<j-select-user-by-dep v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType =='textarea'> |
||||
<a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType=='list' || po.classType=='radio'> |
||||
<j-dict-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'> |
||||
<j-multi-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType=='sel_search'> |
||||
<j-search-select-tag v-model="model.${po.fieldName}" dict="${form_field_dictCode}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType=='cat_tree'> |
||||
<#assign form_cat_tree = true> |
||||
<j-category-select v-model="model.${po.fieldName}" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${dashedToCamel(po.dictText)}" @change="handleCategoryChange"</#if> <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#if po.dictText?default("")?trim?length gt 1> |
||||
<#assign form_cat_back = "${po.dictText}"> |
||||
</#if> |
||||
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> |
||||
<a-input-number v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType=='file'> |
||||
<j-upload v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if> <#if po.uploadnum??>:number=${po.uploadnum}</#if>></j-upload> |
||||
<#elseif po.classType=='image'> |
||||
<j-image-upload isMultiple <#if po.uploadnum??>:number=${po.uploadnum}</#if> v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>></j-image-upload> |
||||
<#elseif po.classType=='umeditor'> |
||||
<j-editor v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>/> |
||||
<#elseif po.classType == 'sel_tree'> |
||||
<j-tree-select |
||||
ref="treeSelect" |
||||
placeholder="请选择${po.filedComment}" |
||||
v-model="model.${po.fieldName}" |
||||
<#if po.dictText??> |
||||
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> |
||||
dict="${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}" |
||||
<#elseif po.dictText?split(',')[1]??> |
||||
pidField="${po.dictText?split(',')[1]}" |
||||
<#elseif po.dictText?split(',')[3]??> |
||||
hasChildField="${po.dictText?split(',')[3]}" |
||||
</#if> |
||||
</#if> |
||||
pidValue="${po.dictField}" |
||||
<#if po.readonly=='Y'>disabled</#if>> |
||||
</j-tree-select> |
||||
<#else> |
||||
<a-input v-model="model.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input> |
||||
</#if> |
||||
</a-form-model-item> |
||||
</a-col> |
||||
</#if> |
||||
</#list> |
||||
|
||||
</a-row> |
||||
</a-form-model> |
||||
|
||||
</a-tab-pane> |
||||
<!--子表单区域 --> |
||||
<#list subTables as sub><#rt/> |
||||
<#if sub.foreignRelationType =='1'> |
||||
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index+1}]" :forceRender="true"> |
||||
<${Format.humpToShortbar(sub.entityName)}-form ref="${sub.entityName?uncap_first}Form" @validateError="validateError"></${Format.humpToShortbar(sub.entityName)}-form> |
||||
</a-tab-pane> |
||||
|
||||
<#else> |
||||
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index+1}]" :forceRender="true"> |
||||
<j-editable-table |
||||
:ref="refKeys[${sub_index+1}]" |
||||
: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> |
||||
|
||||
</#if> |
||||
</#list> |
||||
</a-tabs> |
||||
|
||||
</a-spin> |
||||
</j-modal> |
||||
</template> |
||||
|
||||
<script> |
||||
|
||||
import { FormTypes,getRefPromise } from '@/utils/JEditableTableUtil' |
||||
import { JEditableTableModelMixin } from '@/mixins/JEditableTableModelMixin' |
||||
import { validateDuplicateValue } from '@/utils/util' |
||||
import { VALIDATE_NO_PASSED, validateFormModelAndTables } from '@/utils/JEditableTableUtil' |
||||
<#list subTables as sub> |
||||
<#if sub.foreignRelationType =='1'> |
||||
import ${sub.entityName}Form from './${sub.entityName}Form.vue' |
||||
</#if> |
||||
</#list> |
||||
|
||||
export default { |
||||
name: '${entityName}Forml', |
||||
mixins: [JEditableTableModelMixin], |
||||
components: { |
||||
<#list subTables as sub> |
||||
<#if sub.foreignRelationType =='1'> |
||||
${sub.entityName}Form, |
||||
</#if> |
||||
</#list> |
||||
}, |
||||
data() { |
||||
return { |
||||
labelCol: { |
||||
xs: { span: 24 }, |
||||
sm: { span: 6 }, |
||||
}, |
||||
wrapperCol: { |
||||
xs: { span: 24 }, |
||||
sm: { span: 16 }, |
||||
}, |
||||
labelCol2: { |
||||
xs: { span: 24 }, |
||||
sm: { span: 3 }, |
||||
}, |
||||
wrapperCol2: { |
||||
xs: { span: 24 }, |
||||
sm: { span: 20 }, |
||||
}, |
||||
// 新增时子表默认添加几行空数据 |
||||
addDefaultRowNum: 1, |
||||
model:{ |
||||
<#include "/common/init/initValue.ftl"> |
||||
}, |
||||
<#include "/common/validatorRulesTemplate/main.ftl"> |
||||
refKeys: ['${tableVo.entityName?uncap_first}',<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>], |
||||
<#assign hasOne2Many = false> |
||||
tableKeys:[<#list subTables as sub><#if sub.foreignRelationType =='0'>'${sub.entityName?uncap_first}', <#assign hasOne2Many = true></#if></#list>], |
||||
activeKey: '${tableVo.entityName?uncap_first}', |
||||
<#list subTables as sub><#rt/> |
||||
// ${sub.ftlDescription} |
||||
${sub.entityName?uncap_first}Table: { |
||||
loading: false, |
||||
dataSource: [], |
||||
columns: [ |
||||
<#if sub.foreignRelationType =='0'> |
||||
<#assign popupBackFields = ""> |
||||
|
||||
<#-- 循环子表的列 开始 --> |
||||
<#list sub.colums as col><#rt/> |
||||
<#if col.isShow =='Y'> |
||||
<#if col.filedComment !='外键' > |
||||
{ |
||||
title: '${col.filedComment}', |
||||
key: '${autoStringSuffixForModel(col)}', |
||||
<#if col.classType =='date'> |
||||
type: FormTypes.date, |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif col.classType =='datetime'> |
||||
type: FormTypes.datetime, |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif "int,decimal,double,"?contains(col.classType)> |
||||
type: FormTypes.inputNumber, |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif col.classType =='list' || col.classType =='radio'> |
||||
type: FormTypes.select, |
||||
<#if col.dictTable?default("")?trim?length gt 1> |
||||
dictCode:"${col.dictTable},${col.dictText},${col.dictField}", |
||||
<#else> |
||||
dictCode:"${col.dictField}", |
||||
</#if> |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif col.classType =='list_multi' || col.classType =='checkbox'> |
||||
type: FormTypes.list_multi, |
||||
<#if col.dictTable?default("")?trim?length gt 1> |
||||
dictCode:"${col.dictTable},${col.dictText},${col.dictField}", |
||||
<#else> |
||||
dictCode:"${col.dictField}", |
||||
</#if> |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif col.classType =='sel_search'> |
||||
type: FormTypes.sel_search, |
||||
<#if col.dictTable?default("")?trim?length gt 1> |
||||
dictCode:"${col.dictTable},${col.dictText},${col.dictField}", |
||||
<#else> |
||||
dictCode:"${col.dictField}", |
||||
</#if> |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif col.classType =='switch'> |
||||
type: FormTypes.checkbox, |
||||
<#if col.dictField == 'is_open'> |
||||
customValue: ['Y', 'N'], |
||||
<#else> |
||||
customValue: ${col.dictField}, |
||||
</#if> |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif col.classType =='image'> |
||||
type: FormTypes.image, |
||||
token:true, |
||||
responseName:"message", |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#if col.uploadnum??> |
||||
number: ${col.uploadnum}, |
||||
</#if> |
||||
<#elseif col.classType =='file'> |
||||
type: FormTypes.file, |
||||
token:true, |
||||
responseName:"message", |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#if col.uploadnum??> |
||||
number: ${col.uploadnum}, |
||||
</#if> |
||||
<#elseif col.classType =='popup'> |
||||
<#if popupBackFields?length gt 0> |
||||
<#assign popupBackFields = "${popupBackFields}"+","+"${col.dictText}"> |
||||
<#else> |
||||
<#assign popupBackFields = "${col.dictText}"> |
||||
</#if> |
||||
type: FormTypes.popup, |
||||
popupCode:"${col.dictTable}", |
||||
destFields:"${Format.underlineToHump(col.dictText)}", |
||||
orgFields:"${col.dictField}", |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#elseif col.fieldDbType=='int' || col.fieldDbType=='double' || col.fieldDbType=='BigDecimal'> |
||||
type: FormTypes.inputNumber, |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
<#else> |
||||
type: FormTypes.input, |
||||
<#if col.readonly=='Y'> |
||||
disabled:true, |
||||
</#if> |
||||
</#if> |
||||
<#if col.classType =='list_multi' || col.classType =='checkbox'> |
||||
width:"250px", |
||||
<#else> |
||||
width:"200px", |
||||
</#if> |
||||
<#if col.classType =='file'> |
||||
placeholder: '请选择文件', |
||||
<#else> |
||||
placeholder: '请输入${'$'}{title}', |
||||
</#if> |
||||
<#if col.defaultVal??> |
||||
<#if col.fieldDbType=="BigDecimal" || col.fieldDbType=="double" || col.fieldDbType=="int"> |
||||
defaultValue:${col.defaultVal}, |
||||
<#else> |
||||
defaultValue:"${col.defaultVal}", |
||||
</#if> |
||||
<#else> |
||||
defaultValue:'', |
||||
</#if> |
||||
<#-- 子表的校验 --> |
||||
<#assign subFieldValidType = col.fieldValidType!''> |
||||
<#-- 非空校验 --> |
||||
<#if col.nullable == 'N' || subFieldValidType == '*'> |
||||
validateRules: [{ required: true, message: '${'$'}{title}不能为空' }], |
||||
<#-- 其他情况下,只要有值就被认为是正则校验 --> |
||||
<#elseif subFieldValidType?length gt 0> |
||||
<#assign subMessage = '格式不正确'> |
||||
<#if subFieldValidType == 'only' > |
||||
<#assign subMessage = '不能重复'> |
||||
</#if> |
||||
validateRules: [{ pattern: "${subFieldValidType}", message: "${'$'}{title}${subMessage}" }], |
||||
</#if> |
||||
}, |
||||
</#if> |
||||
</#if> |
||||
</#list> |
||||
<#-- 循环子表的列 结束 --> |
||||
|
||||
<#-- 处理popup的隐藏列 --> |
||||
<#if popupBackFields?length gt 0> |
||||
<#list popupBackFields?split(",") as item> |
||||
<#if item?length gt 0> |
||||
<#assign tempItemFlag = true> |
||||
|
||||
<#list sub.colums as col> |
||||
<#if col.isShow =='Y' && col.fieldName == item> |
||||
<#assign tempItemFlag = false> |
||||
</#if> |
||||
</#list> |
||||
<#if tempItemFlag> |
||||
{ |
||||
title: '${item}', |
||||
key: '${item}', |
||||
type:"hidden" |
||||
}, |
||||
</#if> |
||||
</#if> |
||||
</#list> |
||||
</#if> |
||||
</#if> |
||||
] |
||||
}, |
||||
</#list> |
||||
url: { |
||||
add: "/${entityPackage}/${entityName?uncap_first}/add", |
||||
edit: "/${entityPackage}/${entityName?uncap_first}/edit", |
||||
${tableVo.entityName?uncap_first}: { |
||||
list: '/${entityPackage}/${entityName?uncap_first}/queryById' |
||||
}, |
||||
<#list subTables as sub><#rt/> |
||||
${sub.entityName?uncap_first}: { |
||||
list: '/${entityPackage}/${entityName?uncap_first}/query${sub.entityName}ByMainId' |
||||
}, |
||||
</#list> |
||||
} |
||||
} |
||||
}, |
||||
methods: { |
||||
getAllTable() { |
||||
<#if hasOne2Many==true> |
||||
let values = this.tableKeys.map(key => getRefPromise(this, key)) |
||||
return Promise.all(values) |
||||
<#else> |
||||
return new Promise(resolve => { |
||||
resolve([]); |
||||
}) |
||||
</#if> |
||||
}, |
||||
/** 调用完edit()方法之后会自动调用此方法 */ |
||||
editAfter() { |
||||
this.$nextTick(() => { |
||||
<#list subTables as sub><#rt/> |
||||
<#if sub.foreignRelationType =='1'> |
||||
this.$refs.${sub.entityName?uncap_first}Form.initFormData(this.url.${sub.entityName?uncap_first}.list,this.model.id) |
||||
</#if> |
||||
</#list> |
||||
}) |
||||
// 加载子表数据 |
||||
if (this.model.id) { |
||||
let params = { id: this.model.id } |
||||
<#list subTables as sub><#rt/> |
||||
<#if sub.foreignRelationType =='0'> |
||||
this.requestSubTableData(this.url.${sub.entityName?uncap_first}.list, params, this.${sub.entityName?uncap_first}Table) |
||||
</#if> |
||||
</#list> |
||||
} |
||||
}, |
||||
//校验所有一对一子表表单 |
||||
validateSubForm(allValues){ |
||||
return new Promise((resolve,reject)=>{ |
||||
Promise.all([ |
||||
<#list subTables as sub><#rt/> |
||||
<#if sub.foreignRelationType =='1'> |
||||
this.$refs.${sub.entityName?uncap_first}Form.validate(${sub_index}), |
||||
</#if> |
||||
</#list> |
||||
]).then(() => { |
||||
resolve(allValues) |
||||
}).catch(e => { |
||||
reject(e) |
||||
}) |
||||
}) |
||||
}, |
||||
/** 整理成formData */ |
||||
classifyIntoFormData(allValues) { |
||||
let main = Object.assign(this.model, allValues.formValue) |
||||
return { |
||||
...main, // 展开 |
||||
<#assign subManyIndex = 0> |
||||
<#list subTables as sub><#rt/> |
||||
<#if sub.foreignRelationType =='0'> |
||||
${sub.entityName?uncap_first}List: allValues.tablesValue[${subManyIndex}].values, |
||||
<#assign subManyIndex = subManyIndex+1> |
||||
<#else> |
||||
${sub.entityName?uncap_first}List: this.$refs.${sub.entityName?uncap_first}Form.getFormData(), |
||||
</#if> |
||||
</#list> |
||||
} |
||||
}, |
||||
/** 确定按钮点击事件 */ |
||||
handleOk() { |
||||
/** 触发表单验证 */ |
||||
this.getAllTable().then(tables => { |
||||
return validateFormModelAndTables(this.$refs.form,this.model, tables) |
||||
}).then(allValues => { |
||||
/** 一次性验证一对一的所有子表 */ |
||||
return this.validateSubForm(allValues) |
||||
}).then(allValues => { |
||||
if (typeof this.classifyIntoFormData !== 'function') { |
||||
throw this.throwNotFunction('classifyIntoFormData') |
||||
} |
||||
console.log("this.classifyIntoFormData",typeof this.classifyIntoFormData) |
||||
let formData = this.classifyIntoFormData(allValues) |
||||
|
||||
// 发起请求 |
||||
return this.request(formData) |
||||
}).catch(e => { |
||||
if (e.error === VALIDATE_NO_PASSED) { |
||||
// 如果有未通过表单验证的子表,就自动跳转到它所在的tab |
||||
this.activeKey = e.index == null ? this.refKeys[0] : this.refKeys[e.index+1] |
||||
} else { |
||||
console.error(e) |
||||
} |
||||
}) |
||||
}, |
||||
validateError(msg){ |
||||
this.$message.error(msg) |
||||
}, |
||||
close() { |
||||
this.visible = false |
||||
this.$emit('close') |
||||
this.$refs.form.clearValidate(); |
||||
}, |
||||
<#if form_popup> |
||||
popupCallback(value,row){ |
||||
this.model = Object.assign(this.model, row); |
||||
}, |
||||
</#if> |
||||
<#if form_cat_tree> |
||||
handleCategoryChange(value,backObj){ |
||||
this.model = Object.assign(this.model, backObj); |
||||
} |
||||
</#if> |
||||
|
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
</style> |
@ -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 ""; |
||||
|
||||
|
||||
|
||||
} |
@ -0,0 +1,72 @@
|
||||
package org.jeecg.boot.starter.lock.annotation; |
||||
|
||||
/** |
||||
* @author zyf |
||||
* @date 2019/10/26 18:26 |
||||
*/ |
||||
|
||||
/** |
||||
* 分布式锁枚举类 |
||||
* @author zyf |
||||
*/ |
||||
public enum LockConstant { |
||||
/** |
||||
* 通用锁常量 |
||||
*/ |
||||
COMMON("commonLock:", 1, 500, "请勿重复点击"); |
||||
/** |
||||
* 分布式锁前缀 |
||||
*/ |
||||
private String keyPrefix; |
||||
/** |
||||
* 等到最大时间,强制获取锁 |
||||
*/ |
||||
private int waitTime; |
||||
/** |
||||
* 锁失效时间 |
||||
*/ |
||||
private int leaseTime; |
||||
/** |
||||
* 加锁提示 |
||||
*/ |
||||
private String message; |
||||
|
||||
LockConstant(String keyPrefix, int waitTime, int leaseTime, String message) { |
||||
this.keyPrefix = keyPrefix; |
||||
this.waitTime = waitTime; |
||||
this.leaseTime = leaseTime; |
||||
this.message = message; |
||||
} |
||||
|
||||
public String getKeyPrefix() { |
||||
return keyPrefix; |
||||
} |
||||
|
||||
public void setKeyPrefix(String keyPrefix) { |
||||
this.keyPrefix = keyPrefix; |
||||
} |
||||
|
||||
public int getWaitTime() { |
||||
return waitTime; |
||||
} |
||||
|
||||
public void setWaitTime(int waitTime) { |
||||
this.waitTime = waitTime; |
||||
} |
||||
|
||||
public int getLeaseTime() { |
||||
return leaseTime; |
||||
} |
||||
|
||||
public void setLeaseTime(int leaseTime) { |
||||
this.leaseTime = leaseTime; |
||||
} |
||||
|
||||
public String getMessage() { |
||||
return message; |
||||
} |
||||
|
||||
public void setMessage(String message) { |
||||
this.message = message; |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue