JeecgBoot2.4.3版本发布——企业级低代码平台

pull/2341/head
zhangdaiscott 2021-03-17 18:43:42 +08:00
parent da5ace3397
commit c5965b10d8
131 changed files with 3851 additions and 43841 deletions

View File

@ -7,12 +7,12 @@
JEECG BOOT 低代码开发平台(前后端分离版本)
===============
当前最新版本: 2.4.2发布日期2021-01-26
当前最新版本: 2.4.3发布日期2021-03-22
[![AUR](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
[![](https://img.shields.io/badge/Author-北京国炬软件-orange.svg)](http://www.jeecg.com)
[![](https://img.shields.io/badge/version-2.4.2-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot)
[![](https://img.shields.io/badge/version-2.4.3-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot)
[![GitHub stars](https://img.shields.io/github/stars/zhangdaiscott/jeecg-boot.svg?style=social&label=Stars)](https://github.com/zhangdaiscott/jeecg-boot)
[![GitHub forks](https://img.shields.io/github/forks/zhangdaiscott/jeecg-boot.svg?style=social&label=Fork)](https://github.com/zhangdaiscott/jeecg-boot)

View File

@ -1,7 +1,7 @@
Jeecg-Boot 低代码开发平台
===============
当前最新版本: 2.4.2发布日期20210126
当前最新版本: 2.4.3发布日期20210322
## 后端技术架构

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

View File

@ -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';

View File

@ -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

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-base-api</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.4.2</version>
<version>2.4.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
@ -140,7 +141,7 @@ public interface ISysBaseAPI extends CommonAPI {
* 15 busType busId
*/
@GetMapping("/sys/api/updateSysAnnounReadFlag")
public void updateSysAnnounReadFlag(@RequestParam("busType") String busType, @RequestParam("busId") String busId);
public void updateSysAnnounReadFlag(@RequestParam("busType") String busType, @RequestParam("busId")String busId);
/**
* 16
@ -177,7 +178,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return
*/
@GetMapping("/sys/api/queryAllUser")
public JSONObject queryAllUser(@RequestParam(name = "userIds", required = false) String userIds, @RequestParam(name = "pageNo", required = false) Integer pageNo, @RequestParam(name = "pageSize", required = false) int pageSize);
public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) int pageSize);
/**
@ -186,7 +187,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return
*/
@GetMapping("/sys/api/queryAllRole")
public List<ComboModel> queryAllRole(@RequestParam(name = "roleIds", required = false) String[] roleIds);
public List<ComboModel> queryAllRole(@RequestParam(name = "roleIds",required = false)String[] roleIds);
/**
* 21Id
@ -194,7 +195,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return
*/
@GetMapping("/sys/api/getRoleIdsByUsername")
public List<String> getRoleIdsByUsername(@RequestParam("username") String username);
public List<String> getRoleIdsByUsername(@RequestParam("username")String username);
/**
* 22id
@ -202,7 +203,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return
*/
@GetMapping("/sys/api/getDepartIdsByOrgCode")
public String getDepartIdsByOrgCode(@RequestParam("orgCode") String orgCode);
public String getDepartIdsByOrgCode(@RequestParam("orgCode")String orgCode);
/**
* 23
@ -217,7 +218,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return
*/
@GetMapping("/sys/api/getParentDepartId")
DictModel getParentDepartId(@RequestParam("departId") String departId);
DictModel getParentDepartId(@RequestParam("departId")String departId);
/**
* 25Id
@ -233,7 +234,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @param cmd
*/
@GetMapping("/sys/api/sendWebSocketMsg")
public void sendWebSocketMsg(@RequestParam("userIds") String[] userIds, @RequestParam("cmd") String cmd);
public void sendWebSocketMsg(@RequestParam("userIds")String[] userIds, @RequestParam("cmd") String cmd);
/**
* 27id
@ -250,7 +251,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @param userId
*/
@GetMapping("/sys/api/meetingSignWebsocket")
void meetingSignWebsocket(@RequestParam("userId") String userId);
void meetingSignWebsocket(@RequestParam("userId")String userId);
/**
* 29name
@ -258,7 +259,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return
*/
@GetMapping("/sys/api/queryUserByNames")
List<LoginUser> queryUserByNames(@RequestParam("userNames") String[] userNames);
List<LoginUser> queryUserByNames(@RequestParam("userNames")String[] userNames);
/**
@ -267,7 +268,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return
*/
@GetMapping("/sys/api/getUserRoleSet")
Set<String> getUserRoleSet(@RequestParam("username") String username);
Set<String> getUserRoleSet(@RequestParam("username")String username);
/**
* 31
@ -308,7 +309,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return
*/
@GetMapping("/sys/api/queryUserRoles")
Set<String> queryUserRoles(@RequestParam("username") String username);
Set<String> queryUserRoles(@RequestParam("username")String username);
/**
* 36
@ -316,7 +317,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return
*/
@GetMapping("/sys/api/queryUserAuths")
Set<String> queryUserAuths(@RequestParam("username") String username);
Set<String> queryUserAuths(@RequestParam("username")String username);
/**
* 37 id DynamicDataSourceModel
@ -368,7 +369,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return
*/
@GetMapping("/sys/api/queryPermissionDataRule")
List<SysPermissionDataRuleModel> queryPermissionDataRule(@RequestParam("component") String component, @RequestParam("requestPath") String requestPath, @RequestParam("username") String username);
List<SysPermissionDataRuleModel> queryPermissionDataRule(@RequestParam("component") String component, @RequestParam("requestPath")String requestPath, @RequestParam("username") String username);
/**
* 43
@ -408,7 +409,7 @@ public interface ISysBaseAPI extends CommonAPI {
*/
@GetMapping("/sys/api/queryDepartsByOrgIds")
List<JSONObject> queryDepartsByOrgIds(String ids);
/**
* 40
* @param email
@ -416,5 +417,11 @@ public interface ISysBaseAPI extends CommonAPI {
* @param content
*/
@GetMapping("/sys/api/sendEmailMsg")
void sendEmailMsg(@RequestParam("email") String email, @RequestParam("title") String title, @RequestParam("content") String content);
void sendEmailMsg(@RequestParam("email")String email,@RequestParam("title")String title,@RequestParam("content")String content);
/**
* 41 id
* @param orgCode
*/
@GetMapping("/sys/api/getDeptUserByOrgCode")
List<Map> getDeptUserByOrgCode(@RequestParam("orgCode")String orgCode);
}

View File

@ -9,6 +9,7 @@ import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
@ -259,6 +260,11 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
}
@Override
public List<Map> getDeptUserByOrgCode(String orgCode) {
return null;
}
@Override
public List<JSONObject> queryDepartsByOrgIds(String ids) {
return null;

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-base-api</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.4.2</version>
<version>2.4.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -1,12 +1,16 @@
package org.jeecg.common.system.api;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.api.dto.OnlineAuthDTO;
import org.jeecg.common.api.dto.message.*;
import org.jeecg.common.system.vo.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
@ -280,5 +284,9 @@ public interface ISysBaseAPI extends CommonAPI {
* @param content
*/
void sendEmailMsg(String email,String title,String content);
/**
* 41
* @param orgCode
*/
List<Map> getDeptUserByOrgCode(String orgCode);
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-base</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.4.2</version>
<version>2.4.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-base</artifactId>
<version>2.4.2</version>
<version>2.4.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -101,6 +101,21 @@
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${dynamic-datasource-spring-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<exclusions>
<exclusion>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>hibernate-re</artifactId>
<version>2.4.3-RC</version>
</dependency>
<!--mysql-->
<dependency>
@ -150,21 +165,6 @@
<artifactId>shiro-spring-boot-starter</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>hibernate-re</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<exclusions>
<exclusion>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- shiro-redis -->
<dependency>
<groupId>org.crazycake</groupId>
@ -185,16 +185,6 @@
<version>${knife4j-spring-boot-starter.version}</version>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- 代码生成器 -->
<!-- 如下载失败,请参考此文档 http://doc.jeecg.com/2043876 -->
<dependency>

View File

@ -70,7 +70,7 @@ public class PermissionDataAspect {
String url = "";
if(oConvertUtils.isNotEmpty(requestPath)){
url = requestPath.replace("\\", "/");
url = requestPath.replace("//", "/");
url = url.replace("//", "/");
if(url.indexOf("//")>=0){
url = filterUrl(url);
}

View File

@ -265,7 +265,7 @@ public interface CommonConstant {
/**
* 线
*/
public static final String IM_PREFIX_USER_FRIEND_CACHE = "im_prefix_user_friend_";
public static final String IM_PREFIX_USER_FRIEND_CACHE = "sys:cache:im:im_prefix_user_friend_";
/**
* 1 2
@ -294,7 +294,7 @@ public interface CommonConstant {
/**
*
*/
public final static String TENANT_ID = "tenant_id";
public final static String TENANT_ID = "tenant-id";
/**
*

View File

@ -12,6 +12,8 @@ public interface CommonSendStatus {
public static final String PUBLISHED_STATUS_1 = "1"; //已发布
public static final String REVOKE_STATUS_2 = "2"; //撤销
//app端推送会话标识后缀
public static final String APP_SESSION_SUFFIX = "_app"; //app端推送会话标识后缀

View File

@ -6,6 +6,7 @@ public interface DataBaseConstant {
//*********数据库类型****************************************
public static final String DB_TYPE_MYSQL = "MYSQL";
public static final String DB_TYPE_ORACLE = "ORACLE";
public static final String DB_TYPE_DM = "DM";//达梦数据库
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";

View File

@ -1,6 +1,8 @@
package org.jeecg.common.system.base.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
@ -13,6 +15,7 @@ import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@ -23,9 +26,7 @@ import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -76,6 +77,55 @@ public class JeecgController<T, S extends IService<T>> {
mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
return mv;
}
/**
* sheetsheet
*
* @param request
* @param object
* @param clazz class
* @param title
* @param exportFields
* @param pageNum sheet
* @param request
*/
protected ModelAndView exportXlsSheet(HttpServletRequest request, T object, Class<T> clazz, String title,String exportFields,Integer pageNum) {
// Step.1 组装查询条件
QueryWrapper<T> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap());
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
// Step.2 计算分页sheet数据
double total = service.count();
int count = (int)Math.ceil(total/pageNum);
// Step.3 多sheet处理
List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
for (int i = 1; i <=count ; i++) {
Page<T> page = new Page<T>(i, pageNum);
IPage<T> pageList = service.page(page, queryWrapper);
List<T> records = pageList.getRecords();
List<T> exportList = null;
// 过滤选中数据
String selections = request.getParameter("selections");
if (oConvertUtils.isNotEmpty(selections)) {
List<String> selectionList = Arrays.asList(selections.split(","));
exportList = records.stream().filter(item -> selectionList.contains(getId(item))).collect(Collectors.toList());
} else {
exportList = records;
}
Map<String, Object> map = new HashMap<String, Object>();
ExportParams exportParams=new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title+i,upLoadPath);
exportParams.setType(ExcelType.XSSF);
//map.put("title",exportParams);//表格Title
map.put(NormalExcelConstants.PARAMS,exportParams);//表格Title
map.put(NormalExcelConstants.CLASS,clazz);//表格对应实体
map.put(NormalExcelConstants.DATA_LIST, exportList);//数据集合
listMap.add(map);
}
// Step.4 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
mv.addObject(NormalExcelConstants.FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
mv.addObject(NormalExcelConstants.MAP_LIST, listMap);
return mv;
}
/**
* excel

View File

@ -72,7 +72,7 @@ public class WebMvcConfiguration implements WebMvcConfigurer {
}
/**
* Longjson
* Longjson
* @Return: void
*/
@Override

View File

@ -230,13 +230,14 @@ public class ShiroConfig {
RedisManager redisManager = new RedisManager();
redisManager.setHost(lettuceConnectionFactory.getHostName());
redisManager.setPort(lettuceConnectionFactory.getPort());
redisManager.setDatabase(lettuceConnectionFactory.getDatabase());
redisManager.setTimeout(0);
if (!StringUtils.isEmpty(lettuceConnectionFactory.getPassword())) {
redisManager.setPassword(lettuceConnectionFactory.getPassword());
}
manager = redisManager;
}else{
// redis 集群支持,优先使用集群配置 add by jzyadmin@163.com
// redis集群支持,优先使用集群配置
RedisClusterManager redisManager = new RedisClusterManager();
Set<HostAndPort> portSet = new HashSet<>();
lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().forEach(node -> portSet.add(new HostAndPort(node.getHost() , node.getPort())));

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-base</artifactId>
<version>2.4.2</version>
<version>2.4.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<description>公共模块</description>
@ -17,6 +17,15 @@
<artifactId>spring-boot-starter-web</artifactId>
<optional>true</optional>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!--加载hutool-->
<dependency>
<groupId>cn.hutool</groupId>

View File

@ -52,7 +52,7 @@ public interface CacheConstant {
/**
* gateway
*/
public static final String GATEWAY_ROUTES = "gateway_routes";
public static final String GATEWAY_ROUTES = "sys:cache:cloud:gateway_routes";
/**
@ -70,4 +70,15 @@ public interface CacheConstant {
*
*/
public static final String PLUGIN_MALL_PAGE_LIST = "pluginMall::queryPageList";
/**
* onlinekey
*/
public static final String ONLINE_LIST = "sys:cache:online:list";
/**
* onlinekey
*/
public static final String ONLINE_FORM = "sys:cache:online:form";
}

View File

@ -1,4 +1,4 @@
package org.jeecg.boot.starter.redis.client;
package org.jeecg.common.modules.redis.client;
import org.jeecg.common.base.BaseMap;
import org.jeecg.common.constant.GlobalConstants;
@ -6,7 +6,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.Resource;
import java.util.Map;
/**
* redis
@ -14,7 +13,7 @@ import java.util.Map;
@Configuration
public class JeecgRedisClient {
@Resource(name = "starterRedisTemplate")
@Resource
private RedisTemplate<String, Object> redisTemplate;
@ -30,15 +29,4 @@ public class JeecgRedisClient {
}
/**
* key
*
* @param key
* @return
*/
public <T> T get(String key) {
return key == null ? null : (T) redisTemplate.opsForValue().get(key);
}
}

View File

@ -1,11 +1,17 @@
package org.jeecg.config.redis;
package org.jeecg.common.modules.redis.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.GlobalConstants;
import org.jeecg.common.modules.redis.receiver.RedisReceiver;
import org.jeecg.common.modules.redis.writer.JeecgRedisCacheWriter;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
@ -14,8 +20,12 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.*;
import javax.annotation.Resource;
@ -25,7 +35,8 @@ import static java.util.Collections.singletonMap;
/**
*
* @Return:
* @author zyf
* @Return:
*/
@Slf4j
@EnableCaching
@ -57,27 +68,24 @@ public class RedisConfig extends CachingConfigurerSupport {
/**
* RedisTemplate
*
* @param lettuceConnectionFactory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
log.info(" --- redis config init --- ");
// 设置序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);
om.enableDefaultTyping(DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置redisTemplate
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer =jacksonSerializer();
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);// key序列化
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
// key序列化
redisTemplate.setKeySerializer(stringSerializer);
// value序列化
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// Hash key序列化
redisTemplate.setHashKeySerializer(stringSerializer);
// Hash value序列化
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@ -94,19 +102,53 @@ public class RedisConfig extends CachingConfigurerSupport {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(6));
RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
// 以锁写入的方式创建RedisCacheWriter对象
//RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(factory);
//update-begin-author:taoyan date:20210316 for:注解CacheEvict根据key删除redis支持通配符*
RedisCacheWriter writer = new JeecgRedisCacheWriter(factory, Duration.ofMillis(50L));
//RedisCacheWriter.lockingRedisCacheWriter(factory);
// 创建默认缓存配置对象
/* 默认配置,设置缓存有效期 1小时*/
//RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1));
/* 自定义配置test:demo 的超时时间为 5分钟*/
RedisCacheManager cacheManager = RedisCacheManager.builder(RedisCacheWriter.lockingRedisCacheWriter(factory)).cacheDefaults(redisCacheConfiguration)
RedisCacheManager cacheManager = RedisCacheManager.builder(writer).cacheDefaults(redisCacheConfiguration)
.withInitialCacheConfigurations(singletonMap(CacheConstant.TEST_DEMO_CACHE, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)).disableCachingNullValues()))
.withInitialCacheConfigurations(singletonMap(CacheConstant.PLUGIN_MALL_RANKING, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(24)).disableCachingNullValues()))
.withInitialCacheConfigurations(singletonMap(CacheConstant.PLUGIN_MALL_PAGE_LIST, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(24)).disableCachingNullValues()))
.transactionAware().build();
//update-end-author:taoyan date:20210316 for:注解CacheEvict根据key删除redis支持通配符*
return cacheManager;
}
/**
* redis
*
* @param redisConnectionFactory redis
* @return
*/
@Bean
public RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory, RedisReceiver redisReceiver, MessageListenerAdapter commonListenerAdapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory);
container.addMessageListener(commonListenerAdapter, new ChannelTopic(GlobalConstants.REDIS_TOPIC_NAME));
return container;
}
@Bean
MessageListenerAdapter commonListenerAdapter(RedisReceiver redisReceiver) {
MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(redisReceiver, "onMessage");
messageListenerAdapter.setSerializer(jacksonSerializer());
return messageListenerAdapter;
}
private Jackson2JsonRedisSerializer jacksonSerializer() {
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
return jackson2JsonRedisSerializer;
}
}

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -6,7 +6,6 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jeecg.common.exception.JeecgBootException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-parent</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.4.2</version>
<version>2.4.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-parent</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.4.2</version>
<version>2.4.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -16,10 +16,14 @@
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-base-core</artifactId>
</dependency>
<!-- 引入微服务启动依赖 starter
<!--引入微服务启动依赖 starter
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-starter-cloud</artifactId>
</dependency> -->
</dependency>
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-starter-job</artifactId>
</dependency>-->
</dependencies>
</project>

View File

@ -149,7 +149,8 @@ public class JeecgDemoController extends JeecgController<JeecgDemo, IJeecgDemoSe
public ModelAndView exportXls(HttpServletRequest request, JeecgDemo jeecgDemo) {
//获取导出表格字段
String exportFields = jeecgDemoService.getExportFields();
return super.exportXls(request, jeecgDemo, JeecgDemo.class, "单表模型",exportFields);
//分sheet导出表格字段
return super.exportXlsSheet(request, jeecgDemo, JeecgDemo.class, "单表模型",exportFields,500);
}
/**
@ -281,19 +282,4 @@ public class JeecgDemoController extends JeecgController<JeecgDemo, IJeecgDemoSe
return Result.OK(pageList);
}
/*----------------------------------------外部获取权限示例------------------------------------*/
// /**
// * 测试MQ
// */
// @GetMapping(value = "/rabbitMqClientTest")
// public Result<?> rabbitMqClientTest(HttpServletRequest req) {
// BaseMap map = new BaseMap();
// map.put("orderId", RandomUtil.randomNumbers(10));
// rabbitMqClient.sendMessage("jeecg_place_order", map);
// rabbitMqClient.sendMessage("jeecg_place_order_time", map,10);
// return Result.OK();
// }
// @Autowired
// private RabbitMqClient rabbitMqClient;
}

View File

@ -175,7 +175,7 @@ public class JoaDemoController {
/**
* excel
*
* @param requestFieldPresenceUtil
* @param request
* @param response
*/
@RequestMapping(value = "/exportXls")

View File

@ -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");
// }
//
//}
//

View File

@ -10,6 +10,6 @@ WORKDIR /jeecg-boot
EXPOSE 8080
ADD ./target/jeecg-boot-module-system-2.4.2.jar ./
ADD ./target/jeecg-boot-module-system-2.4.3.jar ./
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-2.4.2.jar
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-2.4.3.jar

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-parent</artifactId>
<version>2.4.2</version>
<version>2.4.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -34,10 +34,6 @@
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-system-local-api</artifactId>
</dependency>
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-starter-redis</artifactId>
</dependency>
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-module-demo</artifactId>
@ -47,11 +43,11 @@
<dependency>
<groupId>org.jeecgframework.jimureport</groupId>
<artifactId>spring-boot-starter-jimureport</artifactId>
<version>1.2.0</version>
<version>1.2.1</version>
<exclusions>
<exclusion>
<artifactId>autopoi-web</artifactId>
<groupId>org.jeecgframework</groupId>
<artifactId>autopoi-web</artifactId>
</exclusion>
</exclusions>
</dependency>

View File

@ -5,6 +5,7 @@ import org.apache.catalina.Context;
import org.apache.tomcat.util.scan.StandardJarScanner;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.boot.SpringApplication;
//import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
@ -40,5 +41,7 @@ public class JeecgSystemApplication extends SpringBootServletInitializer {
"External: \thttp://" + ip + ":" + port + path + "/\n\t" +
"Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n" +
"----------------------------------------------------------");
}
}

View File

@ -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
* onlineDB使jeecg_database.properties;
* 使GUIjeecg_database.properties
* @author: scott
* @date: 20210218 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;
}
}

View File

@ -1,7 +1,9 @@
package org.jeecg.config.jimureport;
import org.jeecg.common.constant.DataBaseConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.SysUserCacheInfo;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
@ -10,14 +12,16 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* ()
* 1.token
* 2.
*/
* ()
* * 1.token
* * 2.
*/
@Component
class JimuReportTokenService implements JmReportTokenServiceI {
public class JimuReportTokenService implements JmReportTokenServiceI {
@Autowired
private ISysBaseAPI sysBaseAPI;
@Autowired
@ -38,4 +42,18 @@ class JimuReportTokenService implements JmReportTokenServiceI {
public Boolean verifyToken(String token) {
return TokenUtils.verifyToken(token, sysBaseAPI, redisUtil);
}
@Override
public Map<String, Object> getUserInfo(String token) {
String username = JwtUtil.getUsername(token);
//此处通过token只能拿到一个信息 用户账号 后面的就是根据账号获取其他信息 查询数据或是走redis 用户根据自身业务可自定义
SysUserCacheInfo userInfo = sysBaseAPI.getCacheUser(username);
Map<String, Object> map = new HashMap<String, Object>();
//设置账号名
map.put(SYS_USER_CODE, userInfo.getSysUserCode());
//设置部门编码
map.put(SYS_ORG_CODE, userInfo.getSysOrgCode());
// 将所有信息存放至map 解析sql/api会根据map的键值解析
return map;
}
}

View File

@ -1,8 +1,8 @@
package org.jeecg.modules.api.controller;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.common.api.dto.OnlineAuthDTO;
import org.jeecg.common.api.dto.message.*;
import org.jeecg.common.api.dto.OnlineAuthDTO;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.*;
import org.jeecg.modules.system.service.ISysUserService;
@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -521,4 +522,12 @@ public class SystemAPIController {
public void sendEmailMsg(@RequestParam("email")String email,@RequestParam("title")String title,@RequestParam("content")String content){
this.sysBaseAPI.sendEmailMsg(email,title,content);
};
/**
* 41
* @param orgCode
*/
@GetMapping("/getDeptUserByOrgCode")
List<Map> getDeptUserByOrgCode(@RequestParam("orgCode")String orgCode){
return this.sysBaseAPI.getDeptUserByOrgCode(orgCode);
}
}

View File

@ -59,6 +59,7 @@ public class SendMsgJob implements Job {
// 发送消息成功
sysMessage.setEsSendStatus(SendMsgStatusEnum.SUCCESS.getCode());
} catch (Exception e) {
e.printStackTrace();
// 发送消息出现异常
sysMessage.setEsSendStatus(SendMsgStatusEnum.FAIL.getCode());
}

View File

@ -1,14 +1,17 @@
package org.jeecg.modules.message.websocket;
import cn.hutool.core.util.ObjectUtil;
import org.jeecg.boot.starter.redis.listener.JeecgRedisListerer;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.base.BaseMap;
import org.jeecg.common.constant.CommonSendStatus;
import org.jeecg.common.modules.redis.listener.JeecgRedisListerer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* (redis)
*/
@Slf4j
@Component
public class SocketHandler implements JeecgRedisListerer {
@ -17,10 +20,14 @@ public class SocketHandler implements JeecgRedisListerer {
@Override
public void onMessage(BaseMap map) {
log.info("【SocketHandler消息】Redis Listerer:" + map.toString());
String userId = map.get("userId");
String message = map.get("message");
if (ObjectUtil.isNotEmpty(userId)) {
webSocket.pushMessage(userId, message);
//app端消息推送
webSocket.pushMessage(userId+CommonSendStatus.APP_SESSION_SUFFIX, message);
} else {
webSocket.pushMessage(message);
}

View File

@ -1,6 +1,5 @@
package org.jeecg.modules.message.websocket;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
@ -13,11 +12,9 @@ import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import cn.hutool.core.util.ObjectUtil;
import org.jeecg.boot.starter.redis.client.JeecgRedisClient;
import org.jeecg.boot.starter.redis.listener.JeecgRedisListerer;
import org.jeecg.common.base.BaseMap;
import org.jeecg.common.constant.WebsocketConst;
import org.jeecg.common.modules.redis.client.JeecgRedisClient;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;
@ -43,6 +40,9 @@ public class WebSocket {
@Resource
private JeecgRedisClient jeecgRedisClient;
/**
* webSocketclass
*/
private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>();
private static Map<String, Session> sessionPool = new HashMap<String, Session>();
@ -105,8 +105,10 @@ public class WebSocket {
//todo 现在有个定时任务刷,应该去掉
log.debug("【websocket消息】收到客户端消息:" + message);
JSONObject obj = new JSONObject();
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK);//业务类型
obj.put(WebsocketConst.MSG_TXT, "心跳响应");//消息内容
//业务类型
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK);
//消息内容
obj.put(WebsocketConst.MSG_TXT, "心跳响应");
for (WebSocket webSocket : webSockets) {
webSocket.pushMessage(message);
}

View File

@ -1,8 +1,7 @@
package org.jeecg.modules.system.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.SqlInjectionUtil;
@ -13,7 +12,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
/**
* @Title: DuplicateCheckAction
@ -29,7 +30,7 @@ import javax.servlet.http.HttpServletRequest;
public class DuplicateCheckController {
@Autowired
SysDictMapper sysDictMapper;
SysDictMapper sysDictMapper;
/**
*

View File

@ -109,7 +109,9 @@ public class LoginController {
//用户登录信息
userInfo(sysUser, result);
//update-begin--Author:wangshuai Date:20200714 for登录日志没有记录人员
//update-begin--Author:liusq Date:20210126 for登录成功删除redis中的验证码
redisUtil.del(realKey);
//update-begin--Author:liusq Date:20210126 for登录成功删除redis中的验证码
LoginUser loginUser = new LoginUser();
BeanUtils.copyProperties(sysUser, loginUser);
baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser);

View File

@ -114,6 +114,24 @@ public class SysDepartController {
return result;
}
/**
* list
*
* @return
*/
@RequestMapping(value = "/queryDepartTreeSync", method = RequestMethod.GET)
public Result<List<SysDepartTreeModel>> queryDepartTreeSync(@RequestParam(name = "pid", required = false) String parentId) {
Result<List<SysDepartTreeModel>> result = new Result<>();
try {
List<SysDepartTreeModel> list = sysDepartService.queryTreeListByPid(parentId);
result.setResult(list);
result.setSuccess(true);
} catch (Exception e) {
log.error(e.getMessage(),e);
}
return result;
}
/**
* ,
*
@ -333,7 +351,7 @@ public class SysDepartController {
params.setNeedSave(true);
try {
// orgCode编码长度
int codeLength = YouBianCodeUtil.zhanweiLength;
int codeLength = YouBianCodeUtil.zhanweiLength;
listSysDeparts = ExcelImportUtil.importExcel(file.getInputStream(), SysDepart.class, params);
//按长度排序
Collections.sort(listSysDeparts, new Comparator<SysDepart>() {
@ -363,9 +381,9 @@ public class SysDepartController {
}else{
sysDepart.setParentId("");
}
//update-begin---author:liusq Date:20210223 for批量导入部门以后不能追加下一级部门 #2245------------
//update-begin---author:liusq Date:20210223 for批量导入部门以后不能追加下一级部门 #2245------------
sysDepart.setOrgType(sysDepart.getOrgCode().length()/codeLength+"");
//update-end---author:liusq Date:20210223 for批量导入部门以后不能追加下一级部门 #2245------------
//update-end---author:liusq Date:20210223 for批量导入部门以后不能追加下一级部门 #2245------------
sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
ImportExcelUtil.importDateSaveOne(sysDepart, ISysDepartService.class, errorMessageList, num, CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE);
num++;

View File

@ -31,6 +31,7 @@ import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.result.ExcelImportResult;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -66,8 +67,8 @@ public class SysDictController {
public RedisTemplate<String, Object> redisTemplate;
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Result<IPage<SysDict>> queryPageList(SysDict sysDict, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize, HttpServletRequest req) {
public Result<IPage<SysDict>> queryPageList(SysDict sysDict,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
Result<IPage<SysDict>> result = new Result<IPage<SysDict>>();
QueryWrapper<SysDict> queryWrapper = QueryGenerator.initQueryWrapper(sysDict, req.getParameterMap());
Page<SysDict> page = new Page<SysDict>(pageNo, pageSize);
@ -91,8 +92,8 @@ public class SysDictController {
*/
@SuppressWarnings("unchecked")
@RequestMapping(value = "/treeList", method = RequestMethod.GET)
public Result<List<SysDictTree>> treeList(SysDict sysDict, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize, HttpServletRequest req) {
public Result<List<SysDictTree>> treeList(SysDict sysDict,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
Result<List<SysDictTree>> result = new Result<>();
LambdaQueryWrapper<SysDict> query = new LambdaQueryWrapper<>();
// 构造查询条件
@ -118,7 +119,7 @@ public class SysDictController {
* @return
*/
@RequestMapping(value = "/getDictItems/{dictCode}", method = RequestMethod.GET)
public Result<List<DictModel>> getDictItems(@PathVariable String dictCode, @RequestParam(value = "sign",required = false) String sign, HttpServletRequest request) {
public Result<List<DictModel>> getDictItems(@PathVariable String dictCode, @RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
log.info(" dictCode : "+ dictCode);
Result<List<DictModel>> result = new Result<List<DictModel>>();
List<DictModel> ls = null;
@ -203,9 +204,9 @@ public class SysDictController {
*/
@RequestMapping(value = "/loadDict/{dictCode}", method = RequestMethod.GET)
public Result<List<DictModel>> loadDict(@PathVariable String dictCode,
@RequestParam(name="keyword") String keyword,
@RequestParam(value = "sign",required = false) String sign,
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
@RequestParam(name="keyword") String keyword,
@RequestParam(value = "sign",required = false) String sign,
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
log.info(" 加载字典表数据,加载关键字: "+ keyword);
Result<List<DictModel>> result = new Result<List<DictModel>>();
List<DictModel> ls = null;
@ -240,7 +241,7 @@ public class SysDictController {
* codetext
*/
@RequestMapping(value = "/loadDictItem/{dictCode}", method = RequestMethod.GET)
public Result<List<String>> loadDictItem(@PathVariable String dictCode, @RequestParam(name="key") String keys, @RequestParam(value = "sign",required = false) String sign, HttpServletRequest request) {
public Result<List<String>> loadDictItem(@PathVariable String dictCode,@RequestParam(name="key") String keys, @RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
Result<List<String>> result = new Result<>();
try {
if(dictCode.indexOf(",")!=-1) {
@ -271,13 +272,13 @@ public class SysDictController {
*/
@SuppressWarnings("unchecked")
@RequestMapping(value = "/loadTreeData", method = RequestMethod.GET)
public Result<List<TreeSelectModel>> loadTreeData(@RequestParam(name="pid") String pid, @RequestParam(name="pidField") String pidField,
@RequestParam(name="tableName") String tbname,
@RequestParam(name="text") String text,
@RequestParam(name="code") String code,
@RequestParam(name="hasChildField") String hasChildField,
@RequestParam(name="condition") String condition,
@RequestParam(value = "sign",required = false) String sign, HttpServletRequest request) {
public Result<List<TreeSelectModel>> loadTreeData(@RequestParam(name="pid") String pid,@RequestParam(name="pidField") String pidField,
@RequestParam(name="tableName") String tbname,
@RequestParam(name="text") String text,
@RequestParam(name="code") String code,
@RequestParam(name="hasChildField") String hasChildField,
@RequestParam(name="condition") String condition,
@RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
Result<List<TreeSelectModel>> result = new Result<List<TreeSelectModel>>();
Map<String, String> query = null;
if(oConvertUtils.isNotEmpty(condition)) {
@ -302,9 +303,9 @@ public class SysDictController {
@Deprecated
@GetMapping("/queryTableData")
public Result<List<DictModel>> queryTableData(DictQuery query,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sign",required = false) String sign, HttpServletRequest request){
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sign",required = false) String sign,HttpServletRequest request){
Result<List<DictModel>> res = new Result<List<DictModel>>();
// SQL注入漏洞 sign签名校验
String dictCode = query.getTable()+","+query.getText()+","+query.getCode();
@ -320,7 +321,7 @@ public class SysDictController {
* @param sysDict
* @return
*/
@RequiresRoles({"admin"})
//@RequiresRoles({"admin"})
@RequestMapping(value = "/add", method = RequestMethod.POST)
public Result<SysDict> add(@RequestBody SysDict sysDict) {
Result<SysDict> result = new Result<SysDict>();
@ -341,7 +342,7 @@ public class SysDictController {
* @param sysDict
* @return
*/
@RequiresRoles({"admin"})
//@RequiresRoles({"admin"})
@RequestMapping(value = "/edit", method = RequestMethod.PUT)
public Result<SysDict> edit(@RequestBody SysDict sysDict) {
Result<SysDict> result = new Result<SysDict>();
@ -363,7 +364,7 @@ public class SysDictController {
* @param id
* @return
*/
@RequiresRoles({"admin"})
//@RequiresRoles({"admin"})
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
@CacheEvict(value=CacheConstant.SYS_DICT_CACHE, allEntries=true)
public Result<SysDict> delete(@RequestParam(name="id",required=true) String id) {
@ -382,7 +383,7 @@ public class SysDictController {
* @param ids
* @return
*/
@RequiresRoles({"admin"})
//@RequiresRoles({"admin"})
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
@CacheEvict(value= CacheConstant.SYS_DICT_CACHE, allEntries=true)
public Result<SysDict> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
@ -425,7 +426,7 @@ public class SysDictController {
* @param request
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(SysDict sysDict, HttpServletRequest request) {
public ModelAndView exportXls(SysDict sysDict,HttpServletRequest request) {
// Step.1 组装查询条件
QueryWrapper<SysDict> queryWrapper = QueryGenerator.initQueryWrapper(sysDict, request.getParameterMap());
//Step.2 AutoPoi 导出Excel
@ -461,7 +462,7 @@ public class SysDictController {
* @param
* @return
*/
@RequiresRoles({"admin"})
//@RequiresRoles({"admin"})
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

View File

@ -298,7 +298,6 @@ public class SysUserController {
/**
*
*/
//@RequiresRoles({"admin"})
@RequestMapping(value = "/changePassword", method = RequestMethod.PUT)
public Result<?> changePassword(@RequestBody SysUser sysUser) {
SysUser u = this.sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, sysUser.getUsername()));

View File

@ -52,4 +52,25 @@ public interface SysDepartMapper extends BaseMapper<SysDepart> {
*/
List<String> getSubDepIdsByOrgCodes(@org.apache.ibatis.annotations.Param("orgCodes") String[] orgCodes);
List<SysDepart> queryTreeListByPid(@Param("parentId") String parentId);
/**
* id
* @param parentId
* @return
*/
@Select("SELECT count(*) FROM sys_depart where del_flag ='0' AND parent_id = #{parentId,jdbcType=VARCHAR}")
Integer queryCountByPid(@Param("parentId")String parentId);
/**
* OrgCod
* @param orgCode
* @return
*/
SysDepart queryCompByOrgCode(@Param("orgCode")String orgCode);
/**
* id
* @param parentId
* @return
*/
@Select("SELECT * FROM sys_depart where del_flag ='0' AND parent_id = #{parentId,jdbcType=VARCHAR}")
List<SysDepart> queryDeptByPid(@Param("parentId")String parentId);
}

View File

@ -33,5 +33,22 @@
org_code LIKE CONCAT(#{item},'%')
</foreach>
</select>
<!--根据parent_id查询下级部门-->
<select id="queryTreeListByPid" parameterType="Object" resultType="org.jeecg.modules.system.entity.SysDepart">
SELECT * FROM sys_depart where del_flag = '0'
<choose>
<when test="parentId != null and parentId != ''">
AND parent_id = #{parentId,jdbcType=VARCHAR}
</when>
<otherwise>
AND parent_id is null or parent_id=''
</otherwise>
</choose>
order by depart_order
</select>
<!-- 根据OrgCod查询公司信息 -->
<select id="queryCompByOrgCode" resultType="org.jeecg.modules.system.entity.SysDepart">
select * from sys_depart where del_flag = '0' and org_category='1' and org_code= #{orgCode,jdbcType=VARCHAR}
</select>
</mapper>

View File

@ -107,4 +107,19 @@ public interface ISysDepartService extends IService<SysDepart>{
* @return
*/
List<SysDepartTreeModel> queryTreeByKeyWord(String keyWord);
/**
*
* @return
*/
List<SysDepartTreeModel> queryTreeListByPid(String parentId);
/**
*
* @return
*/
SysDepart queryCompByOrgCode(String orgCode);
/**
*
* @return
*/
List<SysDepart> queryDeptByPid(String pid);
}

View File

@ -1,4 +1,6 @@
package org.jeecg.modules.system.service.impl;
import java.util.HashMap;
import java.util.ArrayList;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
@ -991,4 +993,42 @@ public class SysBaseApiImpl implements ISysBaseAPI {
emailHandle.SendMsg(email, title, content);
}
/**
* id
* @param orgCode
* @return
*/
@Override
public List<Map> getDeptUserByOrgCode(String orgCode) {
//1.获取公司信息
SysDepart comp=sysDepartService.queryCompByOrgCode(orgCode);
if(comp!=null){
//2.获取公司下级部门
List<SysDepart> departs=sysDepartService.queryDeptByPid(comp.getId());
//3.获取部门下的人员信息
List<Map> list=new ArrayList();
//4.处理部门和下级用户数据
for (SysDepart dept:departs) {
Map map=new HashMap();
//部门名称
String departName = dept.getDepartName();
//根据部门编码获取下级部门id
List<String> listIds = departMapper.getSubDepIdsByDepId(dept.getId());
//根据下级部门ids获取下级部门的所有用户
List<SysUserDepart> userList = sysUserDepartService.list(new QueryWrapper<SysUserDepart>().in("dep_id",listIds));
List<String> userIds = new ArrayList<>();
for(SysUserDepart userDepart : userList){
if(!userIds.contains(userDepart.getUserId())){
userIds.add(userDepart.getUserId());
}
}
map.put("name",departName);
map.put("ids",userIds);
list.add(map);
}
return list;
}
return null;
}
}

View File

@ -454,7 +454,47 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
}
return treelist;
}
/**
/**
* parentId
* @param parentId
* @return
*/
@Override
public List<SysDepartTreeModel> queryTreeListByPid(String parentId) {
List<SysDepart> list = this.baseMapper.queryTreeListByPid(parentId);
List<SysDepartTreeModel> records = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
SysDepart depart = list.get(i);
SysDepartTreeModel treeModel = new SysDepartTreeModel(depart);
//TODO 异步树加载key拼接__+时间戳,以便于每次展开节点会刷新数据
treeModel.setKey(treeModel.getKey()+"__"+System.currentTimeMillis());
Integer count=this.baseMapper.queryCountByPid(depart.getId());
if(count>0){
treeModel.setIsLeaf(false);
}else{
treeModel.setIsLeaf(true);
}
records.add(treeModel);
}
return records;
}
@Override
public SysDepart queryCompByOrgCode(String orgCode) {
int length = YouBianCodeUtil.zhanweiLength;
String compyOrgCode = orgCode.substring(0,length);
return this.baseMapper.queryCompByOrgCode(compyOrgCode);
}
/**
* id
* @param pid
* @return
*/
@Override
public List<SysDepart> queryDeptByPid(String pid) {
return this.baseMapper.queryDeptByPid(pid);
}
/**
*
* @param keyWord
* @return

View File

@ -131,7 +131,7 @@ spring:
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource:
master:
url: jdbc:mysql://127.0.0.1:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
url: jdbc:mysql://127.0.0.1:3306/jeecg-boot-os-re?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
@ -210,7 +210,7 @@ jeecg :
#大屏报表参数设置
jmreport:
mode: dev
#数据字典是否可以全局看到
#数据字典是否进行saas数据隔离自己看自己的字典
saas: false
#是否需要校验token
is_verify_token: false
@ -255,7 +255,7 @@ logging:
knife4j:
production: false
basic:
enable: false
enable: true
username: jeecg
password: jeecg1314
#第三方登录
@ -263,17 +263,17 @@ justauth:
enabled: true
type:
GITHUB:
client-id: true
client-secret: true
client-id: ??
client-secret: ??
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/github/callback
WECHAT_ENTERPRISE:
client-id: true
client-secret: true
client-id: ??
client-secret: ??
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback
agent-id: 1000002
DINGTALK:
client-id: true
client-secret: true
client-id: ??
client-secret: ??
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/dingtalk/callback
WECHAT_OPEN:
client-id: ??

View File

@ -210,7 +210,7 @@ jeecg :
#大屏报表参数设置
jmreport:
mode: prod
#数据字典是否可以全局看到
#数据字典是否进行saas数据隔离自己看自己的字典
saas: false
#是否需要校验token
is_verify_token: true
@ -219,8 +219,8 @@ jeecg :
#Wps在线文档
wps:
domain: https://wwo.wps.cn/office/
appid: true
appsecret: true
appid: ??
appsecret: ??
#xxl-job配置
xxljob:
enabled: false
@ -263,21 +263,21 @@ justauth:
enabled: true
type:
GITHUB:
client-id: true
client-secret: true
client-id: ??
client-secret: ??
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/github/callback
WECHAT_ENTERPRISE:
client-id: true
client-secret: true
client-id: ??
client-secret: ??
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback
agent-id: 1000002
DINGTALK:
client-id: true
client-secret: true
client-id: ??
client-secret: ??
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/dingtalk/callback
WECHAT_OPEN:
client-id: true
client-secret: true
client-id: ??
client-secret: ??
redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_open/callback
cache:
type: default

View File

@ -191,7 +191,7 @@ jeecg :
# ElasticSearch 设置
elasticsearch:
cluster-name: jeecg-ES
cluster-nodes: ??
cluster-nodes: http://fileview.jeecg.com
check-enabled: false
# 表单设计器配置
desform:
@ -210,7 +210,7 @@ jeecg :
#大屏报表参数设置
jmreport:
mode: prod
#数据字典是否可以全局看到
#数据字典是否进行saas数据隔离自己看自己的字典
saas: false
#是否需要校验token
is_verify_token: false
@ -255,7 +255,7 @@ cas:
knife4j:
production: false
basic:
enable: false
enable: true
username: jeecg
password: jeecg1314
#第三方登录

View File

@ -9,6 +9,6 @@ ${AnsiColor.BRIGHT_BLUE}
${AnsiColor.BRIGHT_GREEN}
Jeecg Boot Version: 2.4.2
Jeecg Boot Version: 2.4.3
Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
${AnsiColor.BLACK}

View File

@ -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>

View File

@ -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>

View File

@ -15,7 +15,15 @@
<#return text>
</#if>
</#function>
<#---->
<#--下划线转驼峰-->
<#function dashedToCamel(str)>
<#assign text=""/>
<#assign strlist = str?split("_")/>
<#list strlist as v>
<#assign text=text+v?cap_first/>
</#list>
<#return text?uncap_first>
</#function>
<#-- 驼峰转下划线 -->
<#function camelToDashed(str, case='normal')>
<#return camelToChar(str, "_", case)>
@ -61,8 +69,6 @@
<#return true>
</#if>
</#if>
<#elseif po.defaultVal??>
<#return true>
</#if>
<#return false>
</#function>
@ -84,6 +90,15 @@
</#if>
</#function>
<#-- ** 如果Blob就显示model方式 String * -->
<#function autoStringSuffixForModel po>
<#if po.fieldDbType=='Blob'>
<#return "${po.fieldName}String">
<#else>
<#return "${po.fieldName}">
</#if>
</#function>
<#-- ** 高级查询生成 * -->
<#function superQueryFieldList po>
<#assign superQuery_dictTable="">

View File

@ -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>

View File

@ -36,7 +36,7 @@
<#elseif po.classType=='sel_user'>
<#if query_field_no gt 1> </#if><j-select-user-by-dep placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}"/>
<#elseif po.classType=='switch'>
<#if query_field_no gt 1> </#if><j-switch placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if> query></j-switch>
<#if query_field_no gt 1> </#if><j-switch placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if> query></j-switch>
<#elseif po.classType=='sel_depart'>
<#if query_field_no gt 1> </#if><j-select-depart placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}"/>
<#elseif po.classType=='list_multi'>
@ -342,10 +342,9 @@
<#if list_need_switch>
<#list columns as po>
<#if po.classType=='switch'>
<#if po.dictField?default("")?trim?length gt 1>
<#assign switch_extend_arr=po.dictField?eval>
<#else>
<#assign switch_extend_arr=['Y','N']>
<#assign switch_extend_arr=['Y','N']>
<#if po.dictField?default("")?contains("[")>
<#assign switch_extend_arr=po.dictField?eval>
</#if>
<#list switch_extend_arr as a>
<#if a_index == 0>

View File

@ -3,8 +3,9 @@
<template>
<a-spin :spinning="confirmLoading">
<j-form-container :disabled="formDisabled">
<a-form :form="form" slot="detail">
<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>
@ -24,63 +25,64 @@
<#assign form_field_dictCode="${po.dictField}">
</#if>
<a-col :span="${form_span}">
<a-form-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="${autoStringSuffixForModel(po)}">
<#if po.classType =='date'>
<j-date placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
:trigger-change="true"
v-model="model.${po.fieldName}"
field="${po.fieldName}"
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
@callback="popupCallback"
@input="popupCallback"
<#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_depart'>
<j-select-depart v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" multi <#if po.readonly=='Y'>disabled</#if> />
<j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if> />
<#elseif po.classType =='switch'>
<j-switch v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入省市区" <#if po.readonly=='Y'>disabled</#if> />
<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-decorator="[${autoStringSuffix(po)},{initialValue:''}]" id="${po.fieldName}"></j-markdown-editor>
<j-markdown-editor v-model="model.${autoStringSuffixForModel(po)}" id="${po.fieldName}"></j-markdown-editor>
<#elseif po.classType =='password'>
<a-input-password v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.readonly=='Y'>disabled</#if>/>
<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>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" dict="${form_field_dictCode}" <#if po.readonly=='Y'>disabled</#if> />
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${po.dictText}" @change="handleCategoryChange"</#if> <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" <#if po.readonly=='Y'>disabled</#if> <#if po.uploadnum??>:number=${po.uploadnum}</#if>></j-upload>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.readonly=='Y'>disabled</#if>></j-image-upload>
<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-decorator="[${autoStringSuffix(po)},{trigger:'input'}]" <#if po.readonly=='Y'>disabled</#if>/>
<j-editor v-model="model.${autoStringSuffixForModel(po)}" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.fieldDbType=='Blob'>
<a-input v-decorator="[${autoStringSuffix(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
<a-input v-model="model.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
<#elseif po.classType == 'sel_tree'>
<j-tree-select
ref="treeSelect"
placeholder="请选择${po.filedComment}"
v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
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]}"
@ -94,22 +96,17 @@
<#if po.readonly=='Y'>disabled</#if>>
</j-tree-select>
<#else>
<a-input v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if> ></a-input>
<a-input v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if> ></a-input>
</#if>
</a-form-item>
</a-form-model-item>
</a-col>
</#if>
</#list>
<#if form_cat_tree && form_cat_back?length gt 1>
<a-form-item v-show="false">
<a-input v-decorator="['${form_cat_back}']"></a-input>
</a-form-item>
</#if>
<a-col v-if="showFlowSubmitButton" :span="24" style="text-align: center">
<a-button @click="submitForm">提 交</a-button>
</a-col>
</a-row>
</a-form>
</a-form-model>
</j-form-container>
</a-spin>
</template>
@ -117,7 +114,6 @@
<script>
import { httpAction, getAction } from '@/api/manage'
import pick from 'lodash.pick'
import { validateDuplicateValue } from '@/utils/util'
export default {
@ -146,8 +142,9 @@
},
data () {
return {
form: this.$form.createForm(this),
model: {},
model:{
<#include "/common/init/initValue.ftl">
},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
@ -185,20 +182,18 @@
}
},
created () {
//备份model原始值
this.modelDefault = JSON.parse(JSON.stringify(this.model));
//如果是流程中表单则需要加载流程表单data
this.showFlowData();
},
methods: {
add () {
this.edit({});
this.edit(this.modelDefault);
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model<#list columns as po><#if po.fieldName !='id'><#if po.fieldDbType=='Blob'>,'${po.fieldName}String'<#else>,'${po.fieldName}'</#if></#if></#list>))
})
},
//渲染流程表单数据
showFlowData(){
@ -214,8 +209,8 @@
submitForm () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
@ -226,9 +221,7 @@
httpurl+=this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
console.log("表单提交数据",formData)
httpAction(httpurl,formData,method).then((res)=>{
httpAction(httpurl,this.model,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
@ -242,12 +235,14 @@
})
},
popupCallback(row){
this.form.setFieldsValue(pick(row<#list columns as po><#if po.fieldName !='id'><#if po.fieldDbType=='Blob'>,'${po.fieldName}String'<#else>,'${po.fieldName}'</#if></#if></#list>))
<#if form_popup>
popupCallback(value,row){
this.model = Object.assign(this.model, row);
},
</#if>
<#if form_cat_tree>
handleCategoryChange(value,backObj){
this.form.setFieldsValue(backObj)
this.model = Object.assign(this.model, backObj);
}
</#if>
}

View File

@ -14,6 +14,7 @@
placement="right"
:closable="false"
@close="close"
destroyOnClose
:visible="visible">
<${Format.humpToShortbar(entityName)}-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></${Format.humpToShortbar(entityName)}-form>
<div class="drawer-footer">

View File

@ -289,7 +289,7 @@
</#if>
<#elseif po.classType=='switch'>
dataIndex: '${po.fieldName}',
<#if po.dictField?default("")?trim?length gt 1>
<#if po.dictField != 'is_open'>
customRender: (text) => (!text ? "" : (text == ${po.dictField}[0] ? "是" : "否"))
<#else>
customRender: (text) => (!text ? "" : (text == "Y" ? "是" : "否"))

View File

@ -3,8 +3,9 @@
<a-spin :spinning="confirmLoading">
<j-form-container :disabled="formDisabled">
<!-- 主表单区域 -->
<a-form :form="form" slot="detail">
<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>
@ -25,67 +26,68 @@
</#if>
<#if po.classType =='textarea'>
<a-col :span="24">
<a-form-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2">
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2" prop="${autoStringSuffixForModel(po)}">
<#else>
<a-col :span="${form_span}" >
<a-form-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol">
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
:trigger-change="true"
v-model="model.${po.fieldName}"
field="${po.fieldName}"
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
@callback="popupCallback"
@input="popupCallback"
<#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_depart'>
<j-select-depart v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" multi <#if po.readonly=='Y'>disabled</#if>/>
<j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='switch'>
<j-switch v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入省市区" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="[${autoStringSuffix(po)},{initialValue:''}]" id="${po.fieldName}"></j-markdown-editor>
<j-markdown-editor v-model="model.${autoStringSuffixForModel(po)}" id="${po.fieldName}"></j-markdown-editor>
<#elseif po.classType =='password'>
<a-input-password v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.readonly=='Y'>disabled</#if>/>
<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>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" dict="${form_field_dictCode}" <#if po.readonly=='Y'>disabled</#if> />
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${po.dictText}" @change="handleCategoryChange"</#if> <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" <#if po.readonly=='Y'>disabled</#if> <#if po.uploadnum??>:number=${po.uploadnum}</#if>></j-upload>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.readonly=='Y'>disabled</#if>></j-image-upload>
<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-decorator="[${autoStringSuffix(po)},{trigger:'input'}]" <#if po.readonly=='Y'>disabled</#if>/>
<j-editor v-model="model.${autoStringSuffixForModel(po)}" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.fieldDbType=='Blob'>
<a-input v-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
<a-input v-model="model.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
<#elseif po.classType == 'sel_tree'>
<j-tree-select
ref="treeSelect"
placeholder="请选择${po.filedComment}"
v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
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]}"
@ -99,19 +101,14 @@
<#if po.readonly=='Y'>disabled</#if>>
</j-tree-select>
<#else>
<a-input v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
<a-input v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
</#if>
</a-form-item>
<#if form_cat_tree && form_cat_back?length gt 1>
<a-form-item v-show="false">
<a-input v-decorator="['${form_cat_back}']"></a-input>
</a-form-item>
</#if>
</a-form-model-item>
</a-col>
</#if>
</#list>
</a-row>
</a-form>
</a-form-model>
</j-form-container>
<!-- 子表单区域 -->
<a-tabs v-model="activeKey" @change="handleChangeTabs">
@ -143,10 +140,9 @@
<script>
import pick from 'lodash.pick'
import { getAction } from '@/api/manage'
import { FormTypes,getRefPromise } from '@/utils/JEditableTableUtil'
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
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'>
@ -156,7 +152,7 @@
export default {
name: '${entityName}Form',
mixins: [JEditableTableMixin],
mixins: [JEditableTableModelMixin],
components: {
<#list subTables as sub>
<#if sub.foreignRelationType =='1'>
@ -182,6 +178,9 @@
xs: { span: 24 },
sm: { span: 20 },
},
model:{
<#include "/common/init/initValue.ftl">
},
// 新增时子表默认添加几行空数据
addDefaultRowNum: 1,
<#include "/common/validatorRulesTemplate/main.ftl">
@ -204,7 +203,7 @@
<#if col.filedComment !='外键' >
{
title: '${col.filedComment}',
key: ${autoStringSuffix(col)},
key: '${autoStringSuffixForModel(col)}',
<#if col.classType =='date'>
type: FormTypes.date,
<#if col.readonly=='Y'>
@ -242,10 +241,10 @@
</#if>
<#elseif col.classType =='switch'>
type: FormTypes.checkbox,
<#if col.dictField?default("")?trim?length gt 1>
customValue:${col.dictField},
<#else>
<#if col.dictField == 'is_open'>
customValue: ['Y', 'N'],
<#else>
customValue: ${col.dictField},
</#if>
<#if col.readonly=='Y'>
disabled:true,
@ -424,7 +423,6 @@
},
methods: {
addBefore(){
this.form.resetFields()
<#list subTables as sub><#rt/>
<#if sub.foreignRelationType =='1'>
this.$refs.${sub.entityName?uncap_first}Form.clearFormData()
@ -445,9 +443,7 @@
},
/** 调用完edit()方法之后会自动调用此方法 */
editAfter() {
let fieldval = pick(this.model<#list columns as po><#if po.fieldName !='id'><#if po.fieldDbType=='Blob'>,'${po.fieldName}String'<#else>,'${po.fieldName}'</#if></#if></#list>)
this.$nextTick(() => {
this.form.setFieldsValue(fieldval)
<#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)
@ -464,6 +460,27 @@
</#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)
@ -494,12 +511,14 @@
validateError(msg){
this.$message.error(msg)
},
popupCallback(row){
this.form.setFieldsValue(pick(row<#list columns as po><#if po.fieldName !='id'><#if po.fieldDbType=='Blob'>,'${po.fieldName}String'<#else>,'${po.fieldName}'</#if></#if></#list>))
<#if form_popup>
popupCallback(value,row){
this.model = Object.assign(this.model, row);
},
</#if>
<#if form_cat_tree>
handleCategoryChange(value,backObj){
this.form.setFieldsValue(backObj)
this.model = Object.assign(this.model, backObj);
}
</#if>

View File

@ -4,8 +4,9 @@
#segment#${sub.entityName}Form.vue
<template>
<j-form-container :disabled="disabled">
<a-form :form="form" slot="detail">
<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>
@ -26,82 +27,77 @@
</#if>
<#if po.classType =='textarea'>
<a-col :span="24">
<a-form-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2">
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2" prop="${autoStringSuffixForModel(po)}">
<#else>
<a-col :span="${form_span}">
<a-form-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol">
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%"/>
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" style="width: 100%"/>
<#elseif po.classType =='datetime'>
<j-date placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"/>
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"/>
<#elseif po.classType =='time'>
<j-time placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
:trigger-change="true"
v-model="model.${po.fieldName}"
field="${po.fieldName}"
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
@callback="popupCallback"/>
@input="popupCallback"/>
<#elseif po.classType =='sel_depart'>
<j-select-depart v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" multi/>
<j-select-depart v-model="model.${po.fieldName}" multi/>
<#elseif po.classType =='switch'>
<j-switch v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if>></j-switch>
<j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if>></j-switch>
<#elseif po.classType =='pca'>
<j-area-linkage type="cascader" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入省市区"/>
<j-area-linkage type="cascader" v-model="model.${po.fieldName}" placeholder="请输入省市区"/>
<#elseif po.classType =='markdown'>
<j-markdown-editor v-decorator="[${autoStringSuffix(po)},{initialValue:''}]" id="${po.fieldName}"></j-markdown-editor>
<j-markdown-editor v-model="model.${autoStringSuffixForModel(po)}" id="${po.fieldName}"></j-markdown-editor>
<#elseif po.classType =='password'>
<a-input-password v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}"/>
<a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"/>
<#elseif po.classType =='sel_user'>
<j-select-user-by-dep v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"/>
<j-select-user-by-dep v-model="model.${po.fieldName}"/>
<#elseif po.classType =='textarea'>
<a-textarea v-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" rows="4" placeholder="请输入${po.filedComment}"/>
<a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}"/>
<#elseif po.classType=='list' || po.classType=='radio'>
<j-dict-select-tag type="${po.classType}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<j-dict-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
<j-multi-select-tag type="${po.classType}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<j-multi-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<#elseif po.classType=='sel_search'>
<j-search-select-tag v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" dict="${form_field_dictCode}" />
<j-search-select-tag v-model="model.${po.fieldName}" dict="${form_field_dictCode}" />
<#elseif po.classType=='cat_tree'>
<#assign form_cat_tree = true>
<j-category-select v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${po.dictText}" @change="handleCategoryChange"</#if>/>
<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.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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" style="width: 100%"/>
<a-input-number v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" style="width: 100%"/>
<#elseif po.classType=='file'>
<j-upload v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true"></j-upload>
<j-upload v-model="model.${po.fieldName}"></j-upload>
<#elseif po.classType=='image'>
<j-image-upload isMultiple v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"></j-image-upload>
<j-image-upload isMultiple v-model="model.${po.fieldName}"></j-image-upload>
<#elseif po.classType=='umeditor'>
<j-editor v-decorator="[${autoStringSuffix(po)},{trigger:'input'}]"/>
<j-editor v-model="model.${autoStringSuffixForModel(po)}"/>
<#elseif po.fieldDbType=='Blob'>
<a-input v-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}"></a-input>
<a-input v-model="model.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}"></a-input>
<#else>
<a-input v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}"></a-input>
<a-input v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"></a-input>
</#if>
</a-form-item>
<#if form_cat_tree && form_cat_back?length gt 1>
<a-form-item v-show="false">
<a-input v-decorator="['${form_cat_back}']"></a-input>
</a-form-item>
</#if>
</a-form-model-item>
</a-col>
</#if>
</#list>
</a-row>
</a-form>
</a-form-model>
</j-form-container>
</template>
<script>
import pick from 'lodash.pick'
import { getAction } from '@/api/manage'
import { validateDuplicateValue } from '@/utils/util'
import { VALIDATE_NO_PASSED } from '@/utils/JEditableTableUtil'
export default {
name: '${sub.entityName}Form',
components: {
@ -115,8 +111,9 @@
},
data () {
return {
form: this.$form.createForm(this),
model: {},
model:{
<#include "/common/init/initValueSub.ftl">
},
labelCol: {
xs: { span: 24 },
sm: { span: 6 },
@ -136,12 +133,16 @@
<#include "/common/validatorRulesTemplate/sub.ftl">
confirmLoading: false,
}
},
created () {
//备份model原始值
this.modelDefault = JSON.parse(JSON.stringify(this.model));
},
methods:{
initFormData(url,id){
this.clearFormData()
if(!id){
this.edit({})
this.edit(this.modelDefault)
}else{
getAction(url,{id:id}).then(res=>{
if(res.success){
@ -156,42 +157,49 @@
edit(record){
this.model = Object.assign({}, record)
console.log("${sub.entityName}Form-edit",this.model);
let fieldval = pick(this.model<#list sub.colums as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>)
this.$nextTick(() => {
this.form.setFieldsValue(fieldval)
})
},
getFormData(){
let formdata_arr = []
this.form.validateFields((err, values) => {
if (!err) {
let formdata = Object.assign(this.model, values)
this.$refs.form.validate(valid => {
if (valid) {
let isNullObj = true
Object.keys(formdata).forEach(key=>{
if(formdata[key]){
Object.keys(this.model).forEach(key=>{
if(this.model[key]){
isNullObj = false
}
})
if(!isNullObj){
formdata_arr.push(formdata)
formdata_arr.push(this.model)
}
}else{
this.$emit("validateError","${sub.ftlDescription}表单校验未通过");
}
})
console.log("${sub.ftlDescription}表单数据集",formdata_arr);
return formdata_arr;
},
popupCallback(row){
this.form.setFieldsValue(pick(row<#list sub.colums as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>))
validate(index){
return new Promise((resolve, reject) => {
// 验证主表表单
this.$refs.form.validate(valid => {
!valid ? reject({ error: VALIDATE_NO_PASSED ,index}) : resolve()
})
}).then(values => {
return Promise.resolve()
}).catch(error => {
return Promise.reject(error)
})
},
<#if form_popup>
popupCallback(value,row){
this.model = Object.assign(this.model, row);
},
</#if>
clearFormData(){
this.form.resetFields()
this.model={}
this.$refs.form.clearValidate()
},
<#if form_cat_tree>
handleCategoryChange(value,backObj){
this.form.setFieldsValue(backObj);
this.model = Object.assign(backObj,this.model);
}
</#if>
}

View File

@ -45,7 +45,7 @@
<#elseif po.classType=='sel_user'>
<#if query_field_no gt 1> </#if><j-select-user-by-dep placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}"/>
<#elseif po.classType=='switch'>
<#if query_field_no gt 1> </#if><j-switch placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if> query></j-switch>
<#if query_field_no gt 1> </#if><j-switch placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if> query></j-switch>
<#elseif po.classType=='sel_depart'>
<#if query_field_no gt 1> </#if><j-select-depart placeholder="请选择${po.filedComment}" v-model="queryParam.${po.fieldName}"/>
<#elseif po.classType=='list_multi'>
@ -269,7 +269,7 @@
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='switch'>
dataIndex: '${po.fieldName}',
<#if po.dictField?default("")?trim?length gt 1>
<#if po.dictField != 'is_open'>
customRender: (text) => (!text ? "" : (text == ${po.dictField}[0] ? "是" : "否"))
<#else>
customRender: (text) => (!text ? "" : (text == "Y" ? "是" : "否"))

View File

@ -8,11 +8,11 @@
switchFullscreen
@ok="handleOk"
@cancel="handleCancel"
:destroyOnClose="true"
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-model ref="form" :model="model" :rules="validatorRules">
<#assign pidFieldName = "">
<#assign form_popup = false>
<#assign form_cat_tree = false>
<#assign form_cat_back = "">
<#list columns as po>
@ -23,13 +23,13 @@
<#elseif po.dictField?default("")?trim?length gt 1>
<#assign form_field_dictCode="${po.dictField}">
</#if>
<a-form-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="${autoStringSuffixForModel(po)}">
<#if po.fieldDbName == tableVo.extendParams.pidField>
<#assign pidFieldName = po.fieldName>
<j-tree-select
ref="treeSelect"
placeholder="请选择${po.filedComment}"
v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
v-model="model.${po.fieldName}"
dict="${tableVo.tableName},${tableVo.extendParams.textField},id"
pidField="${tableVo.extendParams.pidField}"
pidValue="0"
@ -37,57 +37,58 @@
<#if po.readonly=='Y'>disabled</#if>>
</j-tree-select>
<#elseif po.classType =='date'>
<j-date placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<j-time placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='switch'>
<j-switch v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if>></j-switch>
<j-switch v-model="model.${po.fieldName}" <#if po.dictField != 'is_open'>:options="${po.dictField}"</#if>></j-switch>
<#elseif po.classType =='popup'>
<#assign form_popup=true>
<j-popup
v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
:trigger-change="true"
v-model="model.${po.fieldName}"
field="${po.fieldName}"
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
@callback="popupCallback"
@input="popupCallback"
<#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_depart'>
<j-select-depart v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" <#if po.readonly=='Y'>disabled</#if>/>
<j-select-depart v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_user'>
<j-select-user-by-dep v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" <#if po.readonly=='Y'>disabled</#if>/>
<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>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
<a-input-number v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" <#if po.readonly=='Y'>disabled</#if> <#if po.uploadnum??>:number=${po.uploadnum}</#if>></j-upload>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.readonly=='Y'>disabled</#if>></j-image-upload>
<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=='sel_search'>
<j-search-select-tag v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" dict="${form_field_dictCode}" <#if po.readonly=='Y'>disabled</#if> />
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${po.dictText}" @change="handleCategoryChange"</#if> <#if po.readonly=='Y'>disabled</#if>/>
<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.classType =='pca'>
<j-area-linkage type="cascader" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入省市区" <#if po.readonly=='Y'>disabled</#if> />
<j-area-linkage type="cascader" v-model="model.${po.fieldName}" placeholder="请输入省市区" <#if po.readonly=='Y'>disabled</#if> />
<#elseif po.classType=='umeditor'>
<j-editor v-decorator="[${autoStringSuffix(po)},{trigger:'input'}]" <#if po.readonly=='Y'>disabled</#if>/>
<j-editor v-model="model.${autoStringSuffixForModel(po)}" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='markdown'>
<j-markdown-editor v-decorator="[${autoStringSuffix(po)},{initialValue:''}]" id="${po.fieldName}"></j-markdown-editor>
<j-markdown-editor v-model="model.${autoStringSuffixForModel(po)}" id="${po.fieldName}"></j-markdown-editor>
<#elseif po.classType == 'sel_tree'>
<j-tree-select
ref="treeSelect"
placeholder="请选择${po.filedComment}"
v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
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]}"
@ -101,18 +102,13 @@
<#if po.readonly=='Y'>disabled</#if>>
</j-tree-select>
<#else>
<a-input v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
<a-input v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
</#if>
</a-form-item>
<#if form_cat_tree && form_cat_back?length gt 1>
<a-form-item v-show="false">
<a-input v-decorator="['${form_cat_back}']"></a-input>
</a-form-item>
</#if>
</a-form-model-item>
</#if>
</#list>
</a-form>
</a-form-model>
</a-spin>
</j-modal>
</template>
@ -120,7 +116,6 @@
<script>
import { httpAction } from '@/api/manage'
import pick from 'lodash.pick'
import { validateDuplicateValue } from '@/utils/util'
export default {
name: "${entityName}Modal",
@ -128,11 +123,12 @@
},
data () {
return {
form: this.$form.createForm(this),
title:"操作",
width:800,
visible: false,
model: {},
model:{
<#include "/common/init/initValue.ftl">
},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
@ -154,28 +150,27 @@
}
},
created () {
//备份model原始值
this.modelDefault = JSON.parse(JSON.stringify(this.model));
},
methods: {
add (obj) {
this.edit(obj);
this.edit(Object.assign(this.modelDefault , obj));
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model<#list columns as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>))
})
},
close () {
this.$emit('close');
this.visible = false;
this.$refs.form.clearValidate()
},
handleOk () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
@ -186,16 +181,12 @@
httpurl+=this.url.edit;
method = 'put';
}
let old_pid = this.model[this.pidField]
let formData = Object.assign(this.model, values);
let new_pid = this.model[this.pidField]
if(this.model.id && this.model.id === new_pid){
if(this.model.id && this.model.id === this.model[this.pidField]){
that.$message.warning("父级节点不能选择自己");
that.confirmLoading = false;
return;
}
console.log("表单提交数据",formData)
httpAction(httpurl,formData,method).then((res)=>{
httpAction(httpurl,this.model,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
this.$emit('ok');
@ -206,16 +197,24 @@
that.confirmLoading = false;
that.close();
})
}else{
return false
}
})
},
handleCancel () {
this.close()
},
popupCallback(row){
this.form.setFieldsValue(pick(row<#list columns as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>))
<#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>
submitSuccess(formData,flag){
if(!formData.id){
let treeData = this.$refs.treeSelect.getCurrTreeData()

View File

@ -84,6 +84,9 @@
<#if po.classType=='cat_tree' && po.dictText?default("")?trim?length == 0>
<#assign list_need_category=true>
</#if>
<#if po.classType=='pca'>
<#assign list_need_pca=true>
</#if>
</#list>
<#-- 结束循环 -->
<#t>
@ -264,7 +267,7 @@
dataIndex: '${po.fieldName}_dictText',
<#elseif po.classType=='switch'>
dataIndex: '${po.fieldName}',
<#if po.dictField?default("")?trim?length gt 1>
<#if po.dictField != 'is_open'>
customRender: (text) => (!text ? "" : (text == ${po.dictField}[0] ? "是" : "否"))
<#else>
customRender: (text) => (!text ? "" : (text == "Y" ? "是" : "否"))

View File

@ -157,7 +157,7 @@
dataIndex: '${po.fieldName}_dictText',
<#elseif po.classType=='switch'>
dataIndex: '${po.fieldName}',
<#if po.dictField?default("")?trim?length gt 1>
<#if po.dictField != 'is_open'>
customRender: (text) => (!text ? "" : (text == ${po.dictField}[0] ? "是" : "否"))
<#else>
customRender: (text) => (!text ? "" : (text == "Y" ? "是" : "否"))

View File

@ -10,8 +10,9 @@
@cancel="handleCancel"
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-model ref="form" :model="model" :rules="validatorRules">
<a-row>
<#assign form_popup = false>
<#assign form_cat_tree = false>
<#assign form_cat_back = "">
<#assign form_span = 24>
@ -24,63 +25,64 @@
<#assign form_field_dictCode="${po.dictField}">
</#if>
<a-col :span="${form_span}">
<a-form-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="${autoStringSuffixForModel(po)}">
<#if po.classType =='date'>
<j-date placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
:trigger-change="true"
v-model="model.${po.fieldName}"
field="${po.fieldName}"
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
@callback="popupCallback"
@input="popupCallback"
<#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_depart'>
<j-select-depart v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" multi <#if po.readonly=='Y'>disabled</#if>/>
<j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='switch'>
<j-switch v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入省市区" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="[${autoStringSuffix(po)},{initialValue:''}]" id="${po.fieldName}"></j-markdown-editor>
<j-markdown-editor v-model="model.${autoStringSuffixForModel(po)}" id="${po.fieldName}"></j-markdown-editor>
<#elseif po.classType =='password'>
<a-input-password v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.readonly=='Y'>disabled</#if>/>
<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>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" dict="${form_field_dictCode}" <#if po.readonly=='Y'>disabled</#if> />
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${po.dictText}" @change="handleCategoryChange"</#if> <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" <#if po.readonly=='Y'>disabled</#if> <#if po.uploadnum??>:number=${po.uploadnum}</#if>></j-upload>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.readonly=='Y'>disabled</#if>></j-image-upload>
<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-decorator="[${autoStringSuffix(po)},{trigger:'input'}]" <#if po.readonly=='Y'>disabled</#if>/>
<j-editor v-model="model.${autoStringSuffixForModel(po)}" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.fieldDbType=='Blob'>
<a-input v-decorator="['${po.fieldName}String'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
<a-input v-model="model.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
<#elseif po.classType == 'sel_tree'>
<j-tree-select
ref="treeSelect"
placeholder="请选择${po.filedComment}"
v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
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]}"
@ -94,19 +96,14 @@
<#if po.readonly=='Y'>disabled</#if>>
</j-tree-select>
<#else>
<a-input v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
<a-input v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
</#if>
</a-form-item>
</a-form-model-item>
</a-col>
</#if>
</#list>
<#if form_cat_tree && form_cat_back?length gt 1>
<a-form-item v-show="false">
<a-input v-decorator="['${form_cat_back}']"></a-input>
</a-form-item>
</#if>
</a-row>
</a-form>
</a-form-model>
</a-spin>
</j-modal>
</template>
@ -114,7 +111,6 @@
<script>
import { httpAction } from '@/api/manage'
import pick from 'lodash.pick'
import { validateDuplicateValue } from '@/utils/util'
export default {
@ -123,11 +119,12 @@
},
data () {
return {
form: this.$form.createForm(this),
title:"操作",
width:800,
visible: false,
model: {},
model:{
<#include "/common/init/initValue.ftl">
},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
@ -147,28 +144,27 @@
}
},
created () {
//备份model原始值
this.modelDefault = JSON.parse(JSON.stringify(this.model));
},
methods: {
add () {
this.edit({});
this.edit(this.modelDefault);
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model<#list columns as po><#if po.fieldName !='id'><#if po.fieldDbType=='Blob'>,'${po.fieldName}String'<#else>,'${po.fieldName}'</#if></#if></#list>))
})
},
close () {
this.$emit('close');
this.visible = false;
this.$refs.form.clearValidate();
},
handleOk () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
@ -179,9 +175,7 @@
httpurl+=this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
console.log("表单提交数据",formData)
httpAction(httpurl,formData,method).then((res)=>{
httpAction(httpurl,this.model,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
@ -192,19 +186,22 @@
that.confirmLoading = false;
that.close();
})
}else{
return false
}
})
},
handleCancel () {
this.close()
},
popupCallback(row){
this.form.setFieldsValue(pick(row<#list columns as po><#if po.fieldName !='id'><#if po.fieldDbType=='Blob'>,'${po.fieldName}String'<#else>,'${po.fieldName}'</#if></#if></#list>))
<#if form_popup>
popupCallback(value,row){
this.model = Object.assign(this.model, row);
},
</#if>
<#if form_cat_tree>
handleCategoryChange(value,backObj){
this.form.setFieldsValue(backObj)
this.model = Object.assign(backObj,this.model);
}
</#if>

View File

@ -12,8 +12,9 @@
@cancel="handleCancel"
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-model ref="form" :model="model" :rules="validatorRules">
<a-row>
<#assign form_popup = false>
<#assign form_cat_tree = false>
<#assign form_cat_back = "">
<#assign form_span = 24>
@ -26,72 +27,68 @@
<#assign form_field_dictCode="${po.dictField}">
</#if>
<a-col :span="${form_span}">
<a-form-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="${autoStringSuffixForModel(po)}">
<#if po.classType =='date'>
<j-date placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
:trigger-change="true"
v-model="model.${po.fieldName}"
field="${po.fieldName}"
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
@callback="popupCallback"
@input="popupCallback"
<#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_depart'>
<j-select-depart v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" multi <#if po.readonly=='Y'>disabled</#if>/>
<j-select-depart v-model="model.${po.fieldName}"multi <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='switch'>
<j-switch v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入省市区" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="[${autoStringSuffix(po)},{initialValue:''}]" id="${po.fieldName}"></j-markdown-editor>
<j-markdown-editor v-model="model.${autoStringSuffixForModel(po)}" id="${po.fieldName}"></j-markdown-editor>
<#elseif po.classType =='password'>
<a-input-password v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.readonly=='Y'>disabled</#if>/>
<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>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" dict="${form_field_dictCode}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${po.dictText}" @change="handleCategoryChange"</#if> <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" <#if po.readonly=='Y'>disabled</#if> <#if po.uploadnum??>:number=${po.uploadnum}</#if>></j-upload>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.readonly=='Y'>disabled</#if>></j-image-upload>
<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-decorator="[${autoStringSuffix(po)},{trigger:'input'}]" <#if po.readonly=='Y'>disabled</#if>/>
<j-editor v-model="model.${autoStringSuffixForModel(po)}" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.fieldDbType=='Blob'>
<a-input v-decorator="['${po.fieldName}String'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
<a-input v-model="model.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
<#else>
<a-input v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
<a-input v-model="model.${po.fieldName}"placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
</#if>
</a-form-item>
</a-form-model-item>
</a-col>
</#if>
</#list>
<#if form_cat_tree && form_cat_back?length gt 1>
<a-form-item v-show="false">
<a-input v-decorator="['${form_cat_back}']"></a-input>
</a-form-item>
</#if>
</a-row>
</a-form>
</a-form-model>
</a-spin>
</j-modal>
</template>
@ -99,7 +96,6 @@
<script>
import { httpAction } from '@/api/manage'
import pick from 'lodash.pick'
import { validateDuplicateValue } from '@/utils/util'
export default {
@ -115,11 +111,12 @@
},
data () {
return {
form: this.$form.createForm(this),
title:"操作",
width:800,
visible: false,
model: {},
model:{
<#include "/common/init/initValueSub.ftl">
},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
@ -139,28 +136,27 @@
}
},
created () {
//备份model原始值
this.modelDefault = JSON.parse(JSON.stringify(this.model));
},
methods: {
add () {
this.edit({});
this.edit(this.modelDefault);
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model<#list sub.originalColumns as po><#if po.fieldName !='id'><#if po.fieldDbType=='Blob'>,'${po.fieldName}String'<#else>,'${po.fieldName}'</#if></#if></#list>))
})
},
close () {
this.$emit('close');
this.visible = false;
this.$refs.form.clearValidate();
},
handleOk () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
@ -171,12 +167,10 @@
httpurl+=this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
<#list sub.foreignKeys as key>
formData['${key?uncap_first}'] = this.mainId
this.model['${key?uncap_first}'] = this.mainId
</#list>
console.log("表单提交数据",formData)
httpAction(httpurl,formData,method).then((res)=>{
httpAction(httpurl,this.model,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
@ -187,19 +181,22 @@
that.confirmLoading = false;
that.close();
})
}else{
return false
}
})
},
handleCancel () {
this.close()
},
popupCallback(row){
this.form.setFieldsValue(pick(row<#list sub.originalColumns as po><#if po.fieldName !='id'><#if po.fieldDbType=='Blob'>,'${po.fieldName}String'<#else>,'${po.fieldName}'</#if></#if></#list>))
<#if form_popup>
popupCallback(value,row){
this.model = Object.assign(this.model, row);
},
</#if>
<#if form_cat_tree>
handleCategoryChange(value,backObj){
this.form.setFieldsValue(backObj)
this.model = Object.assign(this.model,backObj);
}
</#if>

View File

@ -13,6 +13,8 @@
<#assign list_need_dict=false>
<#-- 是否有分类字典 -->
<#assign list_need_category=false>
<#-- 是否有省市区 -->
<#assign list_need_pca=false>
<#-- 是否有用户选择 -->
<#assign query_sel_user=false>
<#-- 是否有部门选择 -->
@ -137,6 +139,10 @@
<#if po.classType == 'cat_tree' && (po.dictText!"")?trim?length == 0>
<#assign list_need_category=true>
</#if>
<#-- 判断是否需要省市区 -->
<#if po.classType=='pca'>
<#assign list_need_pca=true>
</#if>
</#list>
<#-- 查询区域-结束循环 -->
<#if query_field_index gt 2>
@ -236,6 +242,12 @@
</div>
</template>
<#if list_need_pca>
<template slot="pcaSlot" slot-scope="text">
<div>{{ getPcaText(text) }}</div>
</template>
</#if>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
<a-button
@ -316,6 +328,9 @@
<#if query_sel_cat>
import JCategorySelect from '@comp/jeecg/JCategorySelect'
</#if>
<#if list_need_pca>
import Area from '@/components/_util/Area'
</#if>
import '@/assets/less/TableExpand.less'
export default {
@ -379,6 +394,9 @@
<#elseif po.classType=='umeditor'>
dataIndex: '${po.fieldName}',
scopedSlots: {customRender: 'htmlSlot'}
<#elseif po.classType=='pca'>
dataIndex: '${po.fieldName}',
scopedSlots: {customRender: 'pcaSlot'}
<#elseif po.classType=='file'>
dataIndex: '${po.fieldName}',
scopedSlots: {customRender: 'fileSlot'}
@ -397,7 +415,7 @@
</#if>
<#elseif po.classType=='switch'>
dataIndex: '${po.fieldName}',
<#if po.dictField?default("")?trim?length gt 1>
<#if po.dictField != 'is_open'>
customRender: (text) => (!text ? "" : (text == ${po.dictField}[0] ? "是" : "否"))
<#else>
customRender: (text) => (!text ? "" : (text == "Y" ? "是" : "否"))
@ -429,10 +447,16 @@
exportXlsUrl: '${urlPrefix}/exportXls',
importExcelUrl: '${urlPrefix}/importExcel',
},
<#if list_need_pca>
pcaData:'',
</#if>
superFieldList:[],
}
},
created() {
<#if list_need_pca>
this.pcaData = new Area()
</#if>
this.getSuperFieldList();
},
computed: {
@ -441,7 +465,11 @@
}
},
methods: {
<#if list_need_pca>
getPcaText(code){
return this.pcaData.getText(code);
},
</#if>
initDictConfig() {
<#list columns as po>
<#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>

View File

@ -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>

View File

@ -5,428 +5,55 @@
:width="1200"
:visible="visible"
:maskClosable="false"
:confirmLoading="confirmLoading"
switchFullscreen
@ok="handleOk"
:okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
@cancel="handleCancel">
<a-spin :spinning="confirmLoading">
<!-- 主表单区域 -->
<a-form :form="form">
<a-row>
<#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-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2">
<#else>
<a-col :xs="24" :sm="12">
<a-form-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol">
</#if>
<#if po.classType =='date'>
<j-date placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='datetime'>
<j-date placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" :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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='popup'>
<j-popup
v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
:trigger-change="true"
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
@callback="popupCallback"
<#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_depart'>
<j-select-depart v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" multi <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='switch'>
<j-switch v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch>
<#elseif po.classType =='pca'>
<j-area-linkage type="cascader" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入省市区" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='markdown'>
<j-markdown-editor v-decorator="[${autoStringSuffix(po)},{initialValue:''}]" id="${po.fieldName}"></j-markdown-editor>
<#elseif po.classType =='password'>
<a-input-password v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_user'>
<j-select-user-by-dep v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" 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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType=='sel_search'>
<j-search-select-tag v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" dict="${form_field_dictCode}" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType=='cat_tree'>
<#assign form_cat_tree = true>
<j-category-select v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType=='file'>
<j-upload v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" <#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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.readonly=='Y'>disabled</#if>></j-image-upload>
<#elseif po.classType=='umeditor'>
<j-editor v-decorator="[${autoStringSuffix(po)},{trigger:'input'}]" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType == 'sel_tree'>
<j-tree-select
ref="treeSelect"
placeholder="请选择${po.filedComment}"
v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
<#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-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
</#if>
</a-form-item>
<#if form_cat_tree && form_cat_back?length gt 1>
<a-form-item v-show="false">
<a-input v-decorator="['${form_cat_back}']"></a-input>
</a-form-item>
</#if>
</a-col>
</#if>
</#list>
</a-row>
</a-form>
<!-- 子表单区域 -->
<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"></${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"
:rowNumber="true"
:rowSelection="true"
:actionButton="true"/>
</a-tab-pane>
</#if>
</#list>
</a-tabs>
</a-spin>
<${Format.humpToShortbar(entityName)}-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"/>
</j-modal>
</template>
<script>
import pick from 'lodash.pick'
import { FormTypes,getRefPromise } from '@/utils/JEditableTableUtil'
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
import { validateDuplicateValue } from '@/utils/util'
<#list subTables as sub>
<#if sub.foreignRelationType =='1'>
import ${sub.entityName}Form from './${sub.entityName}Form.vue'
</#if>
</#list>
import ${entityName}Form from './${entityName}Form'
export default {
name: '${entityName}Modal',
mixins: [JEditableTableMixin],
components: {
<#list subTables as sub>
<#if sub.foreignRelationType =='1'>
${sub.entityName}Form,
</#if>
</#list>
${entityName}Form
},
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,
<#include "/common/validatorRulesTemplate/main.ftl">
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: ${autoStringSuffix(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?default("")?trim?length gt 1>
customValue:${col.dictField},
<#else>
customValue: ['Y', 'N'],
</#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>
}
title:'',
visible: false,
disableSubmit: false
}
},
methods: {
getAllTable() {
let values = this.tableKeys.map(key => getRefPromise(this, key))
return Promise.all(values)
},
/** 调用完edit()方法之后会自动调用此方法 */
editAfter() {
let fieldval = pick(this.model<#list columns as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>)
this.$nextTick(() => {
this.form.setFieldsValue(fieldval)
<#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>
methods:{
add () {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.add();
})
// 加载子表数据
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>
}
},
/** 整理成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>
}
edit (record) {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.edit(record);
})
},
validateError(msg){
this.$message.error(msg)
close () {
this.$emit('close');
this.visible = false;
},
popupCallback(row){
this.form.setFieldsValue(pick(row<#list columns as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>))
},
<#if form_cat_tree>
handleCategoryChange(value,backObj){
this.form.setFieldsValue(backObj)
handleOk () {
this.$refs.realForm.handleOk();
},
submitCallback(){
this.$emit('ok');
this.visible = false;
},
handleCancel () {
this.close()
}
</#if>
}
}
</script>

View File

@ -3,10 +3,10 @@
<#if sub.foreignRelationType=='1'>
#segment#${sub.entityName}Form.vue
<template>
<div>
<a-form :form="form">
<j-form-container :disabled="disabled">
<a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
<a-row>
<#assign form_popup = false>
<#list sub.colums as po>
<#if po.isShow =='Y'>
<#assign form_field_dictCode="">
@ -17,67 +17,76 @@
</#if>
<#if po.classType =='textarea'>
<a-col :span="24">
<a-form-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2">
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2" prop="${autoStringSuffixForModel(po)}">
<#else>
<a-col :xs="24" :sm="12">
<a-form-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol">
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%"/>
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" style="width: 100%"/>
<#elseif po.classType =='datetime'>
<j-date placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"/>
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"/>
<#elseif po.classType =='time'>
<j-time placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
:trigger-change="true"
v-model="model.${po.fieldName}"
field="${po.fieldName}"
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
@callback="popupCallback"/>
@input="popupCallback"/>
<#elseif po.classType =='switch'>
<j-switch v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if>></j-switch>
<j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if>></j-switch>
<#elseif po.classType =='sel_depart'>
<j-select-depart v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true"/>
<j-select-depart v-model="model.${po.fieldName}" />
<#elseif po.classType =='sel_user'>
<j-select-user-by-dep v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true"/>
<j-select-user-by-dep v-model="model.${po.fieldName}" />
<#elseif po.classType =='textarea'>
<a-textarea v-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" rows="4" placeholder="请输入${po.filedComment}"/>
<a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}"/>
<#elseif po.classType=='list' || po.classType=='radio'>
<j-dict-select-tag type="${po.classType}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<j-dict-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
<j-multi-select-tag type="${po.classType}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<j-multi-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
<a-input-number v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" style="width: 100%"/>
<a-input-number v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" style="width: 100%"/>
<#elseif po.classType=='file'>
<j-upload v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true"></j-upload>
<j-upload v-model="model.${po.fieldName}" ></j-upload>
<#elseif po.classType=='image'>
<j-image-upload isMultiple v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"></j-image-upload>
<j-image-upload isMultiple v-model="model.${po.fieldName}"></j-image-upload>
<#else>
<a-input v-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}"></a-input>
<a-input v-model="model.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}"></a-input>
</#if>
</a-form-item>
</a-form-model-item>
</a-col>
</#if>
</#list>
</a-row>
</a-form>
</div>
</a-form-model>
</j-form-container>
</template>
<script>
import pick from 'lodash.pick'
import { getAction } from '@/api/manage'
import { validateDuplicateValue } from '@/utils/util'
import { VALIDATE_NO_PASSED } from '@/utils/JEditableTableUtil'
export default {
name: '${sub.entityName}Form',
components: {
},
props:{
disabled: {
type: Boolean,
default: false,
required: false
}
},
data () {
return {
form: this.$form.createForm(this),
model: {},
model:{
<#include "/common/init/initValueSub.ftl">
},
labelCol: {
xs: { span: 24 },
sm: { span: 6 },
@ -98,11 +107,15 @@
confirmLoading: false,
}
},
created () {
//备份model原始值
this.modelDefault = JSON.parse(JSON.stringify(this.model));
},
methods:{
initFormData(url,id){
this.clearFormData()
if(!id){
this.edit({})
this.edit(this.modelDefault);
}else{
getAction(url,{id:id}).then(res=>{
if(res.success){
@ -116,39 +129,47 @@
},
edit(record){
this.model = Object.assign({}, record)
console.log("${sub.entityName}Form-edit",this.model);
let fieldval = pick(this.model<#list sub.colums as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>)
this.$nextTick(() => {
this.form.setFieldsValue(fieldval)
})
},
getFormData(){
let formdata_arr = []
this.form.validateFields((err, values) => {
if (!err) {
let formdata = Object.assign(this.model, values)
this.$refs.form.validate(valid => {
if (valid) {
let isNullObj = true
Object.keys(formdata).forEach(key=>{
if(formdata[key]){
Object.keys(this.model).forEach(key=>{
if(this.model[key]){
isNullObj = false
}
})
if(!isNullObj){
formdata_arr.push(formdata)
formdata_arr.push(this.model)
}
}else{
this.$emit("validateError","${sub.ftlDescription}表单校验未通过");
return false
}
})
console.log("${sub.ftlDescription}表单数据集",formdata_arr);
return formdata_arr;
},
popupCallback(row){
this.form.setFieldsValue(pick(row<#list sub.colums as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>))
validate(index){
return new Promise((resolve, reject) => {
// 验证主表表单
this.$refs.form.validate(valid => {
!valid ? reject({ error: VALIDATE_NO_PASSED ,index}) : resolve()
})
}).then(values => {
return Promise.resolve()
}).catch(error => {
return Promise.reject(error)
})
},
<#if form_popup>
popupCallback(value,row){
this.model = Object.assign(this.model, row);
},
</#if>
clearFormData(){
this.form.resetFields()
this.model={}
this.$refs.form.clearValidate()
}
}

View File

@ -91,7 +91,7 @@
</#if>
<#elseif po.classType=='switch'>
dataIndex: '${po.fieldName}',
<#if po.dictField?default("")?trim?length gt 1>
<#if po.dictField != 'is_open'>
customRender: (text) => (!text ? "" : (text == ${po.dictField}[0] ? "是" : "否"))
<#else>
customRender: (text) => (!text ? "" : (text == "Y" ? "是" : "否"))

View File

@ -289,7 +289,7 @@
</#if>
<#elseif po.classType=='switch'>
dataIndex: '${po.fieldName}',
<#if po.dictField?default("")?trim?length gt 1>
<#if po.dictField != 'is_open'>
customRender: (text) => (!text ? "" : (text == ${po.dictField}[0] ? "是" : "否"))
<#else>
customRender: (text) => (!text ? "" : (text == "Y" ? "是" : "否"))

View File

@ -3,8 +3,9 @@
<a-spin :spinning="confirmLoading">
<j-form-container :disabled="formDisabled">
<!-- 主表单区域 -->
<a-form :form="form" slot="detail">
<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>
@ -25,65 +26,66 @@
</#if>
<#if po.classType =='textarea'>
<a-col :span="24">
<a-form-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2">
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2" prop="${autoStringSuffixForModel(po)}">
<#else>
<a-col :span="${form_span}" >
<a-form-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol">
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
:trigger-change="true"
v-model="model.${po.fieldName}"
field="${po.fieldName}"
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
@callback="popupCallback"
@input="popupCallback"
<#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_depart'>
<j-select-depart v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" multi <#if po.readonly=='Y'>disabled</#if>/>
<j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='switch'>
<j-switch v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入省市区" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="[${autoStringSuffix(po)},{initialValue:''}]" id="${po.fieldName}"></j-markdown-editor>
<j-markdown-editor v-model="model.${autoStringSuffixForModel(po)}" id="${po.fieldName}"></j-markdown-editor>
<#elseif po.classType =='password'>
<a-input-password v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.readonly=='Y'>disabled</#if>/>
<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>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" dict="${form_field_dictCode}" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${po.dictText}" @change="handleCategoryChange"</#if> <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" <#if po.readonly=='Y'>disabled</#if> <#if po.uploadnum??>:number=${po.uploadnum}</#if>></j-upload>
<j-upload v-model="model.${autoStringSuffixForModel(po)}" <#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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.readonly=='Y'>disabled</#if>></j-image-upload>
<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-decorator="[${autoStringSuffix(po)},{trigger:'input'}]" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
v-model="model.${autoStringSuffixForModel(po)}"
<#if po.dictText??>
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
dict="${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}"
@ -97,19 +99,14 @@
<#if po.readonly=='Y'>disabled</#if>>
</j-tree-select>
<#else>
<a-input v-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
<a-input v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
</#if>
</a-form-item>
<#if form_cat_tree && form_cat_back?length gt 1>
<a-form-item v-show="false">
<a-input v-decorator="['${form_cat_back}']"></a-input>
</a-form-item>
</#if>
</a-form-model-item>
</a-col>
</#if>
</#list>
</a-row>
</a-form>
</a-form-model>
</j-form-container>
<!-- 子表单区域 -->
<a-tabs v-model="activeKey" @change="handleChangeTabs">
@ -143,11 +140,10 @@
<script>
import pick from 'lodash.pick'
import { getAction } from '@/api/manage'
import { JVxeTableMixin } from '@/mixins/JVxeTableMixin.js'
import { JVxeTableModelMixin } from '@/mixins/JVxeTableModelMixin.js'
import { JVXETypes } from '@/components/jeecg/JVxeTable'
import { getRefPromise} from '@/components/jeecg/JVxeTable/utils/vxeUtils.js'
import { getRefPromise,VALIDATE_FAILED} from '@/components/jeecg/JVxeTable/utils/vxeUtils.js'
import { validateDuplicateValue } from '@/utils/util'
import JFormContainer from '@/components/jeecg/JFormContainer'
<#list subTables as sub>
@ -158,7 +154,7 @@
export default {
name: '${entityName}Form',
mixins: [JVxeTableMixin],
mixins: [JVxeTableModelMixin],
components: {
JFormContainer,
<#list subTables as sub>
@ -185,6 +181,9 @@
xs: { span: 24 },
sm: { span: 20 },
},
model:{
<#include "/common/init/initValue.ftl">
},
// 新增时子表默认添加几行空数据
addDefaultRowNum: 1,
<#include "/common/validatorRulesTemplate/main.ftl">
@ -207,7 +206,7 @@
<#if col.filedComment !='外键' >
{
title: '${col.filedComment}',
key: ${autoStringSuffix(col)},
key: '${autoStringSuffixForModel(col)}',
<#if col.classType =='date'>
type: JVXETypes.date,
<#if col.readonly=='Y'>
@ -282,11 +281,11 @@
</#if>
<#elseif col.classType =='switch'>
type: JVXETypes.checkbox,
<#if col.dictField?default("")?trim?length gt 1>
customValue:${col.dictField},
<#else>
customValue: ['Y', 'N'],
</#if>
<#if col.dictField == 'is_open'>
customValue: ['Y', 'N'],
<#else>
customValue: ${col.dictField},
</#if>
<#if col.readonly=='Y'>
disabled:true,
</#if>
@ -430,7 +429,6 @@
},
methods: {
addBefore(){
this.form.resetFields()
<#list subTables as sub><#rt/>
<#if sub.foreignRelationType =='1'>
this.$refs.${sub.entityName?uncap_first}Form.clearFormData()
@ -451,9 +449,7 @@
},
/** 调用完edit()方法之后会自动调用此方法 */
editAfter() {
let fieldval = pick(this.model<#list columns as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>)
this.$nextTick(() => {
this.form.setFieldsValue(fieldval)
<#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)
@ -470,6 +466,27 @@
</#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_FAILED) {
// 如果有未通过表单验证的子表就自动跳转到它所在的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)
@ -500,12 +517,14 @@
validateError(msg){
this.$message.error(msg)
},
popupCallback(row){
this.form.setFieldsValue(pick(row<#list columns as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>))
<#if form_popup>
popupCallback(value,row){
this.model = Object.assign(this.model, row);
},
</#if>
<#if form_cat_tree>
handleCategoryChange(value,backObj){
this.form.setFieldsValue(backObj)
this.model = Object.assign(this.model, backObj);
}
</#if>

View File

@ -4,8 +4,9 @@
#segment#${sub.entityName}Form.vue
<template>
<j-form-container :disabled="disabled">
<a-form :form="form" slot="detail">
<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>
@ -26,81 +27,76 @@
</#if>
<#if po.classType =='textarea'>
<a-col :span="24">
<a-form-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2">
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2" prop="${autoStringSuffixForModel(po)}">
<#else>
<a-col :span="${form_span}">
<a-form-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol">
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%"/>
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" style="width: 100%"/>
<#elseif po.classType =='datetime'>
<j-date placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"/>
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"/>
<#elseif po.classType =='time'>
<j-time placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
:trigger-change="true"
v-model="model.${po.fieldName}"
field="${po.fieldName}"
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
@callback="popupCallback"/>
@input="popupCallback"/>
<#elseif po.classType =='sel_depart'>
<j-select-depart v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" multi/>
<j-select-depart v-model="model.${po.fieldName}" multi/>
<#elseif po.classType =='switch'>
<j-switch v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if>></j-switch>
<j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if>></j-switch>
<#elseif po.classType =='pca'>
<j-area-linkage type="cascader" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入省市区"/>
<j-area-linkage type="cascader" v-model="model.${po.fieldName}" placeholder="请输入省市区"/>
<#elseif po.classType =='markdown'>
<j-markdown-editor v-decorator="[${autoStringSuffix(po)},{initialValue:''}]" id="${po.fieldName}"></j-markdown-editor>
<j-markdown-editor v-model="model.${autoStringSuffixForModel(po)}" id="${po.fieldName}"></j-markdown-editor>
<#elseif po.classType =='password'>
<a-input-password v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}"/>
<a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"/>
<#elseif po.classType =='sel_user'>
<j-select-user-by-dep v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"/>
<j-select-user-by-dep v-model="model.${po.fieldName}"/>
<#elseif po.classType =='textarea'>
<a-textarea v-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" rows="4" placeholder="请输入${po.filedComment}"/>
<a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}"/>
<#elseif po.classType=='list' || po.classType=='radio'>
<j-dict-select-tag type="${po.classType}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<j-dict-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
<j-multi-select-tag type="${po.classType}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<j-multi-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<#elseif po.classType=='sel_search'>
<j-search-select-tag v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" dict="${form_field_dictCode}" />
<j-search-select-tag v-model="model.${po.fieldName}" dict="${form_field_dictCode}" />
<#elseif po.classType=='cat_tree'>
<#assign form_cat_tree = true>
<j-category-select v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${po.dictText}" @change="handleCategoryChange"</#if>/>
<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.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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" style="width: 100%"/>
<a-input-number v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" style="width: 100%"/>
<#elseif po.classType=='file'>
<j-upload v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true"></j-upload>
<j-upload v-model="model.${po.fieldName}" ></j-upload>
<#elseif po.classType=='image'>
<j-image-upload isMultiple v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"></j-image-upload>
<j-image-upload isMultiple v-model="model.${po.fieldName}"></j-image-upload>
<#elseif po.classType=='umeditor'>
<j-editor v-decorator="[${autoStringSuffix(po)},{trigger:'input'}]"/>
<j-editor v-model="model.${autoStringSuffixForModel(po)}"/>
<#else>
<a-input v-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}"></a-input>
<a-input v-model="model.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}"></a-input>
</#if>
</a-form-item>
<#if form_cat_tree && form_cat_back?length gt 1>
<a-form-item v-show="false">
<a-input v-decorator="['${form_cat_back}']"></a-input>
</a-form-item>
</#if>
</a-form-model-item>
</a-col>
</#if>
</#list>
</a-row>
</a-form>
</a-form-model>
</j-form-container>
</template>
<script>
import pick from 'lodash.pick'
import { getAction } from '@/api/manage'
import { validateDuplicateValue } from '@/utils/util'
import JFormContainer from '@/components/jeecg/JFormContainer'
import { VALIDATE_FAILED } from '@/components/jeecg/JVxeTable/utils/vxeUtils.js'
export default {
name: '${sub.entityName}Form',
components: {
@ -115,8 +111,9 @@
},
data () {
return {
form: this.$form.createForm(this),
model: {},
model:{
<#include "/common/init/initValueSub.ftl">
},
labelCol: {
xs: { span: 24 },
sm: { span: 6 },
@ -137,11 +134,15 @@
confirmLoading: false,
}
},
created () {
//备份model原始值
this.modelDefault = JSON.parse(JSON.stringify(this.model));
},
methods:{
initFormData(url,id){
this.clearFormData()
if(!id){
this.edit({})
this.edit(this.modelDefault)
}else{
getAction(url,{id:id}).then(res=>{
if(res.success){
@ -155,43 +156,49 @@
},
edit(record){
this.model = Object.assign({}, record)
console.log("${sub.entityName}Form-edit",this.model);
let fieldval = pick(this.model<#list sub.colums as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>)
this.$nextTick(() => {
this.form.setFieldsValue(fieldval)
})
},
getFormData(){
let formdata_arr = []
this.form.validateFields((err, values) => {
if (!err) {
let formdata = Object.assign(this.model, values)
this.$refs.form.validate(valid => {
if (valid) {
let isNullObj = true
Object.keys(formdata).forEach(key=>{
if(formdata[key]){
Object.keys(this.model).forEach(key=>{
if(this.model[key]){
isNullObj = false
}
})
if(!isNullObj){
formdata_arr.push(formdata)
formdata_arr.push(this.model)
}
}else{
this.$emit("validateError","${sub.ftlDescription}表单校验未通过");
}
})
console.log("${sub.ftlDescription}表单数据集",formdata_arr);
return formdata_arr;
},
popupCallback(row){
this.form.setFieldsValue(pick(row<#list sub.colums as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>))
validate(index){
return new Promise((resolve, reject) => {
// 验证主表表单
this.$refs.form.validate(valid => {
!valid ? reject({ error: VALIDATE_FAILED ,index}) : resolve()
})
}).then(values => {
return Promise.resolve()
}).catch(error => {
return Promise.reject(error)
})
},
<#if form_popup>
popupCallback(value,row){
this.model = Object.assign(this.model, row);
},
</#if>
clearFormData(){
this.form.resetFields()
this.model={}
this.$refs.form.clearValidate()
},
<#if form_cat_tree>
handleCategoryChange(value,backObj){
this.form.setFieldsValue(backObj);
}
</#if>
}

View File

@ -273,7 +273,7 @@
</#if>
<#elseif po.classType=='switch'>
dataIndex: '${po.fieldName}',
<#if po.dictField?default("")?trim?length gt 1>
<#if po.dictField != 'is_open'>
customRender: (text) => (!text ? "" : (text == ${po.dictField}[0] ? "是" : "否"))
<#else>
customRender: (text) => (!text ? "" : (text == "Y" ? "是" : "否"))

View File

@ -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>

View File

@ -4,469 +4,56 @@
:width="1200"
:visible="visible"
:maskClosable="false"
:confirmLoading="confirmLoading"
switchFullscreen
@ok="handleOk"
@cancel="handleCancel">
<a-spin :spinning="confirmLoading">
<#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 :form="form">
<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-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2">
<#else>
<a-col :xs="24" :sm="12">
<a-form-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol">
</#if>
<#if po.classType =='date'>
<j-date placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='datetime'>
<j-date placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" :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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='popup'>
<j-popup
v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
:trigger-change="true"
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
@callback="popupCallback"
<#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_depart'>
<j-select-depart v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" multi <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='switch'>
<j-switch v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch>
<#elseif po.classType =='pca'>
<j-area-linkage type="cascader" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入省市区" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='markdown'>
<j-markdown-editor v-decorator="[${autoStringSuffix(po)},{initialValue:''}]" id="${po.fieldName}"></j-markdown-editor>
<#elseif po.classType =='password'>
<a-input-password v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType =='sel_user'>
<j-select-user-by-dep v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" 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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType=='sel_search'>
<j-search-select-tag v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" dict="${form_field_dictCode}" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType=='cat_tree'>
<#assign form_cat_tree = true>
<j-category-select v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType=='file'>
<j-upload v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" <#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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.readonly=='Y'>disabled</#if>></j-image-upload>
<#elseif po.classType=='umeditor'>
<j-editor v-decorator="[${autoStringSuffix(po)},{trigger:'input'}]" <#if po.readonly=='Y'>disabled</#if>/>
<#elseif po.classType == 'sel_tree'>
<j-tree-select
ref="treeSelect"
placeholder="请选择${po.filedComment}"
v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
<#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-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>></a-input>
</#if>
</a-form-item>
<#if form_cat_tree && form_cat_back?length gt 1>
<a-form-item v-show="false">
<a-input v-decorator="['${form_cat_back}']"></a-input>
</a-form-item>
</#if>
</a-col>
</#if>
</#list>
</a-row>
</a-form>
</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>
<${Format.humpToShortbar(entityName)}-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"/>
</j-modal>
</template>
<script>
import pick from 'lodash.pick'
import { FormTypes,getRefPromise } from '@/utils/JEditableTableUtil'
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
import { validateDuplicateValue } from '@/utils/util'
import { VALIDATE_NO_PASSED, validateFormAndTables } from '@/utils/JEditableTableUtil'
<#list subTables as sub>
<#if sub.foreignRelationType =='1'>
import ${sub.entityName}Form from './${sub.entityName}Form.vue'
</#if>
</#list>
import ${entityName}Form from './${entityName}Form'
export default {
name: '${entityName}Modal',
mixins: [JEditableTableMixin],
components: {
<#list subTables as sub>
<#if sub.foreignRelationType =='1'>
${sub.entityName}Form,
</#if>
</#list>
${entityName}Form
},
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,
<#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: ${autoStringSuffix(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?default("")?trim?length gt 1>
customValue:${col.dictField},
<#else>
customValue: ['Y', 'N'],
</#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>
}
title:'',
visible: false,
disableSubmit: false
}
},
methods: {
getAllTable() {
<#if hasOne2Many==true>
let values = this.tableKeys.map(key => getRefPromise(this, key))
return Promise.all(values)
<#else>
return new Promise(resolve => {
resolve([]);
methods:{
add () {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.add();
})
</#if>
},
/** 调用完edit()方法之后会自动调用此方法 */
editAfter() {
let fieldval = pick(this.model<#list columns as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>)
this.$nextTick(() => {
this.form.setFieldsValue(fieldval)
<#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>
edit (record) {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.edit(record);
})
// 加载子表数据
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>
}
},
/** 整理成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>
}
close () {
this.$emit('close');
this.visible = false;
},
/** 确定按钮点击事件 */
handleOk() {
/** 触发表单验证 */
this.getAllTable().then(tables => {
return validateFormAndTables(this.form, tables)
}).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)
handleOk () {
this.$refs.realForm.handleOk();
},
popupCallback(row){
this.form.setFieldsValue(pick(row<#list columns as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>))
},
<#if form_cat_tree>
handleCategoryChange(value,backObj){
this.form.setFieldsValue(backObj)
submitCallback(){
this.$emit('ok');
this.visible = false;
},
handleCancel () {
this.close()
}
</#if>
}
}
</script>

View File

@ -4,8 +4,9 @@
#segment#${sub.entityName}Form.vue
<template>
<j-form-container :disabled="disabled">
<a-form :form="form" slot="detail">
<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>
@ -26,80 +27,76 @@
</#if>
<#if po.classType =='textarea'>
<a-col :span="24">
<a-form-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2">
<a-form-model-item label="${po.filedComment}" :labelCol="labelCol2" :wrapperCol="wrapperCol2" prop="${autoStringSuffixForModel(po)}">
<#else>
<a-col :span="${form_span}">
<a-form-item label="${po.filedComment}" :labelCol="labelCol" :wrapperCol="wrapperCol">
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%"/>
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" style="width: 100%"/>
<#elseif po.classType =='datetime'>
<j-date placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"/>
<j-date placeholder="请选择${po.filedComment}" v-model="model.${po.fieldName}" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"/>
<#elseif po.classType =='time'>
<j-time placeholder="请选择${po.filedComment}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
<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-decorator="['${po.fieldName}'${autoWriteRules(po)}]"
:trigger-change="true"
v-model="model.${po.fieldName}"
field="${po.fieldName}"
org-fields="${po.dictField}"
dest-fields="${Format.underlineToHump(po.dictText)}"
code="${po.dictTable}"
@callback="popupCallback"/>
@input="popupCallback"/>
<#elseif po.classType =='sel_depart'>
<j-select-depart v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" multi/>
<j-select-depart v-model="model.${po.fieldName}" multi/>
<#elseif po.classType =='switch'>
<j-switch v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" <#if po.dictField?default("")?trim?length gt 1>:options="${po.dictField}"</#if>></j-switch>
<j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if>></j-switch>
<#elseif po.classType =='pca'>
<j-area-linkage type="cascader" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入省市区"/>
<j-area-linkage type="cascader" v-model="model.${po.fieldName}" placeholder="请输入省市区"/>
<#elseif po.classType =='markdown'>
<j-markdown-editor v-decorator="[${autoStringSuffix(po)},{initialValue:''}]" id="${po.fieldName}"></j-markdown-editor>
<j-markdown-editor v-model="model.${autoStringSuffixForModel(po)}" id="${po.fieldName}"></j-markdown-editor>
<#elseif po.classType =='password'>
<a-input-password v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}"/>
<a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"/>
<#elseif po.classType =='sel_user'>
<j-select-user-by-dep v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"/>
<j-select-user-by-dep v-model="model.${po.fieldName}"/>
<#elseif po.classType =='textarea'>
<a-textarea v-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" rows="4" placeholder="请输入${po.filedComment}"/>
<a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}"/>
<#elseif po.classType=='list' || po.classType=='radio'>
<j-dict-select-tag type="${po.classType}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<j-dict-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
<j-multi-select-tag type="${po.classType}" v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<j-multi-select-tag type="${po.classType}" v-model="model.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}"/>
<#elseif po.classType=='sel_search'>
<j-search-select-tag v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" dict="${form_field_dictCode}" />
<j-search-select-tag v-model="model.${po.fieldName}" dict="${form_field_dictCode}" />
<#elseif po.classType=='cat_tree'>
<#assign form_cat_tree = true>
<j-category-select v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${po.dictText}" @change="handleCategoryChange"</#if>/>
<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.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-decorator="['${po.fieldName}'${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}" style="width: 100%"/>
<a-input-number v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" style="width: 100%"/>
<#elseif po.classType=='file'>
<j-upload v-decorator="['${po.fieldName}'${autoWriteRules(po)}]" :trigger-change="true"></j-upload>
<j-upload v-model="model.${po.fieldName}"></j-upload>
<#elseif po.classType=='image'>
<j-image-upload isMultiple v-decorator="['${po.fieldName}'${autoWriteRules(po)}]"></j-image-upload>
<j-image-upload isMultiple v-model="model.${po.fieldName}"></j-image-upload>
<#elseif po.classType=='umeditor'>
<j-editor v-decorator="[${autoStringSuffix(po)},{trigger:'input'}]"/>
<j-editor v-model="model.${autoStringSuffixForModel(po)}"/>
<#else>
<a-input v-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" placeholder="请输入${po.filedComment}"></a-input>
<a-input v-model="model.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}"></a-input>
</#if>
</a-form-item>
<#if form_cat_tree && form_cat_back?length gt 1>
<a-form-item v-show="false">
<a-input v-decorator="['${form_cat_back}']"></a-input>
</a-form-item>
</#if>
</a-form-model-item>
</a-col>
</#if>
</#list>
</a-row>
</a-form>
</a-form-model>
</j-form-container>
</template>
<script>
import pick from 'lodash.pick'
import { getAction } from '@/api/manage'
import { validateDuplicateValue } from '@/utils/util'
import JFormContainer from '@/components/jeecg/JFormContainer'
import { VALIDATE_NO_PASSED } from '@/utils/JEditableTableUtil'
export default {
name: '${sub.entityName}Form',
@ -115,8 +112,9 @@
},
data () {
return {
form: this.$form.createForm(this),
model: {},
model: {
<#include "/common/init/initValueSub.ftl">
},
labelCol: {
xs: { span: 24 },
sm: { span: 6 },
@ -137,11 +135,15 @@
confirmLoading: false,
}
},
created () {
//备份model原始值
this.modelDefault = JSON.parse(JSON.stringify(this.model));
},
methods:{
initFormData(url,id){
this.clearFormData()
if(!id){
this.edit({})
this.edit(this.modelDefault);
}else{
getAction(url,{id:id}).then(res=>{
if(res.success){
@ -156,42 +158,50 @@
edit(record){
this.model = Object.assign({}, record)
console.log("${sub.entityName}Form-edit",this.model);
let fieldval = pick(this.model<#list sub.colums as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>)
this.$nextTick(() => {
this.form.setFieldsValue(fieldval)
})
},
getFormData(){
let formdata_arr = []
this.form.validateFields((err, values) => {
if (!err) {
let formdata = Object.assign(this.model, values)
this.$refs.form.validate(valid => {
if (valid) {
let isNullObj = true
Object.keys(formdata).forEach(key=>{
if(formdata[key]){
Object.keys(this.model).forEach(key=>{
if( this.model[key]){
isNullObj = false
}
})
if(!isNullObj){
formdata_arr.push(formdata)
formdata_arr.push(this.model)
}
}else{
this.$emit("validateError","${sub.ftlDescription}表单校验未通过");
return false
}
})
console.log("${sub.ftlDescription}表单数据集",formdata_arr);
return formdata_arr;
},
popupCallback(row){
this.form.setFieldsValue(pick(row<#list sub.colums as po><#if po.fieldName !='id'>,${autoStringSuffix(po)}</#if></#list>))
validate(index){
return new Promise((resolve, reject) => {
// 验证主表表单
this.$refs.form.validate(valid => {
!valid ? reject({ error: VALIDATE_NO_PASSED ,index}) : resolve()
})
}).then(values => {
return Promise.resolve()
}).catch(error => {
return Promise.reject(error)
})
},
<#if form_popup>
popupCallback(value,row){
this.model = Object.assign(this.model, row);
},
</#if>
clearFormData(){
this.form.resetFields()
this.model={}
this.$refs.form.clearValidate()
},
<#if form_cat_tree>
handleCategoryChange(value,backObj){
this.form.setFieldsValue(backObj);
this.model = Object.assign(this.model,backObj);
}
</#if>
}

View File

@ -10,35 +10,31 @@
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-model ref="form" :model="model" :rules="validatorRules">
<#list columns as po><#rt/>
<#if po.fieldName !='id'><#rt/>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="${po.filedComment}">
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="${po.fieldName}" label="${po.filedComment}">
<#if po.fieldType =='date'>
<a-date-picker v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<a-date-picker v-model="model.${po.fieldName}"/>
<#elseif po.fieldType =='datetime'>
<a-date-picker showTime format='YYYY-MM-DD HH:mm:ss' v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<a-date-picker showTime valueFormat='YYYY-MM-DD HH:mm:ss' v-model="model.${po.fieldName}" />
<#elseif "int,decimal,double,"?contains(po.fieldType)>
<a-input-number v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<a-input-number v-model="model.${po.fieldName}"/>
<#else>
<a-input placeholder="请输入${po.filedComment}" v-decorator="['${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<a-input placeholder="请输入${po.filedComment}" v-model="model.${po.fieldName}" />
</#if>
</a-form-item>
</a-form-model-item>
</#if>
</#list>
</a-form>
</a-form-model>
</a-spin>
</j-modal>
</template>
<script>
import { httpAction } from '@/api/manage'
import pick from 'lodash.pick'
import moment from "moment"
export default {
@ -58,12 +54,11 @@
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules:{
<#list columns as po>
<#if po.fieldName !='id'>
<#if po.nullable =='N'>
${po.fieldName}:{rules: [{ required: true, message: '请输入${po.filedComment}!' }]},
${po.fieldName}:[{ required: true, message: '请输入${po.filedComment}!' }],
</#if>
</#if>
</#list>
@ -78,32 +73,23 @@
},
methods: {
add () {
//初始化默认值
this.edit({});
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model<#list columns as po><#if po.fieldName !='id' && po.fieldType?index_of("date")==-1>,'${po.fieldName}'</#if></#list>))
//时间格式化
<#list columns as po>
<#if po.fieldName !='id' && po.fieldType?index_of("date")!=-1>
this.form.setFieldsValue({${po.fieldName}:this.model.${po.fieldName}?moment(this.model.${po.fieldName}):null})
</#if>
</#list>
});
},
close () {
this.$emit('close');
this.visible = false;
this.$refs.form.clearValidate();
},
handleOk () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
@ -114,18 +100,7 @@
httpurl+=this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
//时间格式化
<#list columns as po>
<#if po.fieldName !='id' && po.fieldType =='date'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format():null;
<#elseif po.fieldName !='id' && po.fieldType =='datetime'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format('YYYY-MM-DD HH:mm:ss'):null;
</#if>
</#list>
console.log(formData)
httpAction(httpurl,formData,method).then((res)=>{
httpAction(httpurl,this.model,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
@ -136,9 +111,8 @@
that.confirmLoading = false;
that.close();
})
}else{
return false;
}
})
},

View File

@ -5,41 +5,39 @@
placement="right"
:closable="false"
@close="close"
:visible="visible"
>
:visible="visible">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-model ref="form" :model="model" :rules="validatorRules">
<#list columns as po><#rt/>
<#if po.fieldName !='id'><#rt/>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="${po.filedComment}">
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="${po.fieldName}" label="${po.filedComment}">
<#if po.fieldType =='date'>
<a-date-picker v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<a-date-picker v-model="model.${po.fieldName}" />
<#elseif po.fieldType =='datetime'>
<a-date-picker showTime format='YYYY-MM-DD HH:mm:ss' v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<a-date-picker showTime valueFormat='YYYY-MM-DD HH:mm:ss' v-model="model.${po.fieldName}" />
<#elseif "int,decimal,double,"?contains(po.fieldType)>
<a-input-number v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<a-input-number v-model="model.${po.fieldName}" />
<#else>
<a-input placeholder="请输入${po.filedComment}" v-decorator="['${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<a-input placeholder="请输入${po.filedComment}" v-model="model.${po.fieldName}" />
</#if>
</a-form-item>
</a-form-model-item>
</#if>
</#list>
</a-form>
</a-form-model>
</a-spin>
<a-button type="primary" @click="handleOk">确定</a-button>
<a-button type="primary" @click="handleCancel">取消</a-button>
<div class="drawer-bootom-button">
<a-button type="primary" @click="handleOk">确定</a-button>
<a-button type="primary" @click="handleCancel">取消</a-button>
</div>
</a-drawer>
</template>
<script>
import { httpAction } from '@/api/manage'
import pick from 'lodash.pick'
import moment from "moment"
export default {
@ -59,12 +57,11 @@
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules:{
<#list columns as po>
<#if po.fieldName !='id'>
<#if po.nullable =='N'>
${po.fieldName}:{rules: [{ required: true, message: '请输入${po.filedComment}!' }]},
${po.fieldName}:[{ required: true, message: '请输入${po.filedComment}!' }],
</#if>
</#if>
</#list>
@ -79,32 +76,23 @@
},
methods: {
add () {
//初始化默认值
this.edit({});
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model<#list columns as po><#if po.fieldName !='id' && po.fieldType?index_of("date")==-1>,'${po.fieldName}'</#if></#list>))
//时间格式化
<#list columns as po>
<#if po.fieldName !='id' && po.fieldType?index_of("date")!=-1>
this.form.setFieldsValue({${po.fieldName}:this.model.${po.fieldName}?moment(this.model.${po.fieldName}):null})
</#if>
</#list>
});
},
close () {
this.$emit('close');
this.visible = false;
this.$refs.form.clearValidate();
},
handleOk () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
@ -115,18 +103,7 @@
httpurl+=this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
//时间格式化
<#list columns as po>
<#if po.fieldName !='id' && po.fieldType =='date'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format():null;
<#elseif po.fieldName !='id' && po.fieldType =='datetime'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format('YYYY-MM-DD HH:mm:ss'):null;
</#if>
</#list>
console.log(formData)
httpAction(httpurl,formData,method).then((res)=>{
httpAction(httpurl,this.model,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
@ -137,10 +114,9 @@
that.confirmLoading = false;
that.close();
})
}
}else{
return false;
}
})
},
handleCancel () {
@ -153,10 +129,22 @@
</script>
<style lang="less" scoped>
/** Button按钮间距 */
/**Button按钮间距*/
.ant-btn {
margin-left: 30px;
margin-bottom: 30px;
float: right;
}
/**抽屉按钮样式*/
.drawer-bootom-button {
position: absolute;
bottom: -8px;
width: 100%;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: right;
left: 0;
background: #fff;
border-radius: 0 0 2px 2px;
}
</style>

View File

@ -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>

View File

@ -4,181 +4,57 @@
:width="1200"
:visible="visible"
:maskClosable="false"
:confirmLoading="confirmLoading"
switchFullscreen
@ok="handleOk"
@cancel="handleCancel">
<a-spin :spinning="confirmLoading">
<!-- 主表单区域 -->
<a-form :form="form">
<#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-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="${columns[idx].filedComment}">
<#if columns[idx].fieldType =='date'>
<a-date-picker
placeholder="请输入${columns[idx].filedComment}"
style="width:100%"
v-decorator="[ '${columns[idx].fieldName}', <#if columns[idx].nullable =='N'>validatorRules.${columns[idx].fieldName} <#else>{}</#if>]"/>
<#elseif columns[idx].fieldType =='datetime'>
<a-date-picker
placeholder="请输入${columns[idx].filedComment}"
style="width:100%"
:showTime="true"
format="YYYY-MM-DD HH:mm:ss"
v-decorator="[ '${columns[idx].fieldName}', <#if columns[idx].nullable =='N'>validatorRules.${columns[idx].fieldName} <#else>{}</#if>]"/>
<#elseif "int,decimal,double,"?contains(columns[idx].fieldType)>
<a-input-number placeholder="请输入${columns[idx].filedComment}" style="width:100%" v-decorator="[ '${columns[idx].fieldName}', <#if columns[idx].nullable =='N'>validatorRules.${columns[idx].fieldName} <#else>{}</#if>]"/>
<#else>
<a-input placeholder="请输入${columns[idx].filedComment}" v-decorator="['${columns[idx].fieldName}', <#if columns[idx].nullable =='N'>validatorRules.${columns[idx].fieldName} <#else>{}</#if>]"/>
</#if>
</a-form-item>
</a-col>
</#if>
</#list><#rt/>
</#if><#rt/>
</a-row>
</#if><#rt/>
</#list>
</a-form>
<!-- 子表单区域 -->
<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>
<${Format.humpToShortbar(entityName)}-form ref="realForm" @ok="submitCallback"/>
</j-modal>
</template>
<script>
import moment from 'moment'
import pick from 'lodash.pick'
import { FormTypes } from '@/utils/JEditableTableUtil'
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
export default {
name: '${entityName}Modal',
mixins: [JEditableTableMixin],
data() {
return {
// 新增时子表默认添加几行空数据
addDefaultRowNum: 1,
validatorRules: {
<#list columns as po>
<#if po.fieldName !='id'>
<#if po.nullable =='N'>
${po.fieldName}: { rules: [{ 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() {
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, <#list columns as col>'${col.fieldName}', </#list>))
// 时间格式化
<#list columns as col><#rt/>
<#if col.fieldName !='id' && (col.fieldType =='date' || col.fieldType =='datetime')>
this.form.setFieldsValue({ ${col.fieldName}: this.model.${col.fieldName} ? moment(this.model.${col.fieldName}) : null })
</#if>
</#list>
})
// 加载子表数据
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)
//时间格式化
<#list columns as col><#rt/>
<#if col.fieldName !='id' && col.fieldType =='date'>
main.${col.fieldName} = main.${col.fieldName} ? main.${col.fieldName}.format() : null;
<#elseif col.fieldName !='id' && col.fieldType =='datetime'>
main.${col.fieldName} = main.${col.fieldName} ? main.${col.fieldName}.format('YYYY-MM-DD HH:mm:ss') : null;
</#if>
</#list>
return {
...main, // 展开
<#list subTables as sub><#rt/>
${sub.entityName?uncap_first}List: allValues.tablesValue[${sub_index}].values,
</#list>
}
}
}
}
import ${entityName}Form from './${entityName}Form'
export default {
name: '${entityName}Modal',
components: {
${entityName}Form
},
data() {
return {
title:'',
visible: false,
disableSubmit: false
}
},
methods:{
add () {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.add();
})
},
edit (record) {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.edit(record);
})
},
close () {
this.$emit('close');
this.visible = false;
},
handleOk () {
this.$refs.realForm.handleOk();
},
submitCallback(){
this.$emit('ok');
this.visible = false;
},
handleCancel () {
this.close()
}
}
}
</script>
<style scoped>

View File

@ -1,6 +1,6 @@
#mysql
diver_name=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/jeecg-boot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
diver_name=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jeecg-boot?useUnicode=true&characterEncoding=UTF-8
username=root
password=root
database_name=jeecg-boot

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-starter</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.4.2</version>
<version>2.4.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jeecg-boot-starter-cloud</artifactId>

View File

@ -7,9 +7,11 @@ import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.config.FeignConfig;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.cloud.openfeign.support.SpringEncoder;
@ -19,7 +21,6 @@ import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-starter</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.4.2</version>
<version>2.4.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jeecg-boot-starter-job</artifactId>

View File

@ -30,11 +30,14 @@ public class XxlJobConfiguration {
@ConditionalOnClass()
public XxlJobSpringExecutor xxlJobExecutor() {
log.info(">>>>>>>>>>> xxl-job config init.");
//log.info(">>>> ip="+xxlJobProperties.getIp()+"Port="+xxlJobProperties.getPort()+"address="+xxlJobProperties.getAdminAddresses());
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(xxlJobProperties.getAdminAddresses());
xxlJobSpringExecutor.setAppname(xxlJobProperties.getAppname());
//update-begin--Author:scott -- Date:20210305 -- forsystem服务和demo服务有办法同时使用xxl-job吗 #2313---
//xxlJobSpringExecutor.setIp(xxlJobProperties.getIp());
//xxlJobSpringExecutor.setPort(xxlJobProperties.getPort());
//update-end--Author:scott -- Date:20210305 -- forsystem服务和demo服务有办法同时使用xxl-job吗 #2313---
xxlJobSpringExecutor.setAccessToken(xxlJobProperties.getAccessToken());
xxlJobSpringExecutor.setLogPath(xxlJobProperties.getLogPath());
xxlJobSpringExecutor.setLogRetentionDays(xxlJobProperties.getLogRetentionDays());

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-starter</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.4.2</version>
<version>2.4.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jeecg-boot-starter-lock</artifactId>

View File

@ -14,7 +14,7 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface DistributedLock {
public @interface JLock {
/**
* :,,.使 REENTRANT MULTIPLE
@ -28,8 +28,7 @@ public @interface DistributedLock {
String[] lockKey() default {};
/**
* key:keyspelLIST,使+spel,,,<br />
* .
* key:keyspelLIST,使+spel
* @return
*/
String keyConstant() default "";

View File

@ -0,0 +1,36 @@
package org.jeecg.boot.starter.lock.annotation;
/**
* @author zyf
*/
import java.lang.annotation.*;
/**
*
*
* @author 2019618
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface JRepeat {
/**
*
*
* @return
*/
int lockTime();
/**
* redis key
*
* @return redis key
*/
String lockKey() default "";
}

View File

@ -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