mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-08 17:12:28 +08:00
JeecgBoot 3.1.0 版本发布,基于代码生成器的企业级低代码平台
This commit is contained in:
@ -11,6 +11,6 @@ WORKDIR /jeecg-boot
|
||||
EXPOSE 8080
|
||||
|
||||
ADD ./src/main/resources/jeecg ./config/jeecg
|
||||
ADD ./target/jeecg-boot-module-system-3.0.jar ./
|
||||
ADD ./target/jeecg-boot-module-system-3.1.0.jar ./
|
||||
|
||||
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-3.0.jar
|
||||
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-3.1.0.jar
|
||||
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-parent</artifactId>
|
||||
<version>3.0</version>
|
||||
<version>3.1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework</groupId>
|
||||
<artifactId>jeewx-api</artifactId>
|
||||
<version>1.4.6</version>
|
||||
<version>1.4.7</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
@ -54,7 +54,7 @@
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.jimureport</groupId>
|
||||
<artifactId>jimureport-spring-boot-starter</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.2</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
@ -62,7 +62,7 @@
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-module-demo</artifactId>
|
||||
<version>3.0</version>
|
||||
<version>3.1.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@ -1,12 +1,19 @@
|
||||
package org.jeecg;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.net.InetAddress;
|
||||
@ -17,6 +24,7 @@ import java.net.UnknownHostException;
|
||||
*/
|
||||
@Slf4j
|
||||
@SpringBootApplication
|
||||
@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class})
|
||||
public class JeecgSystemApplication extends SpringBootServletInitializer {
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package org.jeecg.config.jimureport;
|
||||
|
||||
import org.jeecg.common.constant.DataBaseConstant;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.SysUserCacheInfo;
|
||||
@ -20,6 +20,9 @@ import java.util.Map;
|
||||
* * 1.自定义获取登录token
|
||||
* * 2.自定义获取登录用户
|
||||
*/
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class JimuReportTokenService implements JmReportTokenServiceI {
|
||||
@Autowired
|
||||
@ -45,10 +48,16 @@ public class JimuReportTokenService implements JmReportTokenServiceI {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getUserInfo(String token) {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
String username = JwtUtil.getUsername(token);
|
||||
//此处通过token只能拿到一个信息 用户账号 后面的就是根据账号获取其他信息 查询数据或是走redis 用户根据自身业务可自定义
|
||||
SysUserCacheInfo userInfo = sysBaseAPI.getCacheUser(username);
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
SysUserCacheInfo userInfo = null;
|
||||
try {
|
||||
userInfo = sysBaseAPI.getCacheUser(username);
|
||||
} catch (Exception e) {
|
||||
log.error("获取用户信息异常:"+ e.getMessage());
|
||||
return map;
|
||||
}
|
||||
//设置账号名
|
||||
map.put(SYS_USER_CODE, userInfo.getSysUserCode());
|
||||
//设置部门编码
|
||||
|
||||
@ -1,46 +1,46 @@
|
||||
package org.jeecg.modules.ngalain.aop;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;;
|
||||
|
||||
|
||||
// 暂时注释掉,提高系统性能
|
||||
//@Aspect //定义一个切面
|
||||
//@Configuration
|
||||
public class LogRecordAspect {
|
||||
private static final Logger logger = LoggerFactory.getLogger(LogRecordAspect.class);
|
||||
|
||||
// 定义切点Pointcut
|
||||
@Pointcut("execution(public * org.jeecg.modules.*.*.*Controller.*(..))")
|
||||
public void excudeService() {
|
||||
}
|
||||
|
||||
@Around("excudeService()")
|
||||
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
|
||||
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
|
||||
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
|
||||
HttpServletRequest request = sra.getRequest();
|
||||
|
||||
String url = request.getRequestURL().toString();
|
||||
String method = request.getMethod();
|
||||
String uri = request.getRequestURI();
|
||||
String queryString = request.getQueryString();
|
||||
logger.info("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, queryString);
|
||||
|
||||
// result的值就是被拦截方法的返回值
|
||||
Object result = pjp.proceed();
|
||||
|
||||
logger.info("请求结束,controller的返回值是 " + result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
//package org.jeecg.modules.ngalain.aop;
|
||||
//
|
||||
//import javax.servlet.http.HttpServletRequest;
|
||||
//
|
||||
//import org.aspectj.lang.ProceedingJoinPoint;
|
||||
//import org.aspectj.lang.annotation.Around;
|
||||
//import org.aspectj.lang.annotation.Aspect;
|
||||
//import org.aspectj.lang.annotation.Pointcut;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//import org.springframework.web.context.request.RequestAttributes;
|
||||
//import org.springframework.web.context.request.RequestContextHolder;
|
||||
//import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
//import org.slf4j.Logger;
|
||||
//import org.slf4j.LoggerFactory;;
|
||||
//
|
||||
//
|
||||
//// 暂时注释掉,提高系统性能
|
||||
////@Aspect //定义一个切面
|
||||
////@Configuration
|
||||
//public class LogRecordAspect {
|
||||
//private static final Logger logger = LoggerFactory.getLogger(LogRecordAspect.class);
|
||||
//
|
||||
// // 定义切点Pointcut
|
||||
// @Pointcut("execution(public * org.jeecg.modules.*.*.*Controller.*(..))")
|
||||
// public void excudeService() {
|
||||
// }
|
||||
//
|
||||
// @Around("excudeService()")
|
||||
// public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
|
||||
// RequestAttributes ra = RequestContextHolder.getRequestAttributes();
|
||||
// ServletRequestAttributes sra = (ServletRequestAttributes) ra;
|
||||
// HttpServletRequest request = sra.getRequest();
|
||||
//
|
||||
// String url = request.getRequestURL().toString();
|
||||
// String method = request.getMethod();
|
||||
// String uri = request.getRequestURI();
|
||||
// String queryString = request.getQueryString();
|
||||
// logger.info("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, queryString);
|
||||
//
|
||||
// // result的值就是被拦截方法的返回值
|
||||
// Object result = pjp.proceed();
|
||||
//
|
||||
// logger.info("请求结束,controller的返回值是 " + result);
|
||||
// return result;
|
||||
// }
|
||||
//}
|
||||
@ -1,86 +1,86 @@
|
||||
package org.jeecg.modules.ngalain.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.modules.ngalain.service.NgAlainService;
|
||||
import org.jeecg.modules.system.service.ISysDictService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/ng-alain")
|
||||
public class NgAlainController {
|
||||
@Autowired
|
||||
private NgAlainService ngAlainService;
|
||||
@Autowired
|
||||
private ISysDictService sysDictService;
|
||||
|
||||
@RequestMapping(value = "/getAppData")
|
||||
@ResponseBody
|
||||
public JSONObject getAppData(HttpServletRequest request) throws Exception {
|
||||
String token=request.getHeader("X-Access-Token");
|
||||
JSONObject j = new JSONObject();
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
JSONObject userObjcet = new JSONObject();
|
||||
userObjcet.put("name", user.getUsername());
|
||||
userObjcet.put("avatar", user.getAvatar());
|
||||
userObjcet.put("email", user.getEmail());
|
||||
userObjcet.put("token", token);
|
||||
j.put("user", userObjcet);
|
||||
j.put("menu",ngAlainService.getMenu(user.getUsername()));
|
||||
JSONObject app = new JSONObject();
|
||||
app.put("name", "jeecg-boot-angular");
|
||||
app.put("description", "jeecg+ng-alain整合版本");
|
||||
j.put("app", app);
|
||||
return j;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/getDictItems/{dictCode}", method = RequestMethod.GET)
|
||||
public Object getDictItems(@PathVariable String dictCode) {
|
||||
log.info(" dictCode : "+ dictCode);
|
||||
Result<List<DictModel>> result = new Result<List<DictModel>>();
|
||||
List<DictModel> ls = null;
|
||||
try {
|
||||
ls = sysDictService.queryDictItemsByCode(dictCode);
|
||||
result.setSuccess(true);
|
||||
result.setResult(ls);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
result.error500("操作失败");
|
||||
return result;
|
||||
}
|
||||
List<JSONObject> dictlist=new ArrayList<>();
|
||||
for (DictModel l : ls) {
|
||||
JSONObject dict=new JSONObject();
|
||||
try {
|
||||
dict.put("value",Integer.parseInt(l.getValue()));
|
||||
} catch (NumberFormatException e) {
|
||||
dict.put("value",l.getValue());
|
||||
}
|
||||
dict.put("label",l.getText());
|
||||
dictlist.add(dict);
|
||||
}
|
||||
return dictlist;
|
||||
}
|
||||
@RequestMapping(value = "/getDictItemsByTable/{table}/{key}/{value}", method = RequestMethod.GET)
|
||||
public Object getDictItemsByTable(@PathVariable String table,@PathVariable String key,@PathVariable String value) {
|
||||
return this.ngAlainService.getDictByTable(table,key,value);
|
||||
}
|
||||
}
|
||||
//package org.jeecg.modules.ngalain.controller;
|
||||
//
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//
|
||||
//import javax.servlet.http.HttpServletRequest;
|
||||
//
|
||||
//import org.apache.shiro.SecurityUtils;
|
||||
//import org.jeecg.common.api.vo.Result;
|
||||
//import org.jeecg.common.system.vo.DictModel;
|
||||
//import org.jeecg.common.system.vo.LoginUser;
|
||||
//import org.jeecg.modules.ngalain.service.NgAlainService;
|
||||
//import org.jeecg.modules.system.service.ISysDictService;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.web.bind.annotation.PathVariable;
|
||||
//import org.springframework.web.bind.annotation.RequestMapping;
|
||||
//import org.springframework.web.bind.annotation.RequestMethod;
|
||||
//import org.springframework.web.bind.annotation.ResponseBody;
|
||||
//import org.springframework.web.bind.annotation.RestController;
|
||||
//
|
||||
//import com.alibaba.fastjson.JSONObject;
|
||||
//
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//
|
||||
//@Slf4j
|
||||
//@RestController
|
||||
//@RequestMapping("/sys/ng-alain")
|
||||
//public class NgAlainController {
|
||||
// @Autowired
|
||||
// private NgAlainService ngAlainService;
|
||||
// @Autowired
|
||||
// private ISysDictService sysDictService;
|
||||
//
|
||||
// @RequestMapping(value = "/getAppData")
|
||||
// @ResponseBody
|
||||
// public JSONObject getAppData(HttpServletRequest request) throws Exception {
|
||||
// String token=request.getHeader("X-Access-Token");
|
||||
// JSONObject j = new JSONObject();
|
||||
// LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
// JSONObject userObjcet = new JSONObject();
|
||||
// userObjcet.put("name", user.getUsername());
|
||||
// userObjcet.put("avatar", user.getAvatar());
|
||||
// userObjcet.put("email", user.getEmail());
|
||||
// userObjcet.put("token", token);
|
||||
// j.put("user", userObjcet);
|
||||
// j.put("menu",ngAlainService.getMenu(user.getUsername()));
|
||||
// JSONObject app = new JSONObject();
|
||||
// app.put("name", "jeecg-boot-angular");
|
||||
// app.put("description", "jeecg+ng-alain整合版本");
|
||||
// j.put("app", app);
|
||||
// return j;
|
||||
// }
|
||||
//
|
||||
// @RequestMapping(value = "/getDictItems/{dictCode}", method = RequestMethod.GET)
|
||||
// public Object getDictItems(@PathVariable String dictCode) {
|
||||
// log.info(" dictCode : "+ dictCode);
|
||||
// Result<List<DictModel>> result = new Result<List<DictModel>>();
|
||||
// List<DictModel> ls = null;
|
||||
// try {
|
||||
// ls = sysDictService.queryDictItemsByCode(dictCode);
|
||||
// result.setSuccess(true);
|
||||
// result.setResult(ls);
|
||||
// } catch (Exception e) {
|
||||
// log.error(e.getMessage(),e);
|
||||
// result.error500("操作失败");
|
||||
// return result;
|
||||
// }
|
||||
// List<JSONObject> dictlist=new ArrayList<>();
|
||||
// for (DictModel l : ls) {
|
||||
// JSONObject dict=new JSONObject();
|
||||
// try {
|
||||
// dict.put("value",Integer.parseInt(l.getValue()));
|
||||
// } catch (NumberFormatException e) {
|
||||
// dict.put("value",l.getValue());
|
||||
// }
|
||||
// dict.put("label",l.getText());
|
||||
// dictlist.add(dict);
|
||||
// }
|
||||
// return dictlist;
|
||||
// }
|
||||
// @RequestMapping(value = "/getDictItemsByTable/{table}/{key}/{value}", method = RequestMethod.GET)
|
||||
// public Object getDictItemsByTable(@PathVariable String table,@PathVariable String key,@PathVariable String value) {
|
||||
// return this.ngAlainService.getDictByTable(table,key,value);
|
||||
// }
|
||||
//}
|
||||
|
||||
@ -6,10 +6,12 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.ImportExcelUtil;
|
||||
import org.jeecg.modules.quartz.entity.QuartzJob;
|
||||
import org.jeecg.modules.quartz.service.IQuartzJobService;
|
||||
@ -145,14 +147,14 @@ public class QuartzJobController {
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@GetMapping(value = "/pause")
|
||||
@ApiOperation(value = "暂停定时任务")
|
||||
@ApiOperation(value = "停止定时任务")
|
||||
public Result<Object> pauseJob(@RequestParam(name = "id") String id) {
|
||||
QuartzJob job = quartzJobService.getById(id);
|
||||
if (job == null) {
|
||||
return Result.error("定时任务不存在!");
|
||||
}
|
||||
quartzJobService.pause(job);
|
||||
return Result.ok("暂停定时任务成功");
|
||||
return Result.ok("停止定时任务成功");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,7 +165,7 @@ public class QuartzJobController {
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@GetMapping(value = "/resume")
|
||||
@ApiOperation(value = "恢复定时任务")
|
||||
@ApiOperation(value = "启动定时任务")
|
||||
public Result<Object> resumeJob(@RequestParam(name = "id") String id) {
|
||||
QuartzJob job = quartzJobService.getById(id);
|
||||
if (job == null) {
|
||||
@ -171,7 +173,7 @@ public class QuartzJobController {
|
||||
}
|
||||
quartzJobService.resumeJob(job);
|
||||
//scheduler.resumeJob(JobKey.jobKey(job.getJobClassName().trim()));
|
||||
return Result.ok("恢复定时任务成功");
|
||||
return Result.ok("启动定时任务成功");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -202,8 +204,12 @@ public class QuartzJobController {
|
||||
// 导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "定时任务列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, QuartzJob.class);
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("定时任务列表数据", "导出人:Jeecg", "导出信息"));
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
|
||||
//获取当前登录用户
|
||||
//update-begin---author:wangshuai ---date:20211227 for:[JTC-116]导出人写死了------------
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("定时任务列表数据", "导出人:"+user.getRealname(), "导出信息"));
|
||||
//update-end---author:wangshuai ---date:20211227 for:[JTC-116]导出人写死了------------
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
|
||||
return mv;
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ public class SampleJob implements Job {
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||
|
||||
log.info(" Job Execution key:"+jobExecutionContext.getJobDetail().getKey());
|
||||
log.info(String.format(" Jeecg-Boot 普通定时任务 SampleJob ! 时间:" + DateUtils.getTimestamp()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,6 +47,15 @@ public class DuplicateCheckController {
|
||||
//SQL注入校验(只限制非法串改数据库)
|
||||
final String[] sqlInjCheck = {duplicateCheckVo.getTableName(),duplicateCheckVo.getFieldName()};
|
||||
SqlInjectionUtil.filterContent(sqlInjCheck);
|
||||
// update-begin-author:taoyan date:20211227 for: JTC-25 【online报表】oracle 操作问题 录入弹框啥都不填直接保存 ①编码不是应该提示必填么?②报错也应该是具体文字提示,不是后台错误日志
|
||||
if(StringUtils.isEmpty(duplicateCheckVo.getFieldVal())){
|
||||
Result rs = new Result();
|
||||
rs.setCode(500);
|
||||
rs.setSuccess(true);
|
||||
rs.setMessage("数据为空,不作处理!");
|
||||
return rs;
|
||||
}
|
||||
// update-end-author:taoyan date:20211227 for: JTC-25 【online报表】oracle 操作问题 录入弹框啥都不填直接保存 ①编码不是应该提示必填么?②报错也应该是具体文字提示,不是后台错误日志
|
||||
if (StringUtils.isNotBlank(duplicateCheckVo.getDataId())) {
|
||||
// [2].编辑页面校验
|
||||
num = sysDictMapper.duplicateCheckCountSql(duplicateCheckVo);
|
||||
|
||||
@ -4,6 +4,7 @@ import cn.hutool.core.util.RandomUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyuncs.exceptions.ClientException;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -58,8 +59,6 @@ public class LoginController {
|
||||
@Resource
|
||||
private BaseCommonService baseCommonService;
|
||||
|
||||
private static final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
|
||||
|
||||
@ApiOperation("登录接口")
|
||||
@RequestMapping(value = "/login", method = RequestMethod.POST)
|
||||
public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel){
|
||||
@ -82,6 +81,7 @@ public class LoginController {
|
||||
Object checkCode = redisUtil.get(realKey);
|
||||
//当进入登录页时,有一定几率出现验证码错误 #1714
|
||||
if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) {
|
||||
log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", sysLoginModel.getCheckKey(), lowerCaseCaptcha, checkCode);
|
||||
result.error500("验证码错误");
|
||||
return result;
|
||||
}
|
||||
@ -402,7 +402,10 @@ public class LoginController {
|
||||
// update-begin--Author:sunjianlei Date:20210802 for:获取用户租户信息
|
||||
String tenantIds = sysUser.getRelTenantIds();
|
||||
if (oConvertUtils.isNotEmpty(tenantIds)) {
|
||||
List<String> tenantIdList = Arrays.asList(tenantIds.split(","));
|
||||
List<Integer> tenantIdList = new ArrayList<>();
|
||||
for(String id: tenantIds.split(",")){
|
||||
tenantIdList.add(Integer.valueOf(id));
|
||||
}
|
||||
// 该方法仅查询有效的租户,如果返回0个就说明所有的租户均无效。
|
||||
List<SysTenant> tenantList = sysTenantService.queryEffectiveTenant(tenantIdList);
|
||||
if (tenantList.size() == 0) {
|
||||
@ -450,10 +453,17 @@ public class LoginController {
|
||||
public Result<String> randomImage(HttpServletResponse response,@PathVariable String key){
|
||||
Result<String> res = new Result<String>();
|
||||
try {
|
||||
//生成验证码
|
||||
final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
|
||||
String code = RandomUtil.randomString(BASE_CHECK_CODES,4);
|
||||
|
||||
//存到redis中
|
||||
String lowerCaseCode = code.toLowerCase();
|
||||
String realKey = MD5Util.MD5Encode(lowerCaseCode+key, "utf-8");
|
||||
log.info("获取验证码,Redis checkCode = {},key = {}", code, key);
|
||||
redisUtil.set(realKey, lowerCaseCode, 60);
|
||||
|
||||
//返回前端
|
||||
String base64 = RandImageUtil.generate(code);
|
||||
res.setSuccess(true);
|
||||
res.setResult(base64);
|
||||
@ -495,13 +505,16 @@ public class LoginController {
|
||||
if(oConvertUtils.isEmpty(orgCode)) {
|
||||
//如果当前用户无选择部门 查看部门关联信息
|
||||
List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
|
||||
//update-begin-author:taoyan date:20220117 for: JTC-1068【app】新建用户,没有设置部门及角色,点击登录提示暂未归属部,一直在登录页面 使用手机号登录 可正常
|
||||
if (departs == null || departs.size() == 0) {
|
||||
result.error500("用户暂未归属部门,不可登录!");
|
||||
return result;
|
||||
/*result.error500("用户暂未归属部门,不可登录!");
|
||||
return result;*/
|
||||
}else{
|
||||
orgCode = departs.get(0).getOrgCode();
|
||||
sysUser.setOrgCode(orgCode);
|
||||
this.sysUserService.updateUserDepart(username, orgCode);
|
||||
}
|
||||
orgCode = departs.get(0).getOrgCode();
|
||||
sysUser.setOrgCode(orgCode);
|
||||
this.sysUserService.updateUserDepart(username, orgCode);
|
||||
//update-end-author:taoyan date:20220117 for: JTC-1068【app】新建用户,没有设置部门及角色,点击登录提示暂未归属部,一直在登录页面 使用手机号登录 可正常
|
||||
}
|
||||
JSONObject obj = new JSONObject();
|
||||
//用户登录信息
|
||||
@ -542,5 +555,58 @@ public class LoginController {
|
||||
}
|
||||
return Result.ok();
|
||||
}
|
||||
/**
|
||||
* 登录二维码
|
||||
*/
|
||||
@ApiOperation(value = "登录二维码", notes = "登录二维码")
|
||||
@GetMapping("/getLoginQrcode")
|
||||
public Result<?> getLoginQrcode() {
|
||||
String qrcodeId = CommonConstant.LOGIN_QRCODE_PRE+IdWorker.getIdStr();
|
||||
//定义二维码参数
|
||||
Map params = new HashMap(5);
|
||||
params.put("qrcodeId", qrcodeId);
|
||||
//存放二维码唯一标识30秒有效
|
||||
redisUtil.set(CommonConstant.LOGIN_QRCODE + qrcodeId, qrcodeId, 30);
|
||||
return Result.OK(params);
|
||||
}
|
||||
/**
|
||||
* 扫码二维码
|
||||
*/
|
||||
@ApiOperation(value = "扫码登录二维码", notes = "扫码登录二维码")
|
||||
@PostMapping("/scanLoginQrcode")
|
||||
public Result<?> scanLoginQrcode(@RequestParam String qrcodeId, @RequestParam String token) {
|
||||
Object check = redisUtil.get(CommonConstant.LOGIN_QRCODE + qrcodeId);
|
||||
if (oConvertUtils.isNotEmpty(check)) {
|
||||
//存放token给前台读取
|
||||
redisUtil.set(CommonConstant.LOGIN_QRCODE_TOKEN+qrcodeId, token, 60);
|
||||
} else {
|
||||
return Result.error("二维码已过期,请刷新后重试");
|
||||
}
|
||||
return Result.OK("扫码成功");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户扫码后保存的token
|
||||
*/
|
||||
@ApiOperation(value = "获取用户扫码后保存的token", notes = "获取用户扫码后保存的token")
|
||||
@GetMapping("/getQrcodeToken")
|
||||
public Result getQrcodeToken(@RequestParam String qrcodeId) {
|
||||
Object token = redisUtil.get(CommonConstant.LOGIN_QRCODE_TOKEN + qrcodeId);
|
||||
Map result = new HashMap();
|
||||
Object qrcodeIdExpire = redisUtil.get(CommonConstant.LOGIN_QRCODE + qrcodeId);
|
||||
if (oConvertUtils.isEmpty(qrcodeIdExpire)) {
|
||||
//二维码过期通知前台刷新
|
||||
result.put("token", "-2");
|
||||
return Result.OK(result);
|
||||
}
|
||||
if (oConvertUtils.isNotEmpty(token)) {
|
||||
result.put("success", true);
|
||||
result.put("token", token);
|
||||
} else {
|
||||
result.put("token", "-1");
|
||||
}
|
||||
return Result.OK(result);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* vue3前端临时接口
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/")
|
||||
@Slf4j
|
||||
public class MockVue3Controller {
|
||||
|
||||
|
||||
}
|
||||
@ -14,6 +14,7 @@ import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.CommonSendStatus;
|
||||
import org.jeecg.common.constant.WebsocketConst;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
@ -93,18 +94,21 @@ public class SysAnnouncementController {
|
||||
HttpServletRequest req) {
|
||||
Result<IPage<SysAnnouncement>> result = new Result<IPage<SysAnnouncement>>();
|
||||
sysAnnouncement.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
|
||||
QueryWrapper<SysAnnouncement> queryWrapper = new QueryWrapper<SysAnnouncement>(sysAnnouncement);
|
||||
QueryWrapper<SysAnnouncement> queryWrapper = QueryGenerator.initQueryWrapper(sysAnnouncement, req.getParameterMap());
|
||||
Page<SysAnnouncement> page = new Page<SysAnnouncement>(pageNo,pageSize);
|
||||
|
||||
//update-begin-author:lvdandan date:20211229 for: sqlserver mssql-jdbc 8.2.2.jre8版本下系统公告列表查询报错 查询SQL中生成了两个create_time DESC;故注释此段代码
|
||||
//排序逻辑 处理
|
||||
String column = req.getParameter("column");
|
||||
String order = req.getParameter("order");
|
||||
if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
|
||||
if("asc".equals(order)) {
|
||||
queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
|
||||
}else {
|
||||
queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
|
||||
}
|
||||
}
|
||||
// String column = req.getParameter("column");
|
||||
// String order = req.getParameter("order");
|
||||
// if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
|
||||
// if("asc".equals(order)) {
|
||||
// queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
|
||||
// }else {
|
||||
// queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
|
||||
// }
|
||||
// }
|
||||
//update-end-author:lvdandan date:20211229 for: sqlserver mssql-jdbc 8.2.2.jre8版本下系统公告列表查询报错 查询SQL中生成了两个create_time DESC;故注释此段代码
|
||||
IPage<SysAnnouncement> pageList = sysAnnouncementService.page(page, queryWrapper);
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
@ -337,11 +341,13 @@ public class SysAnnouncementController {
|
||||
query.eq(SysAnnouncementSend::getUserId,userId);
|
||||
SysAnnouncementSend one = sysAnnouncementSendService.getOne(query);
|
||||
if(null==one){
|
||||
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
|
||||
announcementSend.setAnntId(announcements.get(i).getId());
|
||||
announcementSend.setUserId(userId);
|
||||
announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
|
||||
sysAnnouncementSendService.save(announcementSend);
|
||||
log.info("listByUser接口新增了SysAnnouncementSend:pageSize{}:"+pageSize);
|
||||
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
|
||||
announcementSend.setAnntId(announcements.get(i).getId());
|
||||
announcementSend.setUserId(userId);
|
||||
announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
|
||||
sysAnnouncementSendService.save(announcementSend);
|
||||
log.info("announcementSend.toString()",announcementSend.toString());
|
||||
}
|
||||
//update-end--Author:wangshuai Date:20200803 for: 通知公告消息重复LOWCOD-759------------
|
||||
}
|
||||
@ -373,7 +379,7 @@ public class SysAnnouncementController {
|
||||
LambdaQueryWrapper<SysAnnouncement> queryWrapper = new LambdaQueryWrapper<SysAnnouncement>(sysAnnouncement);
|
||||
//Step.2 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
queryWrapper.eq(SysAnnouncement::getDelFlag,CommonConstant.DEL_FLAG_0);
|
||||
queryWrapper.eq(SysAnnouncement::getDelFlag,CommonConstant.DEL_FLAG_0.toString());
|
||||
List<SysAnnouncement> pageList = sysAnnouncementService.list(queryWrapper);
|
||||
//导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "系统通告列表");
|
||||
|
||||
@ -10,6 +10,7 @@ import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.WebsocketConst;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.SqlInjectionUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.message.websocket.WebSocket;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
||||
@ -69,6 +70,11 @@ public class SysAnnouncementSendController {
|
||||
//排序逻辑 处理
|
||||
String column = req.getParameter("column");
|
||||
String order = req.getParameter("order");
|
||||
|
||||
//issues/3331 SQL injection vulnerability
|
||||
SqlInjectionUtil.filterContent(column);
|
||||
SqlInjectionUtil.filterContent(order);
|
||||
|
||||
if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
|
||||
if("asc".equals(order)) {
|
||||
queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
|
||||
|
||||
@ -9,9 +9,11 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.ImportExcelUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.entity.SysCategory;
|
||||
import org.jeecg.modules.system.model.TreeSelectModel;
|
||||
@ -65,10 +67,16 @@ public class SysCategoryController {
|
||||
Result<IPage<SysCategory>> result = new Result<IPage<SysCategory>>();
|
||||
|
||||
//--author:os_chengtgen---date:20190804 -----for: 分类字典页面显示错误,issues:377--------start
|
||||
//QueryWrapper<SysCategory> queryWrapper = QueryGenerator.initQueryWrapper(sysCategory, req.getParameterMap());
|
||||
QueryWrapper<SysCategory> queryWrapper = new QueryWrapper<SysCategory>();
|
||||
queryWrapper.eq("pid", sysCategory.getPid());
|
||||
//--author:os_chengtgen---date:20190804 -----for: 分类字典页面显示错误,issues:377--------end
|
||||
//--author:liusq---date:20211119 -----for: 【vue3】分类字典页面查询条件配置--------start
|
||||
QueryWrapper<SysCategory> queryWrapper = QueryGenerator.initQueryWrapper(sysCategory, req.getParameterMap());
|
||||
String name = sysCategory.getName();
|
||||
String code = sysCategory.getCode();
|
||||
//QueryWrapper<SysCategory> queryWrapper = new QueryWrapper<SysCategory>();
|
||||
if(StringUtils.isBlank(name)&&StringUtils.isBlank(code)){
|
||||
queryWrapper.eq("pid", sysCategory.getPid());
|
||||
}
|
||||
//--author:liusq---date:20211119 -----for: 分类字典页面查询条件配置--------end
|
||||
//--author:os_chengtgen---date:20190804 -----for:【vue3】 分类字典页面显示错误,issues:377--------end
|
||||
|
||||
Page<SysCategory> page = new Page<SysCategory>(pageNo, pageSize);
|
||||
IPage<SysCategory> pageList = sysCategoryService.page(page, queryWrapper);
|
||||
@ -215,10 +223,13 @@ public class SysCategoryController {
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) throws IOException{
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
// 错误信息
|
||||
List<String> errorMessage = new ArrayList<>();
|
||||
int successLines = 0, errorLines = 0;
|
||||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
MultipartFile file = entity.getValue();// 获取上传文件对象
|
||||
ImportParams params = new ImportParams();
|
||||
params.setTitleRows(2);
|
||||
@ -229,7 +240,8 @@ public class SysCategoryController {
|
||||
//按照编码长度排序
|
||||
Collections.sort(listSysCategorys);
|
||||
log.info("排序后的list====>",listSysCategorys);
|
||||
for (SysCategory sysCategoryExcel : listSysCategorys) {
|
||||
for (int i = 0; i < listSysCategorys.size(); i++) {
|
||||
SysCategory sysCategoryExcel = listSysCategorys.get(i);
|
||||
String code = sysCategoryExcel.getCode();
|
||||
if(code.length()>3){
|
||||
String pCode = sysCategoryExcel.getCode().substring(0,code.length()-3);
|
||||
@ -242,12 +254,25 @@ public class SysCategoryController {
|
||||
}else{
|
||||
sysCategoryExcel.setPid("0");
|
||||
}
|
||||
sysCategoryService.save(sysCategoryExcel);
|
||||
try {
|
||||
sysCategoryService.save(sysCategoryExcel);
|
||||
successLines++;
|
||||
} catch (Exception e) {
|
||||
errorLines++;
|
||||
String message = e.getMessage().toLowerCase();
|
||||
int lineNumber = i + 1;
|
||||
// 通过索引名判断出错信息
|
||||
if (message.contains(CommonConstant.SQL_INDEX_UNIQ_CATEGORY_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:分类编码已经存在,忽略导入。");
|
||||
} else {
|
||||
errorMessage.add("第 " + lineNumber + " 行:未知错误,忽略导入");
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.ok("文件导入成功!数据行数:" + listSysCategorys.size());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("文件导入失败:"+e.getMessage());
|
||||
errorMessage.add("发生异常:" + e.getMessage());
|
||||
log.error(e.getMessage(), e);
|
||||
} finally {
|
||||
try {
|
||||
file.getInputStream().close();
|
||||
@ -256,7 +281,7 @@ public class SysCategoryController {
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.error("文件导入失败!");
|
||||
return ImportExcelUtil.imporReturnRes(errorLines,successLines,errorMessage);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -112,7 +112,7 @@ public class SysCheckRuleController extends JeecgController<SysCheckRule, ISysCh
|
||||
*/
|
||||
@AutoLog(value = "编码校验规则-编辑")
|
||||
@ApiOperation(value = "编码校验规则-编辑", notes = "编码校验规则-编辑")
|
||||
@PutMapping(value = "/edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result edit(@RequestBody SysCheckRule sysCheckRule) {
|
||||
sysCheckRuleService.updateById(sysCheckRule);
|
||||
return Result.ok("编辑成功!");
|
||||
|
||||
@ -14,6 +14,7 @@ import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
@ -57,6 +58,7 @@ public class SysDataSourceController extends JeecgController<SysDataSource, ISys
|
||||
*/
|
||||
@AutoLog(value = "多数据源管理-分页列表查询")
|
||||
@ApiOperation(value = "多数据源管理-分页列表查询", notes = "多数据源管理-分页列表查询")
|
||||
//@RequiresRoles("admin")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(
|
||||
SysDataSource sysDataSource,
|
||||
|
||||
@ -198,7 +198,7 @@ public class SysDepartController {
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles({"admin"})
|
||||
@RequestMapping(value = "/edit", method = RequestMethod.PUT)
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
@CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true)
|
||||
public Result<SysDepart> edit(@RequestBody SysDepart sysDepart, HttpServletRequest request) {
|
||||
String username = JwtUtil.getUserNameByToken(request);
|
||||
@ -322,7 +322,7 @@ public class SysDepartController {
|
||||
if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals( CommonConstant.USER_IDENTITY_2 )){
|
||||
departIds = user.getDepartIds();
|
||||
}
|
||||
List<SysDepartTreeModel> treeList = this.sysDepartService.searhBy(keyWord,myDeptSearch,departIds);
|
||||
List<SysDepartTreeModel> treeList = this.sysDepartService.searchByKeyWord(keyWord,myDeptSearch,departIds);
|
||||
if (treeList == null || treeList.size() == 0) {
|
||||
result.setSuccess(false);
|
||||
result.setMessage("未查询匹配数据!");
|
||||
@ -363,6 +363,8 @@ public class SysDepartController {
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
* 部门导入方案1: 通过机构编码来计算出部门的父级ID,维护上下级关系;
|
||||
* 部门导入方案2: 你也可以改造下程序,机构编码直接导入,先不设置父ID;全部导入后,写一个sql,补下父ID;
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
@ -418,6 +420,11 @@ public class SysDepartController {
|
||||
sysDepart.setOrgType(sysDepart.getOrgCode().length()/codeLength+"");
|
||||
//update-end---author:liusq Date:20210223 for:批量导入部门以后,不能追加下一级部门 #2245------------
|
||||
sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
|
||||
//update-begin---author:wangshuai ---date:20220105 for:[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
|
||||
if(oConvertUtils.isEmpty(sysDepart.getOrgCategory())){
|
||||
sysDepart.setOrgCategory("1");
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220105 for:[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
|
||||
ImportExcelUtil.importDateSaveOne(sysDepart, ISysDepartService.class, errorMessageList, num, CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE);
|
||||
num++;
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ public class SysDepartPermissionController extends JeecgController<SysDepartPerm
|
||||
* @return
|
||||
*/
|
||||
@ApiOperation(value="部门权限表-编辑", notes="部门权限表-编辑")
|
||||
@PutMapping(value = "/edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody SysDepartPermission sysDepartPermission) {
|
||||
sysDepartPermissionService.updateById(sysDepartPermission);
|
||||
return Result.ok("编辑成功!");
|
||||
|
||||
@ -114,7 +114,7 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
|
||||
*/
|
||||
//@RequiresRoles({"admin"})
|
||||
@ApiOperation(value="部门角色-编辑", notes="部门角色-编辑")
|
||||
@PutMapping(value = "/edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody SysDepartRole sysDepartRole) {
|
||||
sysDepartRoleService.updateById(sysDepartRole);
|
||||
return Result.ok("编辑成功!");
|
||||
|
||||
@ -496,7 +496,7 @@ public class SysDictController {
|
||||
try {
|
||||
//导入Excel格式校验,看匹配的字段文本概率
|
||||
Boolean t = ExcelImportCheckUtil.check(file.getInputStream(), SysDictPage.class, params);
|
||||
if(!t){
|
||||
if(t!=null && !t){
|
||||
throw new RuntimeException("导入Excel校验失败 !");
|
||||
}
|
||||
List<SysDictPage> list = ExcelImportUtil.importExcel(file.getInputStream(), SysDictPage.class, params);
|
||||
@ -511,11 +511,22 @@ public class SysDictController {
|
||||
Integer integer = sysDictService.saveMain(po, list.get(i).getSysDictItemList());
|
||||
if(integer>0){
|
||||
successLines++;
|
||||
}else{
|
||||
//update-begin---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
|
||||
}else if(integer == -1){
|
||||
errorLines++;
|
||||
errorMessage.add("字典名称:" + po.getDictName() + ",对应字典列表的字典项值不能为空,忽略导入。");
|
||||
}else{
|
||||
//update-end---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
|
||||
errorLines++;
|
||||
int lineNumber = i + 1;
|
||||
errorMessage.add("第 " + lineNumber + " 行:字典编码已经存在,忽略导入。");
|
||||
}
|
||||
//update-begin---author:wangshuai ---date:20220209 for:[JTC-1168]字典编号不能为空------------
|
||||
if(oConvertUtils.isEmpty(po.getDictCode())){
|
||||
errorMessage.add("第 " + lineNumber + " 行:字典编码不能为空,忽略导入。");
|
||||
}else{
|
||||
errorMessage.add("第 " + lineNumber + " 行:字典编码已经存在,忽略导入。");
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220209 for:[JTC-1168]字典编号不能为空------------
|
||||
}
|
||||
} catch (Exception e) {
|
||||
errorLines++;
|
||||
int lineNumber = i + 1;
|
||||
|
||||
@ -93,7 +93,7 @@ public class SysFillRuleController extends JeecgController<SysFillRule, ISysFill
|
||||
*/
|
||||
@AutoLog(value = "填值规则-编辑")
|
||||
@ApiOperation(value = "填值规则-编辑", notes = "填值规则-编辑")
|
||||
@PutMapping(value = "/edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody SysFillRule sysFillRule) {
|
||||
sysFillRuleService.updateById(sysFillRule);
|
||||
return Result.ok("编辑成功!");
|
||||
|
||||
@ -59,7 +59,7 @@ public class SysPermissionController {
|
||||
|
||||
/**
|
||||
* 加载数据节点
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
||||
@ -200,7 +200,7 @@ public class SysPermissionController {
|
||||
|
||||
/**
|
||||
* 查询用户拥有的菜单权限和按钮权限
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/getUserPermissionByToken", method = RequestMethod.GET)
|
||||
@ -261,32 +261,49 @@ public class SysPermissionController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 【vue3专用】查询用户拥有的按钮/表单访问权限
|
||||
* @return
|
||||
* 【vue3专用】获取
|
||||
* 1、查询用户拥有的按钮/表单访问权限
|
||||
* 2、所有权限 (菜单权限配置)
|
||||
* 3、系统安全模式 (开启则online报表的数据源必填)
|
||||
*/
|
||||
@RequestMapping(value = "/getPermCode", method = RequestMethod.GET)
|
||||
public Result<?> getPermCode() {
|
||||
Result<List<String>> result = new Result<List<String>>();
|
||||
try {
|
||||
//直接获取当前用户
|
||||
// 直接获取当前用户
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
//获取当前用户的权限集合
|
||||
if (oConvertUtils.isEmpty(loginUser)) {
|
||||
return Result.error("请登录系统!");
|
||||
}
|
||||
// 获取当前用户的权限集合
|
||||
List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getUsername());
|
||||
// 按钮权限(用户拥有的权限集合)
|
||||
List<String> codeList = metaList.stream()
|
||||
.filter((permission) -> CommonConstant.MENU_TYPE_2.equals(permission.getMenuType()) && CommonConstant.STATUS_1.equals(permission.getStatus()))
|
||||
.collect(ArrayList::new, (list, permission) -> list.add(permission.getPerms()), ArrayList::addAll);
|
||||
//
|
||||
JSONArray authArray = new JSONArray();
|
||||
this.getAuthJsonArray(authArray, metaList);
|
||||
// 查询所有的权限
|
||||
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
|
||||
query.eq(SysPermission::getMenuType, CommonConstant.MENU_TYPE_2);
|
||||
List<SysPermission> allAuthList = sysPermissionService.list(query);
|
||||
JSONArray allAuthArray = new JSONArray();
|
||||
this.getAllAuthJsonArray(allAuthArray, allAuthList);
|
||||
JSONObject result = new JSONObject();
|
||||
// 所拥有的权限编码
|
||||
result.put("codeList", codeList);
|
||||
//按钮权限(用户拥有的权限集合)
|
||||
List<String> authList = metaList.stream()
|
||||
.filter((permission) -> permission.getMenuType().equals(CommonConstant.MENU_TYPE_2)
|
||||
&& CommonConstant.STATUS_1.equals(permission.getStatus())
|
||||
)
|
||||
.collect(() -> new ArrayList<String>(),
|
||||
(list, permission) -> list.add(permission.getPerms()),
|
||||
(list1, list2) -> list1.addAll(list2)
|
||||
);
|
||||
result.setResult(authList);
|
||||
result.put("auth", authArray);
|
||||
//全部权限配置集合(按钮权限,访问权限)
|
||||
result.put("allAuth", allAuthArray);
|
||||
// 系统安全模式
|
||||
result.put("sysSafeMode", jeeccgBaseConfig.getSafeMode());
|
||||
return Result.OK(result);
|
||||
} catch (Exception e) {
|
||||
result.error500("查询失败:" + e.getMessage());
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("查询失败:" + e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -374,7 +391,7 @@ public class SysPermissionController {
|
||||
|
||||
/**
|
||||
* 获取全部的权限树
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryTreeList", method = RequestMethod.GET)
|
||||
@ -720,7 +737,7 @@ public class SysPermissionController {
|
||||
/**
|
||||
* 判断是否外网URL 例如: http://localhost:8080/jeecg-boot/swagger-ui.html#/ 支持特殊格式: {{
|
||||
* window._CONFIG['domianURL'] }}/druid/ {{ JS代码片段 }},前台解析会自动执行JS代码片段
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean isWWWHttpUrl(String url) {
|
||||
@ -733,7 +750,7 @@ public class SysPermissionController {
|
||||
/**
|
||||
* 通过URL生成路由name(去掉URL前缀斜杠,替换内容中的斜杠‘/’为-) 举例: URL = /isystem/role RouteName =
|
||||
* isystem-role
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String urlToRouteName(String url) {
|
||||
@ -753,7 +770,7 @@ public class SysPermissionController {
|
||||
|
||||
/**
|
||||
* 根据菜单id来获取其对应的权限数据
|
||||
*
|
||||
*
|
||||
* @param sysPermissionDataRule
|
||||
* @return
|
||||
*/
|
||||
@ -768,7 +785,7 @@ public class SysPermissionController {
|
||||
|
||||
/**
|
||||
* 添加菜单权限数据
|
||||
*
|
||||
*
|
||||
* @param sysPermissionDataRule
|
||||
* @return
|
||||
*/
|
||||
@ -803,7 +820,7 @@ public class SysPermissionController {
|
||||
|
||||
/**
|
||||
* 删除菜单权限数据
|
||||
*
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@ -823,7 +840,7 @@ public class SysPermissionController {
|
||||
|
||||
/**
|
||||
* 查询菜单权限数据
|
||||
*
|
||||
*
|
||||
* @param sysPermissionDataRule
|
||||
* @return
|
||||
*/
|
||||
|
||||
@ -8,10 +8,12 @@ import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.ImportExcelUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.quartz.service.IQuartzJobService;
|
||||
@ -208,10 +210,11 @@ public class SysPositionController {
|
||||
//Step.2 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
List<SysPosition> pageList = sysPositionService.list(queryWrapper);
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
//导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "职务表列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysPosition.class);
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("职务表列表数据", "导出人:Jeecg", "导出信息"));
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("职务表列表数据", "导出人:"+user.getRealname(),"导出信息"));
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
|
||||
return mv;
|
||||
}
|
||||
|
||||
@ -6,9 +6,11 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.annotation.PermissionData;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.entity.SysTenant;
|
||||
import org.jeecg.modules.system.service.ISysTenantService;
|
||||
@ -16,9 +18,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 租户配置信息
|
||||
@ -132,11 +132,11 @@ public class SysTenantController {
|
||||
}else {
|
||||
String[] ls = ids.split(",");
|
||||
// 过滤掉已被引用的租户
|
||||
List<String> idList = new ArrayList<>();
|
||||
List<Integer> idList = new ArrayList<>();
|
||||
for (String id : ls) {
|
||||
int userCount = sysTenantService.countUserLinkTenant(id);
|
||||
if (userCount == 0) {
|
||||
idList.add(id);
|
||||
idList.add(Integer.parseInt(id));
|
||||
}
|
||||
}
|
||||
if (idList.size() > 0) {
|
||||
@ -190,4 +190,32 @@ public class SysTenantController {
|
||||
result.setResult(ls);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* 查询当前用户的所有有效租户 【当前用于vue3版本】
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/getCurrentUserTenant", method = RequestMethod.GET)
|
||||
public Result<Map<String,Object>> getCurrentUserTenant() {
|
||||
Result<Map<String,Object>> result = new Result<Map<String,Object>>();
|
||||
try {
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
String tenantIds = sysUser.getRelTenantIds();
|
||||
Map<String,Object> map = new HashMap<String,Object>();
|
||||
if (oConvertUtils.isNotEmpty(tenantIds)) {
|
||||
List<Integer> tenantIdList = new ArrayList<>();
|
||||
for(String id: tenantIds.split(",")){
|
||||
tenantIdList.add(Integer.valueOf(id));
|
||||
}
|
||||
// 该方法仅查询有效的租户,如果返回0个就说明所有的租户均无效。
|
||||
List<SysTenant> tenantList = sysTenantService.queryEffectiveTenant(tenantIdList);
|
||||
map.put("list", tenantList);
|
||||
}
|
||||
result.setSuccess(true);
|
||||
result.setResult(map);
|
||||
}catch(Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
result.error500("查询失败!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,12 +108,38 @@ public class SysUserController {
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
|
||||
Result<IPage<SysUser>> result = new Result<IPage<SysUser>>();
|
||||
QueryWrapper<SysUser> queryWrapper = QueryGenerator.initQueryWrapper(user, req.getParameterMap());
|
||||
//TODO 外部模拟登陆临时账号,列表不显示
|
||||
|
||||
//update-begin-Author:wangshuai--Date:20211119--for:【vue3】通过部门id查询用户,通过code查询id
|
||||
//部门ID
|
||||
String departId = req.getParameter("departId");
|
||||
if(oConvertUtils.isNotEmpty(departId)){
|
||||
LambdaQueryWrapper<SysUserDepart> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysUserDepart::getDepId,departId);
|
||||
List<SysUserDepart> list = sysUserDepartService.list(query);
|
||||
List<String> userIds = list.stream().map(SysUserDepart::getUserId).collect(Collectors.toList());
|
||||
queryWrapper.in("id",userIds);
|
||||
}
|
||||
//用户ID
|
||||
String code = req.getParameter("code");
|
||||
if(oConvertUtils.isNotEmpty(code)){
|
||||
queryWrapper.in("id",Arrays.asList(code.split(",")));
|
||||
pageSize = code.split(",").length;
|
||||
}
|
||||
//update-end-Author:wangshuai--Date:20211119--for:【vue3】通过部门id查询用户,通过code查询id
|
||||
|
||||
//update-begin-author:taoyan--date:20220104--for: JTC-372 【用户冻结问题】 online授权、用户组件,选择用户都能看到被冻结的用户
|
||||
String status = req.getParameter("status");
|
||||
if(oConvertUtils.isNotEmpty(status)){
|
||||
queryWrapper.eq("status", Integer.parseInt(status));
|
||||
}
|
||||
//update-end-author:taoyan--date:20220104--for: JTC-372 【用户冻结问题】 online授权、用户组件,选择用户都能看到被冻结的用户
|
||||
|
||||
//TODO 外部模拟登陆临时账号,列表不显示
|
||||
queryWrapper.ne("username","_reserve_user_external");
|
||||
Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
|
||||
IPage<SysUser> pageList = sysUserService.page(page, queryWrapper);
|
||||
|
||||
//批量查询用户的所属部门
|
||||
//批量查询用户的所属部门
|
||||
//step.1 先拿到全部的 useids
|
||||
//step.2 通过 useids,一次性查询用户的所属部门名字
|
||||
List<String> userIds = pageList.getRecords().stream().map(SysUser::getId).collect(Collectors.toList());
|
||||
@ -492,6 +518,8 @@ public class SysUserController {
|
||||
errorMessage.add("第 " + lineNumber + " 行:手机号已经存在,忽略导入。");
|
||||
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_EMAIL)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:电子邮件已经存在,忽略导入。");
|
||||
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:违反表唯一性约束。");
|
||||
} else {
|
||||
errorMessage.add("第 " + lineNumber + " 行:未知错误,忽略导入");
|
||||
log.error(e.getMessage(), e);
|
||||
@ -1187,7 +1215,7 @@ public class SysUserController {
|
||||
* @param jsonObject
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/appEdit", method = RequestMethod.PUT)
|
||||
@RequestMapping(value = "/appEdit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<SysUser> appEdit(HttpServletRequest request,@RequestBody JSONObject jsonObject) {
|
||||
Result<SysUser> result = new Result<SysUser>();
|
||||
try {
|
||||
@ -1305,7 +1333,9 @@ public class SysUserController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/appQueryUser")
|
||||
public Result<List<SysUser>> appQueryUser(@RequestParam(name = "keyword", required = false) String keyword) {
|
||||
public Result<List<SysUser>> appQueryUser(@RequestParam(name = "keyword", required = false) String keyword,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
|
||||
Result<List<SysUser>> result = new Result<List<SysUser>>();
|
||||
LambdaQueryWrapper<SysUser> queryWrapper =new LambdaQueryWrapper<SysUser>();
|
||||
//TODO 外部模拟登陆临时账号,列表不显示
|
||||
@ -1313,18 +1343,19 @@ public class SysUserController {
|
||||
if(StringUtils.isNotBlank(keyword)){
|
||||
queryWrapper.and(i -> i.like(SysUser::getUsername, keyword).or().like(SysUser::getRealname, keyword));
|
||||
}
|
||||
List<SysUser> list = sysUserService.list(queryWrapper);
|
||||
Page<SysUser> page = new Page<>(pageNo, pageSize);
|
||||
IPage<SysUser> pageList = this.sysUserService.page(page, queryWrapper);
|
||||
//批量查询用户的所属部门
|
||||
//step.1 先拿到全部的 useids
|
||||
//step.2 通过 useids,一次性查询用户的所属部门名字
|
||||
List<String> userIds = list.stream().map(SysUser::getId).collect(Collectors.toList());
|
||||
List<String> userIds = pageList.getRecords().stream().map(SysUser::getId).collect(Collectors.toList());
|
||||
if(userIds!=null && userIds.size()>0){
|
||||
Map<String,String> useDepNames = sysUserService.getDepNamesByUserIds(userIds);
|
||||
list.forEach(item->{
|
||||
pageList.getRecords().forEach(item->{
|
||||
item.setOrgCodeTxt(useDepNames.get(item.getId()));
|
||||
});
|
||||
}
|
||||
result.setResult(list);
|
||||
result.setResult(pageList.getRecords());
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1374,6 +1405,9 @@ public class SysUserController {
|
||||
@GetMapping("/getMultiUser")
|
||||
public List<SysUser> getMultiUser(SysUser sysUser){
|
||||
QueryWrapper<SysUser> queryWrapper = QueryGenerator.initQueryWrapper(sysUser, null);
|
||||
//update-begin---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
|
||||
queryWrapper.eq("status",Integer.parseInt(CommonConstant.STATUS_1));
|
||||
//update-end---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
|
||||
List<SysUser> ls = this.sysUserService.list(queryWrapper);
|
||||
for(SysUser user: ls){
|
||||
user.setPassword(null);
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
@ -21,9 +20,11 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 在线用户
|
||||
@ -63,8 +64,20 @@ public class SysUserOnlineController {
|
||||
online.setToken(token);
|
||||
//TODO 改成一次性查询
|
||||
LoginUser loginUser = sysBaseAPI.getUserByName(JwtUtil.getUsername(token));
|
||||
BeanUtils.copyProperties(loginUser, online);
|
||||
onlineList.add(online);
|
||||
if (loginUser != null) {
|
||||
//update-begin---author:wangshuai ---date:20220104 for:[JTC-382]在线用户查询无效------------
|
||||
//验证用户名是否与传过来的用户名相同
|
||||
boolean isMatchUsername=true;
|
||||
//判断用户名是否为空,并且当前循环的用户不包含传过来的用户名,那么就设成false
|
||||
if(oConvertUtils.isNotEmpty(username) && !loginUser.getUsername().contains(username)){
|
||||
isMatchUsername = false;
|
||||
}
|
||||
if(isMatchUsername){
|
||||
BeanUtils.copyProperties(loginUser, online);
|
||||
onlineList.add(online);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220104 for:[JTC-382]在线用户查询无效------------
|
||||
}
|
||||
}
|
||||
}
|
||||
Collections.reverse(onlineList);
|
||||
|
||||
@ -91,8 +91,12 @@ public class ThirdAppController {
|
||||
@GetMapping("/sync/wechatEnterprise/depart/toApp")
|
||||
public Result syncWechatEnterpriseDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
|
||||
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||
boolean flag = wechatEnterpriseService.syncLocalDepartmentToThirdApp(ids);
|
||||
return flag ? Result.OK("同步成功", null) : Result.error("同步失败");
|
||||
SyncInfoVo syncInfo = wechatEnterpriseService.syncLocalDepartmentToThirdApp(ids);
|
||||
if (syncInfo.getFailInfo().size() == 0) {
|
||||
return Result.OK("同步成功", null);
|
||||
} else {
|
||||
return Result.error("同步失败", syncInfo);
|
||||
}
|
||||
}
|
||||
return Result.error("企业微信同步功能已禁用");
|
||||
}
|
||||
@ -125,8 +129,12 @@ public class ThirdAppController {
|
||||
@GetMapping("/sync/dingtalk/depart/toApp")
|
||||
public Result syncDingtalkDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
|
||||
if (thirdAppConfig.isDingtalkEnabled()) {
|
||||
boolean flag = dingtalkService.syncLocalDepartmentToThirdApp(ids);
|
||||
return flag ? Result.OK("同步成功", null) : Result.error("同步失败");
|
||||
SyncInfoVo syncInfo = dingtalkService.syncLocalDepartmentToThirdApp(ids);
|
||||
if (syncInfo.getFailInfo().size() == 0) {
|
||||
return Result.OK("同步成功", null);
|
||||
} else {
|
||||
return Result.error("同步失败", syncInfo);
|
||||
}
|
||||
}
|
||||
return Result.error("钉钉同步功能已禁用");
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ public class SysDepart implements Serializable {
|
||||
/**描述*/
|
||||
@Excel(name="描述",width=15)
|
||||
private String description;
|
||||
/**机构类别 1公司,2组织机构,2岗位*/
|
||||
/**机构类别 1=公司,2=组织机构,3=岗位*/
|
||||
@Excel(name="机构类别",width=15,dicCode="org_category")
|
||||
private String orgCategory;
|
||||
/**机构类型*/
|
||||
|
||||
@ -54,7 +54,6 @@ public class SysPosition {
|
||||
/**
|
||||
* 公司id
|
||||
*/
|
||||
@Excel(name = "公司id", width = 15)
|
||||
@ApiModelProperty(value = "公司id")
|
||||
private java.lang.String companyId;
|
||||
/**
|
||||
@ -84,7 +83,6 @@ public class SysPosition {
|
||||
/**
|
||||
* 组织机构编码
|
||||
*/
|
||||
@Excel(name = "组织机构编码", width = 15)
|
||||
@ApiModelProperty(value = "组织机构编码")
|
||||
private java.lang.String sysOrgCode;
|
||||
}
|
||||
|
||||
@ -3,12 +3,14 @@ package org.jeecg.modules.system.entity;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
/**
|
||||
* @Description: 第三方登录账号表
|
||||
@ -25,7 +27,7 @@ public class SysThirdAccount {
|
||||
|
||||
/**编号*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@ApiModelProperty(value = "编号")
|
||||
@ApiModelProperty(value = "编号")
|
||||
private java.lang.String id;
|
||||
/**第三方登录id*/
|
||||
@Excel(name = "第三方登录id", width = 15)
|
||||
@ -59,4 +61,20 @@ public class SysThirdAccount {
|
||||
@Excel(name = "第三方用户账号", width = 15)
|
||||
@ApiModelProperty(value = "第三方用户账号")
|
||||
private java.lang.String thirdUserId;
|
||||
/**创建人*/
|
||||
@Excel(name = "创建人", width = 15)
|
||||
private java.lang.String createBy;
|
||||
/**创建日期*/
|
||||
@Excel(name = "创建日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
private java.util.Date createTime;
|
||||
/**修改人*/
|
||||
@Excel(name = "修改人", width = 15)
|
||||
private java.lang.String updateBy;
|
||||
/**修改日期*/
|
||||
@Excel(name = "修改日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
private java.util.Date updateTime;
|
||||
}
|
||||
|
||||
@ -193,4 +193,15 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
|
||||
*/
|
||||
@Deprecated
|
||||
List<DictModel> queryAllTableDictItems(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql);
|
||||
|
||||
/**
|
||||
* 查询字典表的数据
|
||||
* @param table 表名
|
||||
* @param text 显示字段名
|
||||
* @param code 存储字段名
|
||||
* @param filterSql 条件sql
|
||||
* @param codeValues 存储字段值 作为查询条件in
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> queryTableDictByKeysAndFilterSql(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql, @Param("codeValues") List<String> codeValues);
|
||||
}
|
||||
|
||||
@ -134,19 +134,24 @@
|
||||
${pidField} as parentId
|
||||
from ${table}
|
||||
where
|
||||
<choose>
|
||||
<when test="pid != null and pid != ''">
|
||||
${pidField} = #{pid}
|
||||
</when>
|
||||
<otherwise>
|
||||
(${pidField} = '' OR ${pidField} IS NULL)
|
||||
</otherwise>
|
||||
</choose>
|
||||
<!-- udapte-begin-author:sunjianlei date:20220110 for: 【JTC-597】自定义树查询条件查不出数据 -->
|
||||
<if test="query == null">
|
||||
<choose>
|
||||
<when test="pid != null and pid != ''">
|
||||
${pidField} = #{pid}
|
||||
</when>
|
||||
<otherwise>
|
||||
(${pidField} = '' OR ${pidField} IS NULL)
|
||||
</otherwise>
|
||||
</choose>
|
||||
</if>
|
||||
<if test="query!= null">
|
||||
1 = 1
|
||||
<foreach collection="query.entrySet()" item="value" index="key" >
|
||||
and ${key} = #{value}
|
||||
and ${key} LIKE #{value}
|
||||
</foreach>
|
||||
</if>
|
||||
<!-- udapte-end-author:sunjianlei date:20220110 for: 【JTC-597】自定义树查询条件查不出数据 -->
|
||||
</select>
|
||||
|
||||
|
||||
@ -179,5 +184,18 @@
|
||||
</select>
|
||||
|
||||
|
||||
<!-- 查询字典表的数据 支持设置过滤条件、设置存储值作为in查询条件 -->
|
||||
<select id="queryTableDictByKeysAndFilterSql" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel">
|
||||
select ${text} as "text", ${code} as "value" from ${table} where ${code} IN (
|
||||
<foreach item="key" collection="codeValues" separator=",">
|
||||
#{key}
|
||||
</foreach>
|
||||
)
|
||||
<if test="filterSql != null and filterSql != ''">
|
||||
and ${filterSql}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
@ -14,7 +14,9 @@
|
||||
join sys_depart c on b.dep_id = c.id
|
||||
where a.del_flag = 0 and c.org_code like '${orgCode}%'
|
||||
<if test="realname!=null and realname!=''">
|
||||
and a.realname like '%${realname}%'
|
||||
<!-- update by sunjianlei 20220119【#3348】SQL injection exists in /sys/user/queryUserByDepId; -->
|
||||
<bind name="bindRealname" value="'%'+realname+'%'"/>
|
||||
and a.realname like #{bindRealname}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
@ -23,12 +25,14 @@
|
||||
select a.*, c.depart_name as org_code_txt from sys_user a
|
||||
join sys_user_depart b on b.user_id = a.id
|
||||
join sys_depart c on b.dep_id = c.id
|
||||
where a.del_flag = 0 and c.org_code like '${orgCode}%'
|
||||
where a.del_flag = 0 and a.status = 1 and c.org_code like '${orgCode}%'
|
||||
<if test="username!=null and username!=''">
|
||||
and a.username like '%${username}%'
|
||||
<bind name="bindUsername" value="'%'+username+'%'"/>
|
||||
and a.username like #{bindUsername}
|
||||
</if>
|
||||
<if test="realname!=null and realname!=''">
|
||||
and a.realname like '%${realname}%'
|
||||
<bind name="bindRealname" value="'%'+realname+'%'"/>
|
||||
and a.realname like #{bindRealname}
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
@ -1,15 +1,12 @@
|
||||
package org.jeecg.modules.system.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @Description: 用户通告阅读标记表
|
||||
|
||||
@ -2,6 +2,7 @@ package org.jeecg.modules.system.rule;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.handler.IFillRuleHandler;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.YouBianCodeUtil;
|
||||
@ -16,12 +17,14 @@ import java.util.List;
|
||||
* @Date 2019/12/9 11:32
|
||||
* @Description: 分类字典编码生成规则
|
||||
*/
|
||||
@Slf4j
|
||||
public class CategoryCodeRule implements IFillRuleHandler {
|
||||
|
||||
public static final String ROOT_PID_VALUE = "0";
|
||||
|
||||
@Override
|
||||
public Object execute(JSONObject params, JSONObject formData) {
|
||||
log.info("系统自定义编码规则[category_code_rule],params:{} ,formData: {}", params, formData);
|
||||
|
||||
String categoryPid = ROOT_PID_VALUE;
|
||||
String categoryCode = null;
|
||||
|
||||
@ -67,7 +67,7 @@ public interface ISysDepartService extends IService<SysDepart>{
|
||||
* @param keyWord
|
||||
* @return
|
||||
*/
|
||||
List<SysDepartTreeModel> searhBy(String keyWord,String myDeptSearch,String departIds);
|
||||
List<SysDepartTreeModel> searchByKeyWord(String keyWord,String myDeptSearch,String departIds);
|
||||
|
||||
/**
|
||||
* 根据部门id删除并删除其可能存在的子级部门
|
||||
|
||||
@ -14,7 +14,7 @@ public interface ISysTenantService extends IService<SysTenant> {
|
||||
* @param idList
|
||||
* @return
|
||||
*/
|
||||
List<SysTenant> queryEffectiveTenant(Collection<String> idList);
|
||||
List<SysTenant> queryEffectiveTenant(Collection<Integer> idList);
|
||||
|
||||
/**
|
||||
* 返回某个租户被多少个用户引用了
|
||||
|
||||
@ -21,7 +21,7 @@ public interface IThirdAppService {
|
||||
*
|
||||
* @return 成功返回true
|
||||
*/
|
||||
boolean syncLocalDepartmentToThirdApp(String ids);
|
||||
SyncInfoVo syncLocalDepartmentToThirdApp(String ids);
|
||||
|
||||
/**
|
||||
* 将第三方App部门同步到本地<br>
|
||||
|
||||
@ -146,7 +146,9 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
//通过自定义URL匹配规则 获取菜单(实现通过菜单配置数据权限规则,实际上针对获取数据接口进行数据规则控制)
|
||||
String userMatchUrl = UrlMatchEnum.getMatchResultByUrl(requestPath);
|
||||
LambdaQueryWrapper<SysPermission> queryQserMatch = new LambdaQueryWrapper<SysPermission>();
|
||||
queryQserMatch.eq(SysPermission::getMenuType, 1);
|
||||
// update-begin-author:taoyan date:20211027 for: online菜单如果配置成一级菜单 权限查询不到 取消menuType = 1
|
||||
//queryQserMatch.eq(SysPermission::getMenuType, 1);
|
||||
// update-end-author:taoyan date:20211027 for: online菜单如果配置成一级菜单 权限查询不到 取消menuType = 1
|
||||
queryQserMatch.eq(SysPermission::getDelFlag, 0);
|
||||
queryQserMatch.eq(SysPermission::getUrl, userMatchUrl);
|
||||
if(oConvertUtils.isNotEmpty(userMatchUrl)){
|
||||
|
||||
@ -69,7 +69,7 @@ public class SysDepartPermissionServiceImpl extends ServiceImpl<SysDepartPermiss
|
||||
@Override
|
||||
public List<SysPermissionDataRule> getPermRuleListByDeptIdAndPermId(String departId, String permissionId) {
|
||||
SysDepartPermission departPermission = this.getOne(new QueryWrapper<SysDepartPermission>().lambda().eq(SysDepartPermission::getDepartId, departId).eq(SysDepartPermission::getPermissionId, permissionId));
|
||||
if(departPermission != null){
|
||||
if(departPermission != null && oConvertUtils.isNotEmpty(departPermission.getDataRuleIds())){
|
||||
LambdaQueryWrapper<SysPermissionDataRule> query = new LambdaQueryWrapper<SysPermissionDataRule>();
|
||||
query.in(SysPermissionDataRule::getId, Arrays.asList(departPermission.getDataRuleIds().split(",")));
|
||||
query.orderByDesc(SysPermissionDataRule::getCreateTime);
|
||||
|
||||
@ -300,7 +300,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public List<SysDepartTreeModel> searhBy(String keyWord,String myDeptSearch,String departIds) {
|
||||
public List<SysDepartTreeModel> searchByKeyWord(String keyWord,String myDeptSearch,String departIds) {
|
||||
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
|
||||
List<SysDepartTreeModel> newList = new ArrayList<>();
|
||||
//myDeptSearch不为空时为我的部门搜索,只搜索所负责部门
|
||||
@ -311,9 +311,15 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
//根据部门id获取所负责部门
|
||||
String[] codeArr = this.getMyDeptParentOrgCode(departIds);
|
||||
for(int i=0;i<codeArr.length;i++){
|
||||
query.or().likeRight(SysDepart::getOrgCode,codeArr[i]);
|
||||
//update-begin-author:taoyan date:20220104 for:/issues/3311 当用户属于两个部门的时候,且这两个部门没有上下级关系,我的部门-部门名称查询条件模糊搜索失效!
|
||||
if (codeArr != null && codeArr.length > 0) {
|
||||
query.nested(i -> {
|
||||
for (String s : codeArr) {
|
||||
i.or().likeRight(SysDepart::getOrgCode, s);
|
||||
}
|
||||
});
|
||||
}
|
||||
//update-end-author:taoyan date:20220104 for:/issues/3311 当用户属于两个部门的时候,且这两个部门没有上下级关系,我的部门-部门名称查询条件模糊搜索失效!
|
||||
query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
|
||||
}
|
||||
query.like(SysDepart::getDepartName, keyWord);
|
||||
@ -499,7 +505,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
};
|
||||
LambdaQueryWrapper<SysDepart> lqw=new LambdaQueryWrapper();
|
||||
lqw.eq(true,SysDepart::getDelFlag,CommonConstant.DEL_FLAG_0);
|
||||
lqw.eq(true,SysDepart::getDelFlag,CommonConstant.DEL_FLAG_0.toString());
|
||||
lqw.func(square);
|
||||
lqw.orderByDesc(SysDepart::getDepartOrder);
|
||||
List<SysDepart> list = list(lqw);
|
||||
|
||||
@ -163,7 +163,15 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
|
||||
@Override
|
||||
public List<DictModel> queryTableDictTextByKeys(String table, String text, String code, List<String> keys) {
|
||||
return sysDictMapper.queryTableDictTextByKeys(table, text, code, keys);
|
||||
//update-begin-author:taoyan date:20220113 for: @dict注解支持 dicttable 设置where条件
|
||||
String filterSql = null;
|
||||
if(table.toLowerCase().indexOf("where")>0){
|
||||
String[] arr = table.split(" (?i)where ");
|
||||
table = arr[0];
|
||||
filterSql = arr[1];
|
||||
}
|
||||
return sysDictMapper.queryTableDictByKeysAndFilterSql(table, text, code, filterSql, keys);
|
||||
//update-end-author:taoyan date:20220113 for: @dict注解支持 dicttable 设置where条件
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -225,6 +233,11 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
insert = sysDictMapper.insert(sysDict);
|
||||
if (sysDictItemList != null) {
|
||||
for (SysDictItem entity : sysDictItemList) {
|
||||
//update-begin---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
|
||||
if(oConvertUtils.isEmpty(entity.getItemValue())){
|
||||
return -1;
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
|
||||
entity.setDictId(sysDict.getId());
|
||||
entity.setStatus(1);
|
||||
sysDictItemMapper.insert(entity);
|
||||
@ -255,7 +268,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize) {
|
||||
Page<DictModel> page = new Page<DictModel>(1, pageSize);
|
||||
page.setSearchCount(false);
|
||||
String filterSql = getFilterSql(text, code, condition, keyword);
|
||||
String filterSql = getFilterSql(table, text, code, condition, keyword);
|
||||
IPage<DictModel> pageList = baseMapper.queryTableDictWithFilter(page, table, text, code, filterSql);
|
||||
return pageList.getRecords();
|
||||
}
|
||||
@ -268,12 +281,19 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
* @param keyword
|
||||
* @return
|
||||
*/
|
||||
private String getFilterSql(String text, String code, String condition, String keyword){
|
||||
private String getFilterSql(String table, String text, String code, String condition, String keyword){
|
||||
String keywordSql = null, filterSql = "", sql_where = " where ";
|
||||
// update-begin-author:sunjianlei date:20220112 for: 【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错
|
||||
if (table.toLowerCase().contains(" where ")) {
|
||||
sql_where = " and ";
|
||||
}
|
||||
// update-end-author:sunjianlei date:20220112 for: 【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错
|
||||
if(oConvertUtils.isNotEmpty(keyword)){
|
||||
// 判断是否是多选
|
||||
if (keyword.contains(",")) {
|
||||
String inKeywords = "\"" + keyword.replaceAll(",", "\",\"") + "\"";
|
||||
//update-begin--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致 ----
|
||||
String inKeywords = "'" + String.join("','", keyword.split(",")) + "'";
|
||||
//update-end--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致----
|
||||
keywordSql = "(" + text + " in (" + inKeywords + ") or " + code + " in (" + inKeywords + "))";
|
||||
} else {
|
||||
keywordSql = "("+text + " like '%"+keyword+"%' or "+ code + " like '%"+keyword+"%')";
|
||||
@ -290,14 +310,20 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
}
|
||||
@Override
|
||||
public List<DictModel> queryAllTableDictItems(String table, String text, String code, String condition, String keyword) {
|
||||
String filterSql = getFilterSql(text, code, condition, keyword);
|
||||
String filterSql = getFilterSql(table, text, code, condition, keyword);
|
||||
List<DictModel> ls = baseMapper.queryAllTableDictItems(table, text, code, filterSql);
|
||||
return ls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TreeSelectModel> queryTreeList(Map<String, String> query,String table, String text, String code, String pidField,String pid,String hasChildField) {
|
||||
return baseMapper.queryTreeList(query,table, text, code, pidField, pid,hasChildField);
|
||||
List<TreeSelectModel> result = baseMapper.queryTreeList(query, table, text, code, pidField, pid, hasChildField);
|
||||
// udapte-begin-author:sunjianlei date:20220110 for: 【JTC-597】如果 query 有值,就不允许展开子节点
|
||||
if (query != null) {
|
||||
result.forEach(r -> r.setLeaf(true));
|
||||
}
|
||||
return result;
|
||||
// udapte-end-author:sunjianlei date:20220110 for: 【JTC-597】如果 query 有值,就不允许展开子节点
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -24,10 +24,10 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
ISysUserService userService;
|
||||
|
||||
@Override
|
||||
public List<SysTenant> queryEffectiveTenant(Collection<String> idList) {
|
||||
public List<SysTenant> queryEffectiveTenant(Collection<Integer> idList) {
|
||||
LambdaQueryWrapper<SysTenant> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(SysTenant::getId, idList);
|
||||
queryWrapper.eq(SysTenant::getStatus, CommonConstant.STATUS_1);
|
||||
queryWrapper.eq(SysTenant::getStatus, Integer.valueOf(CommonConstant.STATUS_1));
|
||||
//此处查询忽略时间条件
|
||||
return super.list(queryWrapper);
|
||||
}
|
||||
@ -50,7 +50,7 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
if (userCount > 0) {
|
||||
throw new JeecgBootException("该租户已被引用,无法删除!");
|
||||
}
|
||||
return super.removeById(id);
|
||||
return super.removeById(Integer.parseInt(id));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
import org.jeecg.common.util.PasswordUtil;
|
||||
@ -30,6 +31,7 @@ import java.util.List;
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMapper, SysThirdAccount> implements ISysThirdAccountService {
|
||||
|
||||
@Autowired
|
||||
@ -116,6 +118,7 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
|
||||
@Override
|
||||
public SysThirdAccount getOneBySysUserId(String sysUserId, String thirdType) {
|
||||
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||
log.info("getSysUserId: {} ,getThirdType: {}",sysUserId,thirdType);
|
||||
queryWrapper.eq(SysThirdAccount::getSysUserId, sysUserId);
|
||||
queryWrapper.eq(SysThirdAccount::getThirdType, thirdType);
|
||||
return super.getOne(queryWrapper);
|
||||
|
||||
@ -1,15 +1,10 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.entity.SysDepart;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
@ -22,8 +17,11 @@ import org.jeecg.modules.system.service.ISysUserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <P>
|
||||
@ -128,6 +126,9 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
|
||||
if(oConvertUtils.isEmpty(departId)){
|
||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
|
||||
//update-begin---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
|
||||
query.eq(SysUser::getStatus,Integer.parseInt(CommonConstant.STATUS_1));
|
||||
//update-end---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
|
||||
if(oConvertUtils.isNotEmpty(username)){
|
||||
query.like(SysUser::getUsername, username);
|
||||
}
|
||||
|
||||
@ -399,6 +399,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
|
||||
public boolean revertLogicDeleted(List<String> userIds, SysUser updateEntity) {
|
||||
String ids = String.format("'%s'", String.join("','", userIds));
|
||||
return userMapper.revertLogicDeleted(ids, updateEntity) > 0;
|
||||
|
||||
@ -85,18 +85,31 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
return null;
|
||||
}
|
||||
|
||||
// update:2022-1-21,updateBy:sunjianlei; for 【JTC-704】【钉钉】部门同步成功,实际没成,后台提示ip白名单
|
||||
@Override
|
||||
public boolean syncLocalDepartmentToThirdApp(String ids) {
|
||||
public SyncInfoVo syncLocalDepartmentToThirdApp(String ids) {
|
||||
SyncInfoVo syncInfo = new SyncInfoVo();
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
return false;
|
||||
syncInfo.addFailInfo("accessToken获取失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
// 获取【钉钉】所有的部门
|
||||
List<Department> departments = JdtDepartmentAPI.listAll(accessToken);
|
||||
List<Response<Department>> departments = JdtDepartmentAPI.listAllResponse(accessToken);
|
||||
// 删除钉钉有但本地没有的部门(以本地部门数据为主)(钉钉不能创建同名部门,只能先删除)
|
||||
List<SysDepart> sysDepartList = sysDepartService.list();
|
||||
for1:
|
||||
for (Department department : departments) {
|
||||
for (Response<Department> departmentRes : departments) {
|
||||
// 判断部门是否查询成功
|
||||
if (!departmentRes.isSuccess()) {
|
||||
syncInfo.addFailInfo(departmentRes.getErrmsg());
|
||||
// 88 是 ip 不在白名单的错误码,如果遇到此错误码,后面的操作都可以不用进行了,因为肯定都是失败的
|
||||
if (new Integer(88).equals(departmentRes.getErrcode())) {
|
||||
return syncInfo;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Department department = departmentRes.getResult();
|
||||
for (SysDepart depart : sysDepartList) {
|
||||
// id相同,代表已存在,不删除
|
||||
String sourceIdentifier = department.getSource_identifier();
|
||||
@ -124,24 +137,34 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
Department parent = new Department();
|
||||
parent.setDept_id(1);
|
||||
// 递归同步部门
|
||||
departments = JdtDepartmentAPI.listAll(accessToken);
|
||||
this.syncDepartmentRecursion(sysDepartsTree, departments, parent, accessToken);
|
||||
return true;
|
||||
departments = JdtDepartmentAPI.listAllResponse(accessToken);
|
||||
this.syncDepartmentRecursion(sysDepartsTree, departments, parent, accessToken, syncInfo);
|
||||
return syncInfo;
|
||||
}
|
||||
|
||||
// 递归同步部门到本地
|
||||
public void syncDepartmentRecursion(List<SysDepartTreeModel> sysDepartsTree, List<Department> departments, Department parent, String accessToken) {
|
||||
public void syncDepartmentRecursion(List<SysDepartTreeModel> sysDepartsTree, List<Response<Department>> departments, Department parent, String accessToken, SyncInfoVo syncInfo) {
|
||||
if (sysDepartsTree != null && sysDepartsTree.size() != 0) {
|
||||
for1:
|
||||
for (SysDepartTreeModel depart : sysDepartsTree) {
|
||||
for (Department department : departments) {
|
||||
for (Response<Department> departmentRes : departments) {
|
||||
// 判断部门是否查询成功
|
||||
if (!departmentRes.isSuccess()) {
|
||||
syncInfo.addFailInfo(departmentRes.getErrmsg());
|
||||
continue;
|
||||
}
|
||||
Department department = departmentRes.getResult();
|
||||
// id相同,代表已存在,执行修改操作
|
||||
String sourceIdentifier = department.getSource_identifier();
|
||||
if (sourceIdentifier != null && sourceIdentifier.equals(depart.getId())) {
|
||||
this.sysDepartToDtDepartment(depart, department, parent.getDept_id());
|
||||
JdtDepartmentAPI.update(department, accessToken);
|
||||
// 紧接着同步子级
|
||||
this.syncDepartmentRecursion(depart.getChildren(), departments, department, accessToken);
|
||||
Response<JSONObject> response = JdtDepartmentAPI.update(department, accessToken);
|
||||
if (response.isSuccess()) {
|
||||
// 紧接着同步子级
|
||||
this.syncDepartmentRecursion(depart.getChildren(), departments, department, accessToken, syncInfo);
|
||||
}
|
||||
// 收集错误信息
|
||||
this.syncDepartCollectErrInfo(response, depart, syncInfo);
|
||||
// 跳出外部循环
|
||||
continue for1;
|
||||
}
|
||||
@ -154,10 +177,10 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
Department newParent = new Department();
|
||||
newParent.setDept_id(response.getResult());
|
||||
// 紧接着同步子级
|
||||
this.syncDepartmentRecursion(depart.getChildren(), departments, newParent, accessToken);
|
||||
this.syncDepartmentRecursion(depart.getChildren(), departments, newParent, accessToken, syncInfo);
|
||||
}
|
||||
// 收集错误信息
|
||||
// this.syncUserCollectErrInfo(errCode, sysUser, errInfo);
|
||||
this.syncDepartCollectErrInfo(response, depart, syncInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -209,6 +232,11 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
SysDepart newSysDepart = this.dtDepartmentToSysDepart(departmentTree, null);
|
||||
if (sysParentId != null) {
|
||||
newSysDepart.setParentId(sysParentId);
|
||||
// 2 = 组织机构
|
||||
newSysDepart.setOrgCategory("2");
|
||||
} else {
|
||||
// 1 = 公司
|
||||
newSysDepart.setOrgCategory("1");
|
||||
}
|
||||
try {
|
||||
sysDepartService.saveDepartData(newSysDepart, username);
|
||||
@ -246,6 +274,20 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【同步部门】收集同步过程中的错误信息
|
||||
*/
|
||||
private boolean syncDepartCollectErrInfo(Response<?> response, SysDepartTreeModel depart, SyncInfoVo syncInfo) {
|
||||
if (!response.isSuccess()) {
|
||||
String str = String.format("部门 %s(%s) 同步失败!错误码:%s——%s", depart.getDepartName(), depart.getOrgCode(), response.getErrcode(), response.getErrmsg());
|
||||
syncInfo.addFailInfo(str);
|
||||
return false;
|
||||
} else {
|
||||
String str = String.format("部门户 %s(%s) 同步成功!", depart.getDepartName(), depart.getOrgCode());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyncInfoVo syncLocalUserToThirdApp(String ids) {
|
||||
@ -279,7 +321,7 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
/*
|
||||
* 判断是否同步过的逻辑:
|
||||
* 1. 查询 sys_third_account(第三方账号表)是否有数据,如果有代表已同步
|
||||
* 2. 本地表里没有,就先用手机号判断,不通过再用username判断。
|
||||
* 2. 本地表里没有,就先用手机号判断,不通过再用username(用户账号)判断。
|
||||
*/
|
||||
SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneBySysUserId(sysUser.getId(), THIRD_TYPE);
|
||||
if (sysThirdAccount != null && oConvertUtils.isNotEmpty(sysThirdAccount.getThirdUserId())) {
|
||||
@ -528,6 +570,12 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
// update-begin--Author:liusq Date:20210713 for:钉钉同步到本地的人员没有状态,导致同步之后无法登录 #I3ZC2L
|
||||
sysUser.setStatus(1);
|
||||
// update-end--Author:liusq Date:20210713 for:钉钉同步到本地的人员没有状态,导致同步之后无法登录 #I3ZC2L
|
||||
// 设置工号,如果工号为空,则使用username
|
||||
if (oConvertUtils.isEmpty(dtUser.getJob_number())) {
|
||||
sysUser.setWorkNo(dtUser.getUserid());
|
||||
} else {
|
||||
sysUser.setWorkNo(dtUser.getJob_number());
|
||||
}
|
||||
return this.dtUserToSysUser(dtUser, sysUser);
|
||||
}
|
||||
|
||||
|
||||
@ -96,15 +96,18 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean syncLocalDepartmentToThirdApp(String ids) {
|
||||
public SyncInfoVo syncLocalDepartmentToThirdApp(String ids) {
|
||||
SyncInfoVo syncInfo = new SyncInfoVo();
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
return false;
|
||||
syncInfo.addFailInfo("accessToken获取失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
// 获取企业微信所有的部门
|
||||
List<Department> departments = JwDepartmentAPI.getAllDepartment(accessToken);
|
||||
if (departments == null) {
|
||||
return false;
|
||||
syncInfo.addFailInfo("获取企业微信所有部门失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
// 删除企业微信有但本地没有的部门(以本地部门数据为主)(以为企业微信不能创建同名部门,所以只能先删除)
|
||||
List<JwDepartmentTreeVo> departmentTreeList = JwDepartmentTreeVo.listToTree(departments);
|
||||
@ -117,7 +120,7 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
// 递归同步部门
|
||||
departments = JwDepartmentAPI.getAllDepartment(accessToken);
|
||||
this.syncDepartmentRecursion(sysDepartsTree, departments, parent, accessToken);
|
||||
return true;
|
||||
return syncInfo;
|
||||
}
|
||||
|
||||
// 递归删除部门以及子部门,由于企业微信不允许删除带有成员和子部门的部门,所以需要递归删除下子部门,然后把部门成员移动端根部门下
|
||||
@ -250,6 +253,11 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
SysDepart newSysDepart = this.qwDepartmentToSysDepart(departmentTree, null);
|
||||
if (sysParentId != null) {
|
||||
newSysDepart.setParentId(sysParentId);
|
||||
// 2 = 组织机构
|
||||
newSysDepart.setOrgCategory("2");
|
||||
} else {
|
||||
// 1 = 公司
|
||||
newSysDepart.setOrgCategory("1");
|
||||
}
|
||||
try {
|
||||
sysDepartService.saveDepartData(newSysDepart, username);
|
||||
@ -604,6 +612,10 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
BeanUtils.copyProperties(oldSysUser, sysUser);
|
||||
sysUser.setRealname(qwUser.getName());
|
||||
sysUser.setPost(qwUser.getPosition());
|
||||
// 设置工号,由于企业微信没有工号的概念,所以只能用 userId 代替
|
||||
if (oConvertUtils.isEmpty(sysUser.getWorkNo())) {
|
||||
sysUser.setWorkNo(qwUser.getUserid());
|
||||
}
|
||||
try {
|
||||
sysUser.setSex(Integer.parseInt(qwUser.getGender()));
|
||||
} catch (NumberFormatException ignored) {
|
||||
|
||||
@ -197,7 +197,7 @@ jeecg :
|
||||
# ElasticSearch 设置
|
||||
elasticsearch:
|
||||
cluster-name: jeecg-ES
|
||||
cluster-nodes: 81.70.47.128:9200
|
||||
cluster-nodes: 127.0.0.1:9200
|
||||
check-enabled: true
|
||||
# 表单设计器配置
|
||||
desform:
|
||||
|
||||
@ -9,6 +9,6 @@ ${AnsiColor.BRIGHT_BLUE}
|
||||
|
||||
|
||||
${AnsiColor.BRIGHT_GREEN}
|
||||
Jeecg Boot Version: 3.0
|
||||
Jeecg Boot Version: 3.1.0
|
||||
Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
|
||||
${AnsiColor.BLACK}
|
||||
|
||||
@ -115,9 +115,9 @@
|
||||
<#return "{type:'${po.classType}',value:'${po.fieldName}',text:'${po.filedComment}'}">
|
||||
<#else>
|
||||
<#if po.classType=="sel_search" || po.classType=="list_multi">
|
||||
<#return "{type:'${po.classType}',value:'${po.fieldName}',text:'${po.filedComment}',dictTable:'${superQuery_dictTable}', dictText:'${superQuery_dictText}', dictCode:'${po.dictField}'}">
|
||||
<#return "{type:'${po.classType}',value:'${po.fieldName}',text:'${po.filedComment}',dictTable:\"${superQuery_dictTable}\", dictText:'${superQuery_dictText}', dictCode:'${po.dictField}'}">
|
||||
<#elseif po.dictTable?? && po.dictTable!="" && po.classType!="sel_tree" && po.classType!="cat_tree" && po.classType!="link_down">
|
||||
<#return "{type:'${po.fieldDbType}',value:'${po.fieldName}',text:'${po.filedComment}',dictCode:'${po.dictTable},${po.dictText},${po.dictField}'}">
|
||||
<#return "{type:'${po.fieldDbType}',value:'${po.fieldName}',text:'${po.filedComment}',dictCode:\"${po.dictTable},${po.dictText},${po.dictField}\"}">
|
||||
<#elseif po.dictField?? && po.classType!="sel_tree" && po.classType!="cat_tree" && po.classType!="link_down">
|
||||
<#return "{type:'${po.fieldDbType}',value:'${po.fieldName}',text:'${po.filedComment}',dictCode:'${po.dictField}'}">
|
||||
<#elseif po.fieldDbType=="Text">
|
||||
|
||||
@ -65,10 +65,10 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "${tableVo.ftlDescription}-分页列表查询")
|
||||
//@AutoLog(value = "${tableVo.ftlDescription}-分页列表查询")
|
||||
@ApiOperation(value="${tableVo.ftlDescription}-分页列表查询", notes="${tableVo.ftlDescription}-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(${entityName} ${entityName?uncap_first},
|
||||
public Result<IPage<${entityName}>> queryPageList(${entityName} ${entityName?uncap_first},
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
@ -87,7 +87,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
|
||||
@AutoLog(value = "${tableVo.ftlDescription}-添加")
|
||||
@ApiOperation(value="${tableVo.ftlDescription}-添加", notes="${tableVo.ftlDescription}-添加")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody ${entityName} ${entityName?uncap_first}) {
|
||||
public Result<String> add(@RequestBody ${entityName} ${entityName?uncap_first}) {
|
||||
<#if bpm_flag>
|
||||
${entityName?uncap_first}.setBpmStatus("1");
|
||||
</#if>
|
||||
@ -103,8 +103,8 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
|
||||
*/
|
||||
@AutoLog(value = "${tableVo.ftlDescription}-编辑")
|
||||
@ApiOperation(value="${tableVo.ftlDescription}-编辑", notes="${tableVo.ftlDescription}-编辑")
|
||||
@PutMapping(value = "/edit")
|
||||
public Result<?> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
|
||||
${entityName?uncap_first}Service.updateById(${entityName?uncap_first});
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
@ -118,7 +118,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
|
||||
@AutoLog(value = "${tableVo.ftlDescription}-通过id删除")
|
||||
@ApiOperation(value="${tableVo.ftlDescription}-通过id删除", notes="${tableVo.ftlDescription}-通过id删除")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
|
||||
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||
${entityName?uncap_first}Service.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
@ -132,7 +132,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
|
||||
@AutoLog(value = "${tableVo.ftlDescription}-批量删除")
|
||||
@ApiOperation(value="${tableVo.ftlDescription}-批量删除", notes="${tableVo.ftlDescription}-批量删除")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.${entityName?uncap_first}Service.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
@ -143,13 +143,13 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "${tableVo.ftlDescription}-通过id查询")
|
||||
//@AutoLog(value = "${tableVo.ftlDescription}-通过id查询")
|
||||
@ApiOperation(value="${tableVo.ftlDescription}-通过id查询", notes="${tableVo.ftlDescription}-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
public Result<${entityName}> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id);
|
||||
if(${entityName?uncap_first}==null) {
|
||||
return Result.error("未找到对应数据");
|
||||
return Result.error("未找到对应数据",null);
|
||||
}
|
||||
return Result.OK(${entityName?uncap_first});
|
||||
}
|
||||
|
||||
@ -108,8 +108,8 @@
|
||||
</#if>
|
||||
</#list>
|
||||
<#if bpm_flag>
|
||||
<a-col v-if="showFlowSubmitButton" :span="24" style="text-align: center">
|
||||
<a-button @click="submitForm">提 交</a-button>
|
||||
<a-col v-if="showFlowSubmitButton" :span="24" style="width: 100%;text-align: center;">
|
||||
<a-button icon="check" style="width: 126px" type="primary" @click="submitForm">提 交</a-button>
|
||||
</a-col>
|
||||
</#if>
|
||||
</a-row>
|
||||
|
||||
@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<div>
|
||||
<#assign list_need_category=false>
|
||||
<#assign list_need_pca=false>
|
||||
<#assign bpm_flag=false>
|
||||
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#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>
|
||||
<#-- 结束循环 -->
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<a-dropdown v-if="checkedKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button>批量操作
|
||||
<Icon icon="mdi:chevron-down"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{text}">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<template #fileSlot="{text}">
|
||||
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup>
|
||||
import {ref, computed, unref} from 'vue';
|
||||
import {BasicTable, useTable, TableAction} from '/@/components/Table';
|
||||
import {useModal} from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage'
|
||||
import ${entityName}Modal from './components/${entityName}Modal.vue'
|
||||
import {columns, searchFormSchema} from './${entityName?uncap_first}.data';
|
||||
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName?uncap_first}.api';
|
||||
<#if list_need_category>
|
||||
import { loadCategoryData } from '/@/api/common/api'
|
||||
import { getAuthCache, setAuthCache } from '/@/utils/auth';
|
||||
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
|
||||
</#if>
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
//注册model
|
||||
const [registerModal, {openModal}] = useModal();
|
||||
//注册table数据
|
||||
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
|
||||
tableProps:{
|
||||
title: '${tableVo.ftlDescription}',
|
||||
api: list,
|
||||
columns,
|
||||
canResize:false,
|
||||
formConfig: {
|
||||
labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter:true,
|
||||
showAdvancedButton:true,
|
||||
fieldMapToTime: [
|
||||
<#list columns as po>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#if po.queryMode!='single'>
|
||||
<#if po.classType=='date'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD'],
|
||||
<#elseif po.classType=='datetime'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD HH:mm:ss'],
|
||||
</#if>
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name:"${tableVo.ftlDescription}",
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl
|
||||
},
|
||||
})
|
||||
|
||||
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({id: record.id}, reload);
|
||||
}
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
await batchDelete({ids: checkedKeys.value}, reload);
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record){
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
}
|
||||
]
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record){
|
||||
return [
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
}, {
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
<#if list_need_category>
|
||||
/**
|
||||
* 初始化字典配置
|
||||
*/
|
||||
function initDictConfig(){
|
||||
<#list columns as po>
|
||||
<#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>
|
||||
<#if po.classType=='cat_tree' && list_need_category==true>
|
||||
loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => {
|
||||
if (res) {
|
||||
let allDictDate = getAuthCache(DB_DICT_DATA_KEY);
|
||||
if(!allDictDate['${po.dictField?default("")}']){
|
||||
Object.assign(allDictDate,{'${po.dictField?default("")}':res})
|
||||
}
|
||||
setAuthCache(DB_DICT_DATA_KEY,allDictDate)
|
||||
}
|
||||
})
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
initDictConfig();
|
||||
</#if>
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,61 @@
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
import {Modal} from 'ant-design-vue';
|
||||
|
||||
enum Api {
|
||||
list = '/${entityPackage}/${entityName?uncap_first}/list',
|
||||
save='/${entityPackage}/${entityName?uncap_first}/add',
|
||||
edit='/${entityPackage}/${entityName?uncap_first}/edit',
|
||||
deleteOne = '/${entityPackage}/${entityName?uncap_first}/delete',
|
||||
deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
|
||||
importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
|
||||
exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
|
||||
}
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) =>
|
||||
defHttp.get({url: Api.list, params});
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params,handleSuccess) => {
|
||||
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({url: url, params});
|
||||
}
|
||||
@ -0,0 +1,354 @@
|
||||
import {BasicColumn} from '/@/components/Table';
|
||||
import {FormSchema} from '/@/components/Table';
|
||||
import { rules} from '/@/utils/helper/validator';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
<#list columns as po>
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||
{
|
||||
title: '${po.filedComment}',
|
||||
align:"center",
|
||||
<#if po.sort=='Y'>
|
||||
sorter: true,
|
||||
</#if>
|
||||
<#if po.classType=='date'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:({text}) =>{
|
||||
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||
},
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
dataIndex: '${po.fieldName}String'
|
||||
<#elseif po.classType=='umeditor'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'htmlSlot' },
|
||||
<#elseif po.classType=='pca'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||
<#elseif po.classType=='file'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'fileSlot' },
|
||||
<#elseif po.classType=='image'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:render.renderAvatar,
|
||||
<#elseif po.classType=='switch'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#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>
|
||||
<#assign switch_extend_arr1=a>
|
||||
<#else>
|
||||
<#assign switch_extend_arr2=a>
|
||||
</#if>
|
||||
</#list>
|
||||
customRender:({text}) => {
|
||||
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||
},
|
||||
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||
dataIndex: '${po.fieldName}_dictText'
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#if po.dictText?default("")?trim?length == 0>
|
||||
customRender:({text}) => {
|
||||
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||
},
|
||||
<#else>
|
||||
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||
</#if>
|
||||
<#else>
|
||||
dataIndex: '${po.fieldName}'
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#assign query_flag=true>
|
||||
<#assign query_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictField}">
|
||||
</#if>
|
||||
<#if po.queryMode=='single'>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
},
|
||||
<#elseif po.classType=='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
<#elseif po.classType=='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType=='list_multi'>
|
||||
component: 'JMultiSelectTag',//暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"query_field_dictCode?default("")"
|
||||
},
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题
|
||||
},
|
||||
<#elseif po.classType=='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.classType=='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType=='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:"${po.dictField}",
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
},
|
||||
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
<#else>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='date'>
|
||||
component: 'RangePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#else>
|
||||
component: 'Input', //TODO 范围查询
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
<#-- 结束循环 -->
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list columns as po><#rt/>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#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>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#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'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#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}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm"/>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, unref} from 'vue';
|
||||
import {BasicModal, useModalInner} from '/@/components/Modal';
|
||||
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||
import {formSchema} from '../${entityName?uncap_first}.data';
|
||||
import {saveOrUpdate} from '../${entityName?uncap_first}.api';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register','success']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({confirmLoading: false,showCancelBtn:!!data?.showFooter,showOkBtn:!!data?.showFooter});
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
setProps({ disabled: !data?.showFooter })
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
//表单提交事件
|
||||
async function handleSubmit(v) {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({confirmLoading: true});
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({confirmLoading: false});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
@ -119,7 +119,7 @@ public class ${entityName}Controller {
|
||||
*/
|
||||
@AutoLog(value = "${tableVo.ftlDescription}-编辑")
|
||||
@ApiOperation(value="${tableVo.ftlDescription}-编辑", notes="${tableVo.ftlDescription}-编辑")
|
||||
@PutMapping(value = "/edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) {
|
||||
${entityName} ${entityName?uncap_first} = new ${entityName}();
|
||||
BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first});
|
||||
|
||||
@ -28,13 +28,8 @@
|
||||
<#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 :span="${form_span}" >
|
||||
<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'>
|
||||
@ -140,7 +135,7 @@
|
||||
</#list>
|
||||
</a-tabs>
|
||||
<#if bpm_flag>
|
||||
<a-row v-if="showFlowSubmitButton" style="text-align: center;width: 100%;margin-top: 16px;"><a-button @click="handleOk">提 交</a-button></a-row>
|
||||
<a-row v-if="showFlowSubmitButton" style="text-align: center;width: 100%;margin-top: 16px;"><a-button icon="check" style="width: 126px" type="primary" @click="handleOk">提 交</a-button></a-row>
|
||||
</#if>
|
||||
</a-spin>
|
||||
</template>
|
||||
@ -171,20 +166,12 @@
|
||||
return {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
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">
|
||||
},
|
||||
|
||||
@ -25,13 +25,8 @@
|
||||
<#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 :span="${form_span}">
|
||||
<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%"/>
|
||||
<#elseif po.classType =='datetime'>
|
||||
@ -117,20 +112,12 @@
|
||||
},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
labelCol2: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 3 },
|
||||
},
|
||||
wrapperCol2: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 20 },
|
||||
},
|
||||
<#include "/common/validatorRulesTemplate/sub.ftl">
|
||||
confirmLoading: false,
|
||||
}
|
||||
|
||||
@ -158,7 +158,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
|
||||
*/
|
||||
@AutoLog(value = "${tableVo.ftlDescription}-编辑")
|
||||
@ApiOperation(value="${tableVo.ftlDescription}-编辑", notes="${tableVo.ftlDescription}-编辑")
|
||||
@PutMapping(value = "/edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
|
||||
${entityName?uncap_first}Service.update${entityName}(${entityName?uncap_first});
|
||||
return Result.OK("编辑成功!");
|
||||
|
||||
@ -0,0 +1,272 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection" :expandedRowKeys="expandedRowKeys" @expand="handleExpand" @fetch-success="onFetchSuccess">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleCreate" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
|
||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button>批量操作
|
||||
<Icon icon="ant-design:down-outlined"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)"/>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!--字典弹窗-->
|
||||
<${entityName}Modal @register="registerModal" @success="handleSuccess"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup>
|
||||
//ts语法
|
||||
import {ref, computed, unref, toRaw, nextTick} from 'vue';
|
||||
import {BasicTable, useTable, TableAction} from '/src/components/Table';
|
||||
import {useModal} from '/src/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage'
|
||||
import ${entityName}Modal from './components/${entityName}Modal.vue';
|
||||
import {columns} from './${entityName}.data';
|
||||
import {list, delete${entityName}, batchDelete${entityName}, getExportUrl,getImportUrl, getChildList,getChildListBatch} from './${entityName}.api';
|
||||
|
||||
const expandedRowKeys = ref([]);
|
||||
//字典model
|
||||
const [registerModal, {openModal}] = useModal();
|
||||
//注册table数据
|
||||
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
|
||||
tableProps:{
|
||||
title: '${tableVo.ftlDescription}',
|
||||
columns,
|
||||
canResize:false,
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name:"${tableVo.ftlDescription}",
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl,
|
||||
success:importSuccess
|
||||
},
|
||||
})
|
||||
|
||||
const [registerTable, {reload, collapseAll, updateTableDataRecord, findTableDataRecord,getDataSource},{ rowSelection, selectedRowKeys }] = tableContext
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleCreate() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
async function handleEdit(record) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
async function handleDetail(record) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
hideFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await delete${entityName}({id: record.id}, importSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
const ids = selectedRowKeys.value.filter(item => !item.includes('loading'))
|
||||
await batchDelete${entityName}({ids: ids}, importSuccess);
|
||||
}
|
||||
/**
|
||||
* 导入
|
||||
*/
|
||||
function importSuccess() {
|
||||
reload() && (expandedRowKeys.value = []);
|
||||
}
|
||||
/**
|
||||
* 添加下级
|
||||
*/
|
||||
function handleAddSub(record) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
async function handleSuccess({isUpdate, values, expandedArr}) {
|
||||
if (isUpdate) {
|
||||
//编辑回调
|
||||
updateTableDataRecord(values.id, values);
|
||||
} else {
|
||||
if(!values['pid']){
|
||||
//新增根节点
|
||||
reload();
|
||||
}else{
|
||||
//新增子集
|
||||
expandedRowKeys.value = [];
|
||||
for (let key of unref(expandedArr)) {
|
||||
await expandTreeNode(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口请求成功后回调
|
||||
*/
|
||||
function onFetchSuccess(result) {
|
||||
getDataByResult(result.items)&&loadDataByExpandedRows();
|
||||
}
|
||||
/**
|
||||
* 根据已展开的行查询数据(用于保存后刷新时异步加载子级的数据)
|
||||
*/
|
||||
async function loadDataByExpandedRows() {
|
||||
if (unref(expandedRowKeys).length > 0) {
|
||||
const res = await getChildListBatch({ parentIds: unref(expandedRowKeys).join(',')});
|
||||
if (res.success && res.result.records.length>0) {
|
||||
//已展开的数据批量子节点
|
||||
let records = res.result.records
|
||||
const listMap = new Map();
|
||||
for (let item of records) {
|
||||
let pid = item['pid'];
|
||||
if (unref(expandedRowKeys).includes(pid)) {
|
||||
let mapList = listMap.get(pid);
|
||||
if (mapList == null) {
|
||||
mapList = [];
|
||||
}
|
||||
mapList.push(item);
|
||||
listMap.set(pid, mapList);
|
||||
}
|
||||
}
|
||||
let childrenMap = listMap;
|
||||
let fn = (list) => {
|
||||
if(list) {
|
||||
list.forEach(data => {
|
||||
if (unref(expandedRowKeys).includes(data.id)) {
|
||||
data.children = getDataByResult(childrenMap.get(data.id))
|
||||
fn(data.children)
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
fn(getDataSource())
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 处理数据集
|
||||
*/
|
||||
function getDataByResult(result){
|
||||
if(result && result.length>0){
|
||||
return result.map(item=>{
|
||||
//判断是否标记了带有子节点
|
||||
if(item["hasChild"]=='1'){
|
||||
let loadChild = { id: item.id+'_loadChild', name: 'loading...', isLoading: true }
|
||||
item.children = [loadChild]
|
||||
}
|
||||
return item
|
||||
})
|
||||
}
|
||||
}
|
||||
/**
|
||||
*树节点展开合并
|
||||
* */
|
||||
async function handleExpand(expanded, record) {
|
||||
// 判断是否是展开状态,展开状态(expanded)并且存在子集(children)并且未加载过(isLoading)的就去查询子节点数据
|
||||
if (expanded) {
|
||||
expandedRowKeys.value.push(record.id)
|
||||
if (record.children.length > 0 && !!record.children[0].isLoading) {
|
||||
let result = await getChildList({pid: record.id});
|
||||
result=result.records?result.records:result;
|
||||
if (result && result.length > 0) {
|
||||
record.children = getDataByResult(result);
|
||||
} else {
|
||||
record.children = null
|
||||
record.hasChild = '0'
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let keyIndex = expandedRowKeys.value.indexOf(record.id)
|
||||
if (keyIndex >= 0) {
|
||||
expandedRowKeys.value.splice(keyIndex, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*操作表格后处理树节点展开合并
|
||||
* */
|
||||
async function expandTreeNode(key) {
|
||||
let record = findTableDataRecord(key)
|
||||
expandedRowKeys.value.push(key);
|
||||
let result = await getChildList({pid: key});
|
||||
if (result && result.length > 0) {
|
||||
record.children = getDataByResult(result);
|
||||
} else {
|
||||
record.children = null
|
||||
record.hasChild = '0'
|
||||
}
|
||||
updateTableDataRecord(key, record);
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '确定删除吗?',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '添加下级',
|
||||
onClick: handleAddSub.bind(null, {pid: record.id}),
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,82 @@
|
||||
import {defHttp} from "/@/utils/http/axios";
|
||||
import {Modal} from 'ant-design-vue';
|
||||
|
||||
enum Api {
|
||||
list = '/${entityPackage}/${entityName?uncap_first}/rootList',
|
||||
save='/${entityPackage}/${entityName?uncap_first}/add',
|
||||
edit='/${entityPackage}/${entityName?uncap_first}/edit',
|
||||
delete${entityName} = '/sys/${entityName?uncap_first}/delete',
|
||||
deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
|
||||
importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
|
||||
exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
|
||||
loadTreeData = '/${entityPackage}/${entityName?uncap_first}/loadTreeRoot',
|
||||
getChildList = '/${entityPackage}/${entityName?uncap_first}/childList',
|
||||
getChildListBatch = '/${entityPackage}/${entityName?uncap_first}/getChildListBatch',
|
||||
}
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
/**
|
||||
* 导入api
|
||||
* @param params
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) =>
|
||||
defHttp.get({url: Api.list, params});
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
export const delete${entityName} = (params,handleSuccess) => {
|
||||
return defHttp.delete({url: Api.delete${entityName}, params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete${entityName} = (params, handleSuccess) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdateDict = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({url: url, params});
|
||||
}
|
||||
/**
|
||||
* 查询全部树形节点数据
|
||||
* @param params
|
||||
*/
|
||||
export const loadTreeData = (params) =>
|
||||
defHttp.get({url: Api.loadTreeData,params});
|
||||
/**
|
||||
* 查询子节点数据
|
||||
* @param params
|
||||
*/
|
||||
export const getChildList = (params) =>
|
||||
defHttp.get({url: Api.getChildList, params});
|
||||
/**
|
||||
* 批量查询子节点数据
|
||||
* @param params
|
||||
*/
|
||||
export const getChildListBatch = (params) =>
|
||||
defHttp.get({url: Api.getChildListBatch, params},{isTransformResponse:false});
|
||||
@ -0,0 +1,354 @@
|
||||
import {BasicColumn} from '/@/components/Table';
|
||||
import {FormSchema} from '/@/components/Table';
|
||||
import { rules} from '/@/utils/helper/validator';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
<#list columns as po>
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||
{
|
||||
title: '${po.filedComment}',
|
||||
align:"center",
|
||||
<#if po.sort=='Y'>
|
||||
sorter: true,
|
||||
</#if>
|
||||
<#if po.classType=='date'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:({text}) =>{
|
||||
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||
},
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
dataIndex: '${po.fieldName}String'
|
||||
<#elseif po.classType=='umeditor'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'htmlSlot' },
|
||||
<#elseif po.classType=='pca'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||
<#elseif po.classType=='file'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'fileSlot' },
|
||||
<#elseif po.classType=='image'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:render.renderAvatar,
|
||||
<#elseif po.classType=='switch'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#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>
|
||||
<#assign switch_extend_arr1=a>
|
||||
<#else>
|
||||
<#assign switch_extend_arr2=a>
|
||||
</#if>
|
||||
</#list>
|
||||
customRender:({text}) => {
|
||||
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||
},
|
||||
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||
dataIndex: '${po.fieldName}_dictText'
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#if po.dictText?default("")?trim?length == 0>
|
||||
customRender:({text}) => {
|
||||
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||
},
|
||||
<#else>
|
||||
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||
</#if>
|
||||
<#else>
|
||||
dataIndex: '${po.fieldName}'
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#assign query_flag=true>
|
||||
<#assign query_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictField}">
|
||||
</#if>
|
||||
<#if po.queryMode=='single'>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
},
|
||||
<#elseif po.classType=='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
<#elseif po.classType=='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType=='list_multi'>
|
||||
component: 'JMultiSelectTag',//暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"query_field_dictCode?default("")"
|
||||
},
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题
|
||||
},
|
||||
<#elseif po.classType=='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.classType=='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType=='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:"${po.dictField}",
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
},
|
||||
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
<#else>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='date'>
|
||||
component: 'RangePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#else>
|
||||
component: 'Input', //TODO 范围查询
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
<#-- 结束循环 -->
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list columns as po><#rt/>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#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>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#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'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#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}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm"/>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, unref} from 'vue';
|
||||
import {BasicModal, useModalInner} from '/src/components/Modal';
|
||||
import {BasicForm, useForm} from '/src/components/Form';
|
||||
import {formSchema} from '../${entityName?uncap_first}.data';
|
||||
import {loadTreeData, saveOrUpdateDict} from '../${entityName?uncap_first}.api';
|
||||
// 获取emit
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
const expandedRowKeys = ref([]);
|
||||
const treeData = ref([]);
|
||||
//表单配置
|
||||
const [registerForm, {resetFields, setFieldsValue, validate, updateSchema}] = useForm({
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 4 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 18 },
|
||||
},
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
expandedRowKeys.value = [];
|
||||
setModalProps({confirmLoading: false, minHeight: 80});
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (data?.record) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
}
|
||||
//父级节点树信息
|
||||
treeData.value = await loadTreeData({'async': false,'pcode':''});
|
||||
updateSchema({
|
||||
field: 'pid',
|
||||
componentProps: {treeData},
|
||||
});
|
||||
});
|
||||
//设置标题
|
||||
const getTitle = computed(() => (!unref(isUpdate) ? '新增字典' : '编辑字典'));
|
||||
|
||||
/**
|
||||
* 根据pid获取展开的节点
|
||||
* @param pid
|
||||
* @param arr
|
||||
*/
|
||||
function getExpandKeysByPid(pid,arr){
|
||||
if(pid && arr && arr.length>0){
|
||||
for(let i=0;i<arr.length;i++){
|
||||
if(arr[i].key==pid && unref(expandedRowKeys).indexOf(pid)<0){
|
||||
expandedRowKeys.value.push(arr[i].key);
|
||||
getExpandKeysByPid(arr[i]['parentId'],unref(treeData))
|
||||
}else{
|
||||
getExpandKeysByPid(pid,arr[i].children)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({confirmLoading: true});
|
||||
//提交表单
|
||||
await saveOrUpdateDict(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//展开的节点信息
|
||||
await getExpandKeysByPid(values['pid'],unref(treeData))
|
||||
//刷新列表(isUpdate:是否编辑;values:表单信息;expandedArr:展开的节点信息)
|
||||
emit('success', {isUpdate: unref(isUpdate), values:{...values},expandedArr: unref(expandedRowKeys).reverse()});
|
||||
} finally {
|
||||
setModalProps({confirmLoading: false});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -103,7 +103,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
|
||||
*/
|
||||
@AutoLog(value = "${tableVo.ftlDescription}-编辑")
|
||||
@ApiOperation(value="${tableVo.ftlDescription}-编辑", notes="${tableVo.ftlDescription}-编辑")
|
||||
@PutMapping(value = "/edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
|
||||
${entityName?uncap_first}Service.updateById(${entityName?uncap_first});
|
||||
return Result.OK("编辑成功!");
|
||||
@ -194,7 +194,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
|
||||
*/
|
||||
@AutoLog(value = "${sub.ftlDescription}-编辑")
|
||||
@ApiOperation(value="${sub.ftlDescription}-编辑", notes="${sub.ftlDescription}-编辑")
|
||||
@PutMapping(value = "/edit${sub.entityName}")
|
||||
@RequestMapping(value = "/edit${sub.entityName}", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<?> edit${sub.entityName}(@RequestBody ${sub.entityName} ${sub.entityName?uncap_first}) {
|
||||
${sub.entityName?uncap_first}Service.updateById(${sub.entityName?uncap_first});
|
||||
return Result.OK("编辑成功!");
|
||||
|
||||
@ -371,7 +371,7 @@
|
||||
this.$set(this.dictOptions, '${po.fieldName}', res.result)
|
||||
}
|
||||
})
|
||||
<#elseif po.classType=='sel_search' || po.classType=='list_multi' || po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||
<#elseif po.classType=='radio' || po.classType=='checkbox'>
|
||||
<#assign list_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
<#assign list_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
|
||||
@ -15,8 +15,6 @@
|
||||
@change="handleImportExcel">
|
||||
<a-button type="primary" icon="import">导入</a-button>
|
||||
</a-upload>
|
||||
<!-- 高级查询区域 -->
|
||||
<j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
|
||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
@ -192,12 +190,10 @@
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
},
|
||||
superFieldList:[],
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getSuperFieldList();
|
||||
},
|
||||
computed: {
|
||||
importExcelUrl(){
|
||||
@ -209,15 +205,8 @@
|
||||
this.dataSource=[]
|
||||
this.selectedRowKeys=[]
|
||||
this.ipagination.current = 1
|
||||
},
|
||||
getSuperFieldList(){
|
||||
<#include "/common/utils.ftl">
|
||||
let fieldList=[];
|
||||
<#list columns as po>
|
||||
fieldList.push(${superQueryFieldList(po)})
|
||||
</#list>
|
||||
this.superFieldList = fieldList
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<div>
|
||||
<#assign list_need_category=false>
|
||||
<#assign list_need_pca=false>
|
||||
<#assign bpm_flag=false>
|
||||
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#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>
|
||||
<#-- 结束循环 -->
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button>批量操作
|
||||
<Icon icon="mdi:chevron-down"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{text}">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<template #fileSlot="{text}">
|
||||
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!--子表表格tab-->
|
||||
<a-tabs defaultActiveKey="1">
|
||||
<#assign sub_seq=1>
|
||||
<#list subTables as sub>
|
||||
<a-tab-pane tab="${sub.ftlDescription}" key="${sub_seq}" <#if sub_seq gt 1>forceRender</#if>>
|
||||
<${sub.entityName}List/>
|
||||
</a-tab-pane>
|
||||
<#assign sub_seq=sub_seq+1>
|
||||
</#list>
|
||||
</a-tabs>
|
||||
<!-- 表单区域 -->
|
||||
<${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup>
|
||||
import {ref, computed, unref,provide} from 'vue';
|
||||
import {BasicTable, useTable, TableAction} from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage'
|
||||
import {useModal} from '/@/components/Modal';
|
||||
import ${entityName}Modal from './components/${entityName}Modal.vue'
|
||||
<#list subTables as sub>
|
||||
import ${sub.entityName}List from './${sub.entityName}List.vue'
|
||||
</#list>
|
||||
import {columns, searchFormSchema} from './${entityName?uncap_first}.data';
|
||||
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName?uncap_first}.api';
|
||||
<#if list_need_category>
|
||||
import { loadCategoryData } from '/@/api/common/api'
|
||||
import { getAuthCache, setAuthCache } from '/@/utils/auth';
|
||||
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
|
||||
</#if>
|
||||
//注册model
|
||||
const [registerModal, {openModal}] = useModal();
|
||||
//注册table数据
|
||||
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
|
||||
tableProps:{
|
||||
title: '${tableVo.ftlDescription}',
|
||||
api: list,
|
||||
columns,
|
||||
canResize:false,
|
||||
rowSelection: {type: 'radio'},
|
||||
formConfig: {
|
||||
schemas: searchFormSchema,
|
||||
fieldMapToTime: [
|
||||
<#list columns as po>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#if po.queryMode!='single'>
|
||||
<#if po.classType=='date'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD'],
|
||||
<#elseif po.classType=='datetime'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD HH:mm:ss'],
|
||||
</#if>
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
},
|
||||
pagination:{
|
||||
current: 1,
|
||||
pageSize: 5,
|
||||
pageSizeOptions: ['5', '10', '20'],
|
||||
}
|
||||
},
|
||||
exportConfig: {
|
||||
name:"${tableVo.ftlDescription}",
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl
|
||||
},
|
||||
})
|
||||
|
||||
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
|
||||
|
||||
const mainId = computed(() => (unref(selectedRowKeys).length > 0 ? unref(selectedRowKeys)[0] : ''));
|
||||
//下发 mainId,子组件接收
|
||||
provide('mainId', mainId);
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({id: record.id}, reload);
|
||||
}
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
await batchDelete({ids: selectedRowKeys.value}, reload);
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record){
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
}
|
||||
]
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record){
|
||||
return [
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
}, {
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
<#if list_need_category>
|
||||
/**
|
||||
* 初始化字典配置
|
||||
*/
|
||||
function initDictConfig(){
|
||||
<#list columns as po>
|
||||
<#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>
|
||||
<#if po.classType=='cat_tree' && list_need_category==true>
|
||||
loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => {
|
||||
if (res) {
|
||||
let allDictDate = getAuthCache(DB_DICT_DATA_KEY);
|
||||
if(!allDictDate['${po.dictField?default("")}']){
|
||||
Object.assign(allDictDate,{'${po.dictField?default("")}':res})
|
||||
}
|
||||
setAuthCache(DB_DICT_DATA_KEY,allDictDate)
|
||||
}
|
||||
})
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
initDictConfig();
|
||||
</#if>
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,113 @@
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
import {Modal} from 'ant-design-vue';
|
||||
|
||||
enum Api {
|
||||
list = '/${entityPackage}/${entityName?uncap_first}/list',
|
||||
save='/${entityPackage}/${entityName?uncap_first}/add',
|
||||
edit='/${entityPackage}/${entityName?uncap_first}/edit',
|
||||
deleteOne = '/${entityPackage}/${entityName?uncap_first}/delete',
|
||||
deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
|
||||
importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
|
||||
exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
|
||||
<#list subTables as sub><#rt/>
|
||||
${sub.entityName?uncap_first}List = '/${entityPackage}/${entityName?uncap_first}/list${sub.entityName}ByMainId',
|
||||
${sub.entityName?uncap_first}Save='/${entityPackage}/${entityName?uncap_first}/add${sub.entityName}',
|
||||
${sub.entityName?uncap_first}Edit='/${entityPackage}/${entityName?uncap_first}/edit${sub.entityName}',
|
||||
${sub.entityName?uncap_first}Delete = '/${entityPackage}/${entityName?uncap_first}/delete${sub.entityName}',
|
||||
${sub.entityName?uncap_first}DeleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch${sub.entityName}',
|
||||
${sub.entityName?uncap_first}ExportXlsUrl = '/${entityPackage}/${entityName?uncap_first}/export${sub.entityName}',
|
||||
${sub.entityName?uncap_first}ImportUrl = '/${entityPackage}/${entityName?uncap_first}/import${sub.entityName}',
|
||||
</#list>
|
||||
}
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) =>
|
||||
defHttp.get({url: Api.list, params});
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params,handleSuccess) => {
|
||||
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({url: url, params});
|
||||
}
|
||||
<#list subTables as sub><#rt/>
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const ${sub.entityName?uncap_first}List = (params) =>
|
||||
defHttp.get({url: Api.${sub.entityName?uncap_first}List, params});
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const ${sub.entityName?uncap_first}Delete = (params,handleSuccess) => {
|
||||
return defHttp.delete({url: Api.${sub.entityName?uncap_first}Delete, params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const ${sub.entityName?uncap_first}DeleteBatch = (params, handleSuccess) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({url: Api.${sub.entityName?uncap_first}DeleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const ${sub.entityName?uncap_first}SaveOrUpdate = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.${sub.entityName?uncap_first}Edit : Api.${sub.entityName?uncap_first}Save;
|
||||
return defHttp.post({url: url, params});
|
||||
}
|
||||
</#list>
|
||||
@ -0,0 +1,601 @@
|
||||
import {BasicColumn} from '/@/components/Table';
|
||||
import {FormSchema} from '/@/components/Table';
|
||||
import { rules} from '/@/utils/helper/validator';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
<#list columns as po>
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||
{
|
||||
title: '${po.filedComment}',
|
||||
align:"center",
|
||||
<#if po.sort=='Y'>
|
||||
sorter: true,
|
||||
</#if>
|
||||
<#if po.classType=='date'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:({text}) =>{
|
||||
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||
},
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
dataIndex: '${po.fieldName}String'
|
||||
<#elseif po.classType=='umeditor'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'htmlSlot' },
|
||||
<#elseif po.classType=='pca'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||
<#elseif po.classType=='file'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'fileSlot' },
|
||||
<#elseif po.classType=='image'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:render.renderAvatar,
|
||||
<#elseif po.classType=='switch'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#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>
|
||||
<#assign switch_extend_arr1=a>
|
||||
<#else>
|
||||
<#assign switch_extend_arr2=a>
|
||||
</#if>
|
||||
</#list>
|
||||
customRender:({text}) => {
|
||||
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||
},
|
||||
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||
dataIndex: '${po.fieldName}_dictText'
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#if po.dictText?default("")?trim?length == 0>
|
||||
customRender:({text}) => {
|
||||
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||
},
|
||||
<#else>
|
||||
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||
</#if>
|
||||
<#else>
|
||||
dataIndex: '${po.fieldName}'
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#assign query_flag=true>
|
||||
<#assign query_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictField}">
|
||||
</#if>
|
||||
<#if po.queryMode=='single'>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
},
|
||||
<#elseif po.classType=='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
<#elseif po.classType=='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType=='list_multi'>
|
||||
component: 'JMultiSelectTag',//暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"query_field_dictCode?default("")"
|
||||
},
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题
|
||||
},
|
||||
<#elseif po.classType=='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.classType=='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType=='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:"${po.dictField}",
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
},
|
||||
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
<#else>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='date'>
|
||||
component: 'RangePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#else>
|
||||
component: 'Input', //TODO 范围查询
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
<#-- 结束循环 -->
|
||||
];
|
||||
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list columns as po><#rt/>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#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>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#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'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#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}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
|
||||
<#list subTables as sub>
|
||||
//子表列表数据
|
||||
export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [
|
||||
<#list sub.originalColumns as po>
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||
{
|
||||
title: '${po.filedComment}',
|
||||
align:"center",
|
||||
<#if po.sort=='Y'>
|
||||
sorter: true,
|
||||
</#if>
|
||||
<#if po.classType=='date'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:({text}) =>{
|
||||
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||
},
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
dataIndex: '${po.fieldName}String'
|
||||
<#elseif po.classType=='umeditor'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'htmlSlot' },
|
||||
<#elseif po.classType=='pca'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||
<#elseif po.classType=='file'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'fileSlot' },
|
||||
<#elseif po.classType=='image'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:render.renderAvatar,
|
||||
<#elseif po.classType=='switch'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#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>
|
||||
<#assign switch_extend_arr1=a>
|
||||
<#else>
|
||||
<#assign switch_extend_arr2=a>
|
||||
</#if>
|
||||
</#list>
|
||||
customRender:({text}) => {
|
||||
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||
},
|
||||
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||
dataIndex: '${po.fieldName}_dictText'
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#if po.dictText?default("")?trim?length == 0>
|
||||
customRender:({text}) => {
|
||||
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||
},
|
||||
<#else>
|
||||
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||
</#if>
|
||||
<#else>
|
||||
dataIndex: '${po.fieldName}'
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//子表表单数据
|
||||
export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list sub.originalColumns as po><#rt/>
|
||||
<#if po.isShow =='Y'>
|
||||
<#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>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#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'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#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}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
</#list>
|
||||
@ -0,0 +1,157 @@
|
||||
<#list subTables as sub>
|
||||
#segment#${sub.entityName}List.vue
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection" :searchInfo="searchInfo">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleCreate" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button>批量操作
|
||||
<Icon icon="mdi:chevron-down"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)"/>
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{text}">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<template #fileSlot="{text}">
|
||||
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
|
||||
<${sub.entityName}Modal @register="registerModal" @success="handleSuccess"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, unref,inject,watch} from 'vue';
|
||||
import {BasicTable, useTable, TableAction} from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage'
|
||||
import {useModal} from '/@/components/Modal';
|
||||
import ${sub.entityName}Modal from './components/${sub.entityName}Modal.vue'
|
||||
import {${sub.entityName?uncap_first}Columns} from './${entityName}.data';
|
||||
import {${sub.entityName?uncap_first}List, ${sub.entityName?uncap_first}Delete, ${sub.entityName?uncap_first}DeleteBatch} from './${entityName}.api';
|
||||
import {isEmpty} from "/@/utils/is";
|
||||
import {useMessage} from '/@/hooks/web/useMessage';
|
||||
|
||||
//接收主表id
|
||||
const mainId = inject('mainId') || '';
|
||||
//提示弹窗
|
||||
const $message = useMessage()
|
||||
//弹窗model
|
||||
const [registerModal, {openModal}] = useModal();
|
||||
const searchInfo = {};
|
||||
// 列表页面公共参数、方法
|
||||
const {prefixCls, tableContext} = useListPage({
|
||||
tableProps: {
|
||||
api: ${sub.entityName?uncap_first}List,
|
||||
columns: ${sub.entityName?uncap_first}Columns,
|
||||
canResize: false,
|
||||
useSearchForm: false,
|
||||
actionColumn: {
|
||||
width: 180,
|
||||
},
|
||||
pagination:{
|
||||
current: 1,
|
||||
pageSize: 5,
|
||||
pageSizeOptions: ['5', '10', '20'],
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
//注册table数据
|
||||
const [registerTable, {reload}, {rowSelection, selectedRowKeys}] = tableContext;
|
||||
|
||||
watch(mainId, () => {
|
||||
<#list sub.foreignKeys as key>
|
||||
searchInfo['${key?uncap_first}'] = unref(mainId);
|
||||
</#list>
|
||||
reload();
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleCreate() {
|
||||
if (isEmpty(unref(mainId))) {
|
||||
$message.createMessage.warning('请选择一个主表信息')
|
||||
return;
|
||||
}
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
async function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await ${sub.entityName?uncap_first}Delete({id: record.id}, reload);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
await ${sub.entityName?uncap_first}DeleteBatch({ids: selectedRowKeys.value}, () => {
|
||||
reload()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
}, {
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
</#list>
|
||||
@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm"/>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, unref} from 'vue';
|
||||
import {BasicModal, useModalInner} from '/@/components/Modal';
|
||||
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||
import {formSchema} from '../${entityName?uncap_first}.data';
|
||||
import {saveOrUpdate} from '../${entityName?uncap_first}.api';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register','success']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({confirmLoading: false,showCancelBtn:!!data?.showFooter,showOkBtn:!!data?.showFooter});
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
setProps({ disabled: !data?.showFooter })
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
//表单提交事件
|
||||
async function handleSubmit(v) {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({confirmLoading: true});
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({confirmLoading: false});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,66 @@
|
||||
<#include "/common/utils.ftl">
|
||||
<#list subTables as sub>
|
||||
#segment#${sub.entityName}Modal.vue
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm"/>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, unref,inject} from 'vue';
|
||||
import {BasicModal, useModalInner} from '/@/components/Modal';
|
||||
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||
import {${sub.entityName?uncap_first}FormSchema} from '../${entityName?uncap_first}.data';
|
||||
import {${sub.entityName?uncap_first}SaveOrUpdate} from '../${entityName?uncap_first}.api';
|
||||
|
||||
//接收主表id
|
||||
const mainId = inject('mainId');
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register','success']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: ${sub.entityName?uncap_first}FormSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({confirmLoading: false,showCancelBtn:!!data?.showFooter,showOkBtn:!!data?.showFooter});
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
setProps({ disabled: !data?.showFooter })
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
//表单提交事件
|
||||
async function handleSubmit(v) {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({confirmLoading: true});
|
||||
if (unref(mainId)) {
|
||||
<#list sub.foreignKeys as key>
|
||||
values['${key?uncap_first}'] = unref(mainId);
|
||||
</#list>
|
||||
}
|
||||
//提交表单
|
||||
await ${sub.entityName?uncap_first}SaveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({confirmLoading: false});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</#list>
|
||||
@ -110,7 +110,7 @@ public class ${entityName}Controller {
|
||||
*/
|
||||
@AutoLog(value = "${tableVo.ftlDescription}-编辑")
|
||||
@ApiOperation(value="${tableVo.ftlDescription}-编辑", notes="${tableVo.ftlDescription}-编辑")
|
||||
@PutMapping(value = "/edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) {
|
||||
${entityName} ${entityName?uncap_first} = new ${entityName}();
|
||||
BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first});
|
||||
|
||||
@ -266,9 +266,7 @@
|
||||
<a @click="handleEdit(record)">编辑</a>
|
||||
<a-divider type="vertical"/>
|
||||
<a-dropdown>
|
||||
<a class="ant-dropdown-link">
|
||||
<span>更多 <a-icon type="down"/></span>
|
||||
</a>
|
||||
<a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item>
|
||||
<a-popconfirm title="确定删除吗?" @confirm="handleDelete(record.id)">
|
||||
|
||||
@ -21,13 +21,8 @@
|
||||
<#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'>
|
||||
@ -131,7 +126,7 @@
|
||||
</#list>
|
||||
</a-tabs>
|
||||
<#if bpm_flag>
|
||||
<a-row v-if="showFlowSubmitButton" style="text-align: center;width: 100%;margin-top: 16px;"><a-button @click="handleOk">提 交</a-button></a-row>
|
||||
<a-row v-if="showFlowSubmitButton" style="text-align: center;width: 100%;margin-top: 16px;"><a-button icon="check" style="width: 126px" type="primary" @click="handleOk">提 交</a-button></a-row>
|
||||
</#if>
|
||||
</a-spin>
|
||||
</template>
|
||||
@ -161,20 +156,12 @@
|
||||
return {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
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">
|
||||
},
|
||||
|
||||
@ -15,13 +15,8 @@
|
||||
<#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%"/>
|
||||
<#elseif po.classType =='datetime'>
|
||||
@ -90,20 +85,12 @@
|
||||
},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
labelCol2: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 3 },
|
||||
},
|
||||
wrapperCol2: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 20 },
|
||||
},
|
||||
<#include "/common/validatorRulesTemplate/sub.ftl">
|
||||
confirmLoading: false,
|
||||
}
|
||||
|
||||
@ -0,0 +1,244 @@
|
||||
<#-- ** 引入全局工具方法 ** -->
|
||||
<#--<#include "/common/utils.ftl">-->
|
||||
<#include "../../../../../../common/utils.ftl">
|
||||
<template>
|
||||
<div>
|
||||
<#assign list_need_category=false>
|
||||
<#assign list_need_pca=false>
|
||||
<#assign bpm_flag=false>
|
||||
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#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>
|
||||
<#-- 结束循环 -->
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection" :expandedRowKeys="expandedRowKeys" @expand="handleExpand">
|
||||
<!-- 内嵌table区域 begin -->
|
||||
<template #expandedRowRender="{record}">
|
||||
<a-tabs tabPosition="top">
|
||||
<#list subTables as sub>
|
||||
<a-tab-pane tab="${sub.ftlDescription}" key="${sub.entityName?uncap_first}" forceRender>
|
||||
<${sub.entityName?uncap_first}SubTable :id="expandedRowKeys[0]"/>
|
||||
</a-tab-pane>
|
||||
</#list>
|
||||
</a-tabs>
|
||||
</template>
|
||||
<!-- 内嵌table区域 end -->
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button>批量操作
|
||||
<Icon icon="mdi:chevron-down"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{text}">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<template #fileSlot="{text}">
|
||||
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup>
|
||||
import {ref, computed, unref} from 'vue';
|
||||
import {BasicTable, useTable, TableAction} from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage'
|
||||
import {useModal} from '/@/components/Modal';
|
||||
import ${entityName}Modal from './components/${entityName}Modal.vue'
|
||||
<#list subTables as sub>
|
||||
import ${sub.entityName}SubTable from './subTables/${sub.entityName}SubTable.vue'
|
||||
</#list>
|
||||
import {columns, searchFormSchema} from './${entityName?uncap_first}.data';
|
||||
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName?uncap_first}.api';
|
||||
<#if list_need_category>
|
||||
import { loadCategoryData } from '/@/api/common/api'
|
||||
import { getAuthCache, setAuthCache } from '/@/utils/auth';
|
||||
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
|
||||
</#if>
|
||||
// 展开key
|
||||
const expandedRowKeys = ref<any[]>([]);
|
||||
//注册model
|
||||
const [registerModal, {openModal}] = useModal();
|
||||
//注册table数据
|
||||
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
|
||||
tableProps:{
|
||||
title: '${tableVo.ftlDescription}',
|
||||
api: list,
|
||||
columns,
|
||||
canResize:false,
|
||||
formConfig: {
|
||||
labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter:true,
|
||||
showAdvancedButton:true,
|
||||
fieldMapToTime: [
|
||||
<#list columns as po>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#if po.queryMode!='single'>
|
||||
<#if po.classType=='date'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD'],
|
||||
<#elseif po.classType=='datetime'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD HH:mm:ss'],
|
||||
</#if>
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name:"${tableVo.ftlDescription}",
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl
|
||||
},
|
||||
})
|
||||
|
||||
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
|
||||
/**
|
||||
* 展开事件
|
||||
* */
|
||||
function handleExpand(expanded, record){
|
||||
expandedRowKeys.value=[];
|
||||
if (expanded === true) {
|
||||
expandedRowKeys.value.push(record.id)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({id: record.id}, reload);
|
||||
}
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
await batchDelete({ids: selectedRowKeys.value}, reload);
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record){
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
}
|
||||
]
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record){
|
||||
return [
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
}, {
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
<#if list_need_category>
|
||||
/**
|
||||
* 初始化字典配置
|
||||
*/
|
||||
function initDictConfig(){
|
||||
<#list columns as po>
|
||||
<#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>
|
||||
<#if po.classType=='cat_tree' && list_need_category==true>
|
||||
loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => {
|
||||
if (res) {
|
||||
let allDictDate = getAuthCache(DB_DICT_DATA_KEY);
|
||||
if(!allDictDate['${po.dictField?default("")}']){
|
||||
Object.assign(allDictDate,{'${po.dictField?default("")}':res})
|
||||
}
|
||||
setAuthCache(DB_DICT_DATA_KEY,allDictDate)
|
||||
}
|
||||
})
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
initDictConfig();
|
||||
</#if>
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,80 @@
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
import {Modal} from 'ant-design-vue';
|
||||
|
||||
enum Api {
|
||||
list = '/${entityPackage}/${entityName?uncap_first}/list',
|
||||
save='/${entityPackage}/${entityName?uncap_first}/add',
|
||||
edit='/${entityPackage}/${entityName?uncap_first}/edit',
|
||||
deleteOne = '/${entityPackage}/${entityName?uncap_first}/delete',
|
||||
deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
|
||||
importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
|
||||
exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
|
||||
<#list subTables as sub><#rt/>
|
||||
${sub.entityName?uncap_first}List = '/${entityPackage}/${entityName?uncap_first}/query${sub.entityName}ByMainId',
|
||||
</#list>
|
||||
}
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
<#list subTables as sub><#rt/>
|
||||
/**
|
||||
* 子表单查询接口
|
||||
* @param params
|
||||
*/
|
||||
export const query${sub.entityName} = Api.${sub.entityName?uncap_first}List
|
||||
</#list>
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) =>
|
||||
defHttp.get({url: Api.list, params});
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params,handleSuccess) => {
|
||||
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({url: url, params});
|
||||
}
|
||||
<#list subTables as sub><#rt/>
|
||||
/**
|
||||
* 子表列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const ${sub.entityName?uncap_first}List = (params) =>
|
||||
defHttp.get({url: Api.${sub.entityName?uncap_first}List, params},{isTransformResponse:false});
|
||||
</#list>
|
||||
@ -0,0 +1,763 @@
|
||||
import {BasicColumn} from '/@/components/Table';
|
||||
import {FormSchema} from '/@/components/Table';
|
||||
import { rules} from '/@/utils/helper/validator';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import {JVxeTypes,JVxeColumn} from '/@/components/jeecg/JVxeTable/types'
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
<#list columns as po>
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||
{
|
||||
title: '${po.filedComment}',
|
||||
align:"center",
|
||||
<#if po.sort=='Y'>
|
||||
sorter: true,
|
||||
</#if>
|
||||
<#if po.classType=='date'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:({text}) =>{
|
||||
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||
},
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
dataIndex: '${po.fieldName}String'
|
||||
<#elseif po.classType=='umeditor'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'htmlSlot' },
|
||||
<#elseif po.classType=='pca'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||
<#elseif po.classType=='file'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'fileSlot' },
|
||||
<#elseif po.classType=='image'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:render.renderAvatar,
|
||||
<#elseif po.classType=='switch'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#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>
|
||||
<#assign switch_extend_arr1=a>
|
||||
<#else>
|
||||
<#assign switch_extend_arr2=a>
|
||||
</#if>
|
||||
</#list>
|
||||
customRender:({text}) => {
|
||||
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||
},
|
||||
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||
dataIndex: '${po.fieldName}_dictText'
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#if po.dictText?default("")?trim?length == 0>
|
||||
customRender:({text}) => {
|
||||
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||
},
|
||||
<#else>
|
||||
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||
</#if>
|
||||
<#else>
|
||||
dataIndex: '${po.fieldName}'
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#assign query_flag=true>
|
||||
<#assign query_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictField}">
|
||||
</#if>
|
||||
<#if po.queryMode=='single'>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
},
|
||||
<#elseif po.classType=='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
<#elseif po.classType=='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType=='list_multi'>
|
||||
component: 'JMultiSelectTag',//暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"query_field_dictCode?default("")"
|
||||
},
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题
|
||||
},
|
||||
<#elseif po.classType=='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.classType=='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType=='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:"${po.dictField}",
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
},
|
||||
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
<#else>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='date'>
|
||||
component: 'RangePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#else>
|
||||
component: 'Input', //TODO 范围查询
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
<#-- 结束循环 -->
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list columns as po><#rt/>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#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>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#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'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#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}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//子表单数据
|
||||
<#list subTables as sub>
|
||||
//子表列表数据
|
||||
export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [
|
||||
<#list sub.originalColumns as po>
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||
{
|
||||
title: '${po.filedComment}',
|
||||
align:"center",
|
||||
<#if po.sort=='Y'>
|
||||
sorter: true,
|
||||
</#if>
|
||||
<#if po.classType=='date'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:({text}) =>{
|
||||
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||
},
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
dataIndex: '${po.fieldName}String'
|
||||
<#elseif po.classType=='umeditor'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'htmlSlot' },
|
||||
<#elseif po.classType=='pca'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||
<#elseif po.classType=='file'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'fileSlot' },
|
||||
<#elseif po.classType=='image'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:render.renderAvatar,
|
||||
<#elseif po.classType=='switch'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#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>
|
||||
<#assign switch_extend_arr1=a>
|
||||
<#else>
|
||||
<#assign switch_extend_arr2=a>
|
||||
</#if>
|
||||
</#list>
|
||||
customRender:({text}) => {
|
||||
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||
},
|
||||
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||
dataIndex: '${po.fieldName}_dictText'
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#if po.dictText?default("")?trim?length == 0>
|
||||
customRender:({text}) => {
|
||||
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||
},
|
||||
<#else>
|
||||
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||
</#if>
|
||||
<#else>
|
||||
dataIndex: '${po.fieldName}'
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list sub.colums as po><#rt/>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#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>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#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'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#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}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
</#if>
|
||||
</#list>
|
||||
//子表表格配置
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [
|
||||
<#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: JVxeTypes.date,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='datetime'>
|
||||
type: JVxeTypes.datetime,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='textarea'>
|
||||
type: JVxeTypes.textarea,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif "int,decimal,double,"?contains(col.classType)>
|
||||
type: JVxeTypes.inputNumber,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='list' || col.classType =='radio'>
|
||||
type: JVxeTypes.select,
|
||||
options:[],
|
||||
<#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: JVxeTypes.selectMultiple,
|
||||
options:[],
|
||||
<#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: JVxeTypes.selectSearch,
|
||||
<#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: JVxeTypes.image,
|
||||
token:true,
|
||||
responseName:"message",
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#if col.uploadnum??>
|
||||
number: ${col.uploadnum},
|
||||
</#if>
|
||||
<#elseif col.classType =='file'>
|
||||
type: JVxeTypes.file,
|
||||
token:true,
|
||||
responseName:"message",
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#if col.uploadnum??>
|
||||
number: ${col.uploadnum},
|
||||
</#if>
|
||||
<#elseif col.classType =='switch'>
|
||||
type: JVxeTypes.checkbox,
|
||||
<#if col.dictField == 'is_open'>
|
||||
customValue: ['Y', 'N'],
|
||||
<#else>
|
||||
customValue: ${col.dictField},
|
||||
</#if>
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='popup'>
|
||||
<#if popupBackFields?length gt 0>
|
||||
<#assign popupBackFields = "${popupBackFields}"+","+"${col.dictText}">
|
||||
<#else>
|
||||
<#assign popupBackFields = "${col.dictText}">
|
||||
</#if>
|
||||
type: JVxeTypes.popup,
|
||||
popupCode:"${col.dictTable}",
|
||||
field:"${col.dictField}",
|
||||
orgFields:"${col.dictField}",
|
||||
destFields:"${Format.underlineToHump(col.dictText)}",
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#else>
|
||||
type: JVxeTypes.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>
|
||||
<#-- 循环子表的列 结束 -->
|
||||
]
|
||||
</#if>
|
||||
</#list>
|
||||
@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" ref="formRef"/>
|
||||
<!-- 子表单区域 -->
|
||||
<a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs">
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index}]" :forceRender="true">
|
||||
<${sub.entityName}Form ref="${sub.entityName?uncap_first}Form"></${sub.entityName}Form>
|
||||
</a-tab-pane>
|
||||
|
||||
<#else>
|
||||
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index}]" :forceRender="true">
|
||||
<JVxeTable
|
||||
keep-source
|
||||
resizable
|
||||
: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"
|
||||
:toolbar="true"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</#if>
|
||||
</#list>
|
||||
</a-tabs>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, unref,reactive} from 'vue';
|
||||
import {BasicModal, useModalInner} from '/@/components/Modal';
|
||||
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||
import { JVxeTable } from '/@/components/jeecg/JVxeTable'
|
||||
import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts'
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
import ${sub.entityName}Form from './${sub.entityName}Form.vue'
|
||||
</#if>
|
||||
</#list>
|
||||
import {formSchema<#list subTables as sub><#if sub.foreignRelationType =='0'>,${sub.entityName?uncap_first}JVxeColumns</#if></#list>} from '../${entityName?uncap_first}.data';
|
||||
import {saveOrUpdate<#list subTables as sub>,query${sub.entityName}</#list>} from '../${entityName?uncap_first}.api';
|
||||
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register','success']);
|
||||
const isUpdate = ref(true);
|
||||
const refKeys = ref([<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]);
|
||||
<#assign hasOne2Many = false>
|
||||
<#assign hasOne2One = false>
|
||||
const activeKey = ref('${subTables[0].entityName?uncap_first}');
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
<#assign hasOne2Many = true>
|
||||
const ${sub.entityName?uncap_first} = ref();
|
||||
</#if>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
<#assign hasOne2One = true>
|
||||
const ${sub.entityName?uncap_first}Form = ref();
|
||||
</#if>
|
||||
</#list>
|
||||
const tableRefs = {<#list subTables as sub><#if sub.foreignRelationType =='0'>${sub.entityName?uncap_first}, <#assign hasOne2Many = true></#if></#list>};
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
const ${sub.entityName?uncap_first}Table = reactive({
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns:${sub.entityName?uncap_first}JVxeColumns
|
||||
})
|
||||
</#if>
|
||||
</#list>
|
||||
//表单配置
|
||||
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await reset();
|
||||
setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter});
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
${sub.entityName?uncap_first}Form.value.initFormData(query${sub.entityName},data?.record?.id)
|
||||
</#if>
|
||||
</#list>
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
requestSubTableData(query${sub.entityName}, {id:data?.record?.id}, ${sub.entityName?uncap_first}Table)
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
setProps({ disabled: !data?.showFooter })
|
||||
});
|
||||
//方法配置
|
||||
const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys<#if hasOne2One==true>,validateSubForm</#if>);
|
||||
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
|
||||
async function reset(){
|
||||
await resetFields();
|
||||
activeKey.value = ref('${subTables[0].entityName?uncap_first}');
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
${sub.entityName?uncap_first}Table.dataSource = [];
|
||||
</#if>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
${sub.entityName?uncap_first}Form.value.resetFields();
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
function classifyIntoFormData(allValues) {
|
||||
let main = Object.assign({}, allValues.formValue)
|
||||
return {
|
||||
...main, // 展开
|
||||
<#assign subManyIndex = 0>
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
${sub.entityName?uncap_first}List: allValues.tablesValue[${subManyIndex}].tableData,
|
||||
<#assign subManyIndex = subManyIndex+1>
|
||||
<#else>
|
||||
${sub.entityName?uncap_first}List: ${sub.entityName?uncap_first}Form.value.getFormData(),
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
}
|
||||
<#if hasOne2One==true>
|
||||
//校验所有一对一子表表单
|
||||
function validateSubForm(allValues){
|
||||
return new Promise((resolve,reject)=>{
|
||||
Promise.all([
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
${sub.entityName?uncap_first}Form.value.validateForm(${sub_index}),
|
||||
</#if>
|
||||
</#list>
|
||||
]).then(() => {
|
||||
resolve(allValues)
|
||||
}).catch(e => {
|
||||
if (e.error === VALIDATE_FAILED) {
|
||||
// 如果有未通过表单验证的子表,就自动跳转到它所在的tab
|
||||
activeKey.value = e.index == null ? unref(activeKey) : refKeys.value[e.index]
|
||||
} else {
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
</#if>
|
||||
//表单提交事件
|
||||
async function requestAddOrEdit(values) {
|
||||
try {
|
||||
setModalProps({confirmLoading: true});
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({confirmLoading: false});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,64 @@
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType=='1'>
|
||||
#segment#${sub.entityName}Form.vue
|
||||
<template>
|
||||
<BasicForm @register="registerForm"/>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue';
|
||||
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||
import {${sub.entityName?uncap_first}FormSchema} from '../${entityName?uncap_first}.data';
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
|
||||
|
||||
export default defineComponent({
|
||||
name:"${sub.entityName}Form",
|
||||
components: {BasicForm},
|
||||
emits:['register'],
|
||||
setup(_,{emit}) {
|
||||
const [registerForm, {resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: ${sub.entityName?uncap_first}FormSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
/**
|
||||
*初始化加载数据
|
||||
*/
|
||||
function initFormData(url,id){
|
||||
if(id){
|
||||
defHttp.get({url,params:{id}},{isTransformResponse:false}).then(res=>{
|
||||
res.success && setFieldsValue({...res.result.records[0]});
|
||||
})
|
||||
}
|
||||
}
|
||||
/**
|
||||
*获取表单数据
|
||||
*/
|
||||
function getFormData(){
|
||||
return [getFieldsValue()];
|
||||
}
|
||||
/**
|
||||
*表单校验
|
||||
*/
|
||||
function validateForm(index){
|
||||
return new Promise((resolve, reject) => {
|
||||
// 验证子表表单
|
||||
validate().then(()=>{
|
||||
return resolve()
|
||||
}).catch(()=> {
|
||||
return reject({ error: VALIDATE_FAILED ,index})
|
||||
})
|
||||
})
|
||||
}
|
||||
return {
|
||||
registerForm,
|
||||
resetFields,
|
||||
initFormData,
|
||||
getFormData,
|
||||
validateForm
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</#if>
|
||||
</#list>
|
||||
@ -0,0 +1,69 @@
|
||||
<#--noinspection JSDuplicatedDeclaration-->
|
||||
<#list subTables as sub>
|
||||
#segment#${sub.entityName}SubTable.vue
|
||||
<template>
|
||||
<div>
|
||||
<#assign list_need_category=false>
|
||||
<#assign list_need_pca=false>
|
||||
<#assign bpm_flag=false>
|
||||
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#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>
|
||||
<#-- 结束循环 -->
|
||||
<!--引用表格-->
|
||||
<BasicTable bordered size="middle" :loading="loading" rowKey="id" :canResize="false" :columns="${sub.entityName?uncap_first}Columns" :dataSource="dataSource" :pagination="false">
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{text}">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<template #fileSlot="{text}">
|
||||
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref,watchEffect} from 'vue';
|
||||
import {BasicTable} from '/@/components/Table';
|
||||
import {${sub.entityName?uncap_first}Columns} from '../${entityName}.data';
|
||||
import {${sub.entityName?uncap_first}List} from '../${entityName}.api';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
})
|
||||
|
||||
const loading = ref(false);
|
||||
const dataSource = ref([]);
|
||||
|
||||
watchEffect(() => {
|
||||
props.id && loadData(props.id);
|
||||
});
|
||||
|
||||
function loadData(id) {
|
||||
dataSource.value = []
|
||||
loading.value = true
|
||||
${sub.entityName?uncap_first}List({id}).then((res) => {
|
||||
if (res.success) {
|
||||
dataSource.value = res.result.records
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</#list>
|
||||
@ -28,13 +28,8 @@
|
||||
<#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 :span="${form_span}" >
|
||||
<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'>
|
||||
@ -140,7 +135,7 @@
|
||||
</#list>
|
||||
</a-tabs>
|
||||
<#if bpm_flag>
|
||||
<a-row v-if="showFlowSubmitButton" style="text-align: center;width: 100%;margin-top: 16px;"><a-button @click="handleOk">提 交</a-button></a-row>
|
||||
<a-row v-if="showFlowSubmitButton" style="text-align: center;width: 100%;margin-top: 16px;"><a-button icon="check" style="width: 126px" type="primary" @click="handleOk">提 交</a-button></a-row>
|
||||
</#if>
|
||||
</a-spin>
|
||||
</template>
|
||||
@ -174,20 +169,12 @@
|
||||
return {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
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">
|
||||
},
|
||||
|
||||
@ -25,13 +25,8 @@
|
||||
<#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 :span="${form_span}">
|
||||
<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%"/>
|
||||
<#elseif po.classType =='datetime'>
|
||||
@ -117,20 +112,12 @@
|
||||
},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
labelCol2: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 3 },
|
||||
},
|
||||
wrapperCol2: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 20 },
|
||||
},
|
||||
<#include "/common/validatorRulesTemplate/sub.ftl">
|
||||
confirmLoading: false,
|
||||
}
|
||||
|
||||
@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<div>
|
||||
<#assign list_need_category=false>
|
||||
<#assign list_need_pca=false>
|
||||
<#assign bpm_flag=false>
|
||||
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#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>
|
||||
<#-- 结束循环 -->
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<a-dropdown v-if="checkedKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button>批量操作
|
||||
<Icon icon="mdi:chevron-down"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{text}">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<template #fileSlot="{text}">
|
||||
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup>
|
||||
import {ref, computed, unref} from 'vue';
|
||||
import {BasicTable, useTable, TableAction} from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage'
|
||||
import {useModal} from '/@/components/Modal';
|
||||
import ${entityName}Modal from './components/${entityName}Modal.vue'
|
||||
import {columns, searchFormSchema} from './${entityName?uncap_first}.data';
|
||||
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName?uncap_first}.api';
|
||||
<#if list_need_category>
|
||||
import { loadCategoryData } from '/@/api/common/api'
|
||||
import { getAuthCache, setAuthCache } from '/@/utils/auth';
|
||||
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
|
||||
</#if>
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
//注册model
|
||||
const [registerModal, {openModal}] = useModal();
|
||||
//注册table数据
|
||||
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
|
||||
tableProps:{
|
||||
title: '${tableVo.ftlDescription}',
|
||||
api: list,
|
||||
columns,
|
||||
canResize:false,
|
||||
formConfig: {
|
||||
labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter:true,
|
||||
showAdvancedButton:true,
|
||||
fieldMapToTime: [
|
||||
<#list columns as po>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#if po.queryMode!='single'>
|
||||
<#if po.classType=='date'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD'],
|
||||
<#elseif po.classType=='datetime'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD HH:mm:ss'],
|
||||
</#if>
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name:"${tableVo.ftlDescription}",
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl
|
||||
},
|
||||
})
|
||||
|
||||
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({id: record.id}, reload);
|
||||
}
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
await batchDelete({ids: checkedKeys.value}, reload);
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record){
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
}
|
||||
]
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record){
|
||||
return [
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
}, {
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
<#if list_need_category>
|
||||
/**
|
||||
* 初始化字典配置
|
||||
*/
|
||||
function initDictConfig(){
|
||||
<#list columns as po>
|
||||
<#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>
|
||||
<#if po.classType=='cat_tree' && list_need_category==true>
|
||||
loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => {
|
||||
if (res) {
|
||||
let allDictDate = getAuthCache(DB_DICT_DATA_KEY);
|
||||
if(!allDictDate['${po.dictField?default("")}']){
|
||||
Object.assign(allDictDate,{'${po.dictField?default("")}':res})
|
||||
}
|
||||
setAuthCache(DB_DICT_DATA_KEY,allDictDate)
|
||||
}
|
||||
})
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
initDictConfig();
|
||||
</#if>
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,72 @@
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
import {Modal} from 'ant-design-vue';
|
||||
|
||||
enum Api {
|
||||
list = '/${entityPackage}/${entityName?uncap_first}/list',
|
||||
save='/${entityPackage}/${entityName?uncap_first}/add',
|
||||
edit='/${entityPackage}/${entityName?uncap_first}/edit',
|
||||
deleteOne = '/${entityPackage}/${entityName?uncap_first}/delete',
|
||||
deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
|
||||
importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
|
||||
exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
|
||||
<#list subTables as sub><#rt/>
|
||||
${sub.entityName?uncap_first}List = '/${entityPackage}/${entityName?uncap_first}/query${sub.entityName}ByMainId',
|
||||
</#list>
|
||||
}
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
<#list subTables as sub><#rt/>
|
||||
/**
|
||||
* 查询子表数据
|
||||
* @param params
|
||||
*/
|
||||
export const ${sub.entityName?uncap_first}List = Api.${sub.entityName?uncap_first}List;
|
||||
</#list>
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) =>
|
||||
defHttp.get({url: Api.list, params});
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params,handleSuccess) => {
|
||||
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({url: url, params});
|
||||
}
|
||||
@ -0,0 +1,700 @@
|
||||
import {BasicColumn} from '/@/components/Table';
|
||||
import {FormSchema} from '/@/components/Table';
|
||||
import { rules} from '/@/utils/helper/validator';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import {JVxeTypes,JVxeColumn} from '/@/components/jeecg/JVxeTable/types'
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
<#list columns as po>
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||
{
|
||||
title: '${po.filedComment}',
|
||||
align:"center",
|
||||
<#if po.sort=='Y'>
|
||||
sorter: true,
|
||||
</#if>
|
||||
<#if po.classType=='date'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:({text}) =>{
|
||||
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||
},
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
dataIndex: '${po.fieldName}String'
|
||||
<#elseif po.classType=='umeditor'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'htmlSlot' },
|
||||
<#elseif po.classType=='pca'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||
<#elseif po.classType=='file'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'fileSlot' },
|
||||
<#elseif po.classType=='image'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:render.renderAvatar,
|
||||
<#elseif po.classType=='switch'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#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>
|
||||
<#assign switch_extend_arr1=a>
|
||||
<#else>
|
||||
<#assign switch_extend_arr2=a>
|
||||
</#if>
|
||||
</#list>
|
||||
customRender:({text}) => {
|
||||
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||
},
|
||||
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||
dataIndex: '${po.fieldName}_dictText'
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#if po.dictText?default("")?trim?length == 0>
|
||||
customRender:({text}) => {
|
||||
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||
},
|
||||
<#else>
|
||||
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||
</#if>
|
||||
<#else>
|
||||
dataIndex: '${po.fieldName}'
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#assign query_flag=true>
|
||||
<#assign query_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictField}">
|
||||
</#if>
|
||||
<#if po.queryMode=='single'>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
},
|
||||
<#elseif po.classType=='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
<#elseif po.classType=='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType=='list_multi'>
|
||||
component: 'JMultiSelectTag',//暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"query_field_dictCode?default("")"
|
||||
},
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题
|
||||
},
|
||||
<#elseif po.classType=='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.classType=='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType=='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:"${po.dictField}",
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
},
|
||||
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
<#else>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='date'>
|
||||
component: 'RangePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#else>
|
||||
component: 'Input', //TODO 范围查询
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
<#-- 结束循环 -->
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list columns as po><#rt/>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#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>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#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'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#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}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//子表单数据
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list sub.colums as po><#rt/>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#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>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#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'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#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}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
</#if>
|
||||
</#list>
|
||||
//子表表格配置
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
|
||||
<#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: JVxeTypes.date,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='datetime'>
|
||||
type: JVxeTypes.datetime,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='textarea'>
|
||||
type: JVxeTypes.textarea,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif "int,decimal,double,"?contains(col.classType)>
|
||||
type: JVxeTypes.inputNumber,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='list' || col.classType =='radio'>
|
||||
type: JVxeTypes.select,
|
||||
options:[],
|
||||
<#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: JVxeTypes.selectMultiple,
|
||||
options:[],
|
||||
<#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: JVxeTypes.selectSearch,
|
||||
<#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: JVxeTypes.image,
|
||||
token:true,
|
||||
responseName:"message",
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#if col.uploadnum??>
|
||||
number: ${col.uploadnum},
|
||||
</#if>
|
||||
<#elseif col.classType =='file'>
|
||||
type: JVxeTypes.file,
|
||||
token:true,
|
||||
responseName:"message",
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#if col.uploadnum??>
|
||||
number: ${col.uploadnum},
|
||||
</#if>
|
||||
<#elseif col.classType =='switch'>
|
||||
type: JVxeTypes.checkbox,
|
||||
<#if col.dictField == 'is_open'>
|
||||
customValue: ['Y', 'N'],
|
||||
<#else>
|
||||
customValue: ${col.dictField},
|
||||
</#if>
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='popup'>
|
||||
<#if popupBackFields?length gt 0>
|
||||
<#assign popupBackFields = "${popupBackFields}"+","+"${col.dictText}">
|
||||
<#else>
|
||||
<#assign popupBackFields = "${col.dictText}">
|
||||
</#if>
|
||||
type: JVxeTypes.popup,
|
||||
popupCode:"${col.dictTable}",
|
||||
field:"${col.dictField}",
|
||||
orgFields:"${col.dictField}",
|
||||
destFields:"${Format.underlineToHump(col.dictText)}",
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#else>
|
||||
type: JVxeTypes.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>
|
||||
<#-- 循环子表的列 结束 -->
|
||||
]
|
||||
</#if>
|
||||
</#list>
|
||||
@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" ref="formRef"/>
|
||||
<!-- 子表单区域 -->
|
||||
<a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs">
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index}]" :forceRender="true">
|
||||
<${sub.entityName}Form ref="${sub.entityName?uncap_first}Form"></${sub.entityName}Form>
|
||||
</a-tab-pane>
|
||||
|
||||
<#else>
|
||||
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index}]" :forceRender="true">
|
||||
<JVxeTable
|
||||
keep-source
|
||||
resizable
|
||||
: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"
|
||||
:toolbar="true"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</#if>
|
||||
</#list>
|
||||
</a-tabs>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, unref,reactive} from 'vue';
|
||||
import {BasicModal, useModalInner} from '/@/components/Modal';
|
||||
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||
import { JVxeTable } from '/@/components/jeecg/JVxeTable'
|
||||
import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts'
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
import ${sub.entityName}Form from './${sub.entityName}Form.vue'
|
||||
</#if>
|
||||
</#list>
|
||||
import {formSchema<#list subTables as sub><#if sub.foreignRelationType =='0'>,${sub.entityName?uncap_first}Columns</#if></#list>} from '../${entityName?uncap_first}.data';
|
||||
import {saveOrUpdate<#list subTables as sub>,${sub.entityName?uncap_first}List</#list>} from '../${entityName?uncap_first}.api';
|
||||
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register','success']);
|
||||
const isUpdate = ref(true);
|
||||
const refKeys = ref([<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]);
|
||||
<#assign hasOne2Many = false>
|
||||
<#assign hasOne2One = false>
|
||||
const activeKey = ref('${subTables[0].entityName?uncap_first}');
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
<#assign hasOne2Many = true>
|
||||
const ${sub.entityName?uncap_first} = ref();
|
||||
</#if>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
<#assign hasOne2One = true>
|
||||
const ${sub.entityName?uncap_first}Form = ref();
|
||||
</#if>
|
||||
</#list>
|
||||
const tableRefs = {<#list subTables as sub><#if sub.foreignRelationType =='0'>${sub.entityName?uncap_first}, <#assign hasOne2Many = true></#if></#list>};
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
const ${sub.entityName?uncap_first}Table = reactive({
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns:${sub.entityName?uncap_first}Columns
|
||||
})
|
||||
</#if>
|
||||
</#list>
|
||||
//表单配置
|
||||
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await reset();
|
||||
setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter});
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
${sub.entityName?uncap_first}Form.value.initFormData(${sub.entityName?uncap_first}List,data?.record?.id)
|
||||
</#if>
|
||||
</#list>
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
requestSubTableData(${sub.entityName?uncap_first}List, {id:data?.record?.id}, ${sub.entityName?uncap_first}Table)
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
setProps({ disabled: !data?.showFooter })
|
||||
});
|
||||
//方法配置
|
||||
const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys<#if hasOne2One==true>,validateSubForm</#if>);
|
||||
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
|
||||
async function reset(){
|
||||
await resetFields();
|
||||
activeKey.value = ref('${subTables[0].entityName?uncap_first}');
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
${sub.entityName?uncap_first}Table.dataSource = [];
|
||||
</#if>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
${sub.entityName?uncap_first}Form.value.resetFields();
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
function classifyIntoFormData(allValues) {
|
||||
let main = Object.assign({}, allValues.formValue)
|
||||
return {
|
||||
...main, // 展开
|
||||
<#assign subManyIndex = 0>
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
${sub.entityName?uncap_first}List: allValues.tablesValue[${subManyIndex}].tableData,
|
||||
<#assign subManyIndex = subManyIndex+1>
|
||||
<#else>
|
||||
${sub.entityName?uncap_first}List: ${sub.entityName?uncap_first}Form.value.getFormData(),
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
}
|
||||
<#if hasOne2One==true>
|
||||
//校验所有一对一子表表单
|
||||
function validateSubForm(allValues){
|
||||
return new Promise((resolve,reject)=>{
|
||||
Promise.all([
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
${sub.entityName?uncap_first}Form.value.validateForm(${sub_index}),
|
||||
</#if>
|
||||
</#list>
|
||||
]).then(() => {
|
||||
resolve(allValues)
|
||||
}).catch(e => {
|
||||
if (e.error === VALIDATE_FAILED) {
|
||||
// 如果有未通过表单验证的子表,就自动跳转到它所在的tab
|
||||
activeKey.value = e.index == null ? unref(activeKey) : refKeys.value[e.index]
|
||||
} else {
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
</#if>
|
||||
//表单提交事件
|
||||
async function requestAddOrEdit(values) {
|
||||
try {
|
||||
setModalProps({confirmLoading: true});
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({confirmLoading: false});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,64 @@
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType=='1'>
|
||||
#segment#${sub.entityName}Form.vue
|
||||
<template>
|
||||
<BasicForm @register="registerForm"/>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue';
|
||||
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||
import {${sub.entityName?uncap_first}FormSchema} from '../${entityName?uncap_first}.data';
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
|
||||
|
||||
export default defineComponent({
|
||||
name:"${sub.entityName}Form",
|
||||
components: {BasicForm},
|
||||
emits:['register'],
|
||||
setup(_,{emit}) {
|
||||
const [registerForm, {resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: ${sub.entityName?uncap_first}FormSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
/**
|
||||
*初始化加载数据
|
||||
*/
|
||||
function initFormData(url,id){
|
||||
if(id){
|
||||
defHttp.get({url,params:{id}},{isTransformResponse:false}).then(res=>{
|
||||
res.success && setFieldsValue({...res.result[0]});
|
||||
})
|
||||
}
|
||||
}
|
||||
/**
|
||||
*获取表单数据
|
||||
*/
|
||||
function getFormData(){
|
||||
return [getFieldsValue()];
|
||||
}
|
||||
/**
|
||||
*表单校验
|
||||
*/
|
||||
function validateForm(index){
|
||||
return new Promise((resolve, reject) => {
|
||||
// 验证子表表单
|
||||
validate().then(()=>{
|
||||
return resolve()
|
||||
}).catch(()=> {
|
||||
return reject({ error: VALIDATE_FAILED ,index})
|
||||
})
|
||||
})
|
||||
}
|
||||
return {
|
||||
registerForm,
|
||||
resetFields,
|
||||
initFormData,
|
||||
getFormData,
|
||||
validateForm
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</#if>
|
||||
</#list>
|
||||
@ -110,7 +110,7 @@ public class ${entityName}Controller {
|
||||
*/
|
||||
@AutoLog(value = "${tableVo.ftlDescription}-编辑")
|
||||
@ApiOperation(value="${tableVo.ftlDescription}-编辑", notes="${tableVo.ftlDescription}-编辑")
|
||||
@PutMapping(value = "/edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) {
|
||||
${entityName} ${entityName?uncap_first} = new ${entityName}();
|
||||
BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first});
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
<a-tabs v-model="activeKey" @change="handleChangeTabs">
|
||||
<!--主表区域 -->
|
||||
<a-tab-pane tab="${tableVo.ftlDescription}" :key="refKeys[0]" :forceRender="true">
|
||||
<a-tab-pane tab="${tableVo.ftlDescription}" :key="refKeys[0]" :forceRender="true" :class="'jeecg-tabs-top'" :animated="false">
|
||||
<a-form-model ref="form" :model="model" :rules="validatorRules">
|
||||
<a-row>
|
||||
<#list columns as po>
|
||||
@ -19,13 +19,8 @@
|
||||
<#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'>
|
||||
@ -160,20 +155,12 @@ export default {
|
||||
return {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
labelCol2: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 3 },
|
||||
},
|
||||
wrapperCol2: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 20 },
|
||||
},
|
||||
// 新增时子表默认添加几行空数据
|
||||
addDefaultRowNum: 1,
|
||||
model:{
|
||||
@ -516,4 +503,8 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/** tab panel 中有下拉框/日期 这类带下拉效果的,需要加此样式 */
|
||||
/deep/ .jeecg-tabs-top {
|
||||
overflow: visible;
|
||||
}
|
||||
</style>
|
||||
@ -25,13 +25,8 @@
|
||||
<#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 :span="${form_span}">
|
||||
<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%"/>
|
||||
<#elseif po.classType =='datetime'>
|
||||
@ -118,20 +113,12 @@
|
||||
},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
labelCol2: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 3 },
|
||||
},
|
||||
wrapperCol2: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 20 },
|
||||
},
|
||||
<#include "/common/validatorRulesTemplate/sub.ftl">
|
||||
confirmLoading: false,
|
||||
}
|
||||
|
||||
@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<div>
|
||||
<#assign list_need_category=false>
|
||||
<#assign list_need_pca=false>
|
||||
<#assign bpm_flag=false>
|
||||
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#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>
|
||||
<#-- 结束循环 -->
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<a-dropdown v-if="checkedKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button>批量操作
|
||||
<Icon icon="mdi:chevron-down"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{text}">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<template #fileSlot="{text}">
|
||||
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup>
|
||||
import {ref, computed, unref} from 'vue';
|
||||
import {BasicTable, useTable, TableAction} from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage'
|
||||
import {useModal} from '/@/components/Modal';
|
||||
import ${entityName}Modal from './components/${entityName}Modal.vue'
|
||||
import {columns, searchFormSchema} from './${entityName?uncap_first}.data';
|
||||
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName?uncap_first}.api';
|
||||
<#if list_need_category>
|
||||
import { loadCategoryData } from '/@/api/common/api'
|
||||
import { getAuthCache, setAuthCache } from '/@/utils/auth';
|
||||
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
|
||||
</#if>
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
//注册model
|
||||
const [registerModal, {openModal}] = useModal();
|
||||
//注册table数据
|
||||
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
|
||||
tableProps:{
|
||||
title: '${tableVo.ftlDescription}',
|
||||
api: list,
|
||||
columns,
|
||||
canResize:false,
|
||||
formConfig: {
|
||||
labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter:true,
|
||||
showAdvancedButton:true,
|
||||
fieldMapToTime: [
|
||||
<#list columns as po>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#if po.queryMode!='single'>
|
||||
<#if po.classType=='date'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD'],
|
||||
<#elseif po.classType=='datetime'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD HH:mm:ss'],
|
||||
</#if>
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name:"${tableVo.ftlDescription}",
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl
|
||||
},
|
||||
})
|
||||
|
||||
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({id: record.id}, reload);
|
||||
}
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
await batchDelete({ids: checkedKeys.value}, reload);
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record){
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
}
|
||||
]
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record){
|
||||
return [
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
}, {
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
<#if list_need_category>
|
||||
/**
|
||||
* 初始化字典配置
|
||||
*/
|
||||
function initDictConfig(){
|
||||
<#list columns as po>
|
||||
<#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>
|
||||
<#if po.classType=='cat_tree' && list_need_category==true>
|
||||
loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => {
|
||||
if (res) {
|
||||
let allDictDate = getAuthCache(DB_DICT_DATA_KEY);
|
||||
if(!allDictDate['${po.dictField?default("")}']){
|
||||
Object.assign(allDictDate,{'${po.dictField?default("")}':res})
|
||||
}
|
||||
setAuthCache(DB_DICT_DATA_KEY,allDictDate)
|
||||
}
|
||||
})
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
initDictConfig();
|
||||
</#if>
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,72 @@
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
import {Modal} from 'ant-design-vue';
|
||||
|
||||
enum Api {
|
||||
list = '/${entityPackage}/${entityName?uncap_first}/list',
|
||||
save='/${entityPackage}/${entityName?uncap_first}/add',
|
||||
edit='/${entityPackage}/${entityName?uncap_first}/edit',
|
||||
deleteOne = '/${entityPackage}/${entityName?uncap_first}/delete',
|
||||
deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
|
||||
importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
|
||||
exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
|
||||
<#list subTables as sub><#rt/>
|
||||
${sub.entityName?uncap_first}List = '/${entityPackage}/${entityName?uncap_first}/query${sub.entityName}ByMainId',
|
||||
</#list>
|
||||
}
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
<#list subTables as sub><#rt/>
|
||||
/**
|
||||
* 查询子表数据
|
||||
* @param params
|
||||
*/
|
||||
export const ${sub.entityName?uncap_first}List = Api.${sub.entityName?uncap_first}List;
|
||||
</#list>
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) =>
|
||||
defHttp.get({url: Api.list, params});
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params,handleSuccess) => {
|
||||
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({url: url, params});
|
||||
}
|
||||
@ -0,0 +1,700 @@
|
||||
import {BasicColumn} from '/@/components/Table';
|
||||
import {FormSchema} from '/@/components/Table';
|
||||
import { rules} from '/@/utils/helper/validator';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import {JVxeTypes,JVxeColumn} from '/@/components/jeecg/JVxeTable/types'
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
<#list columns as po>
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||
{
|
||||
title: '${po.filedComment}',
|
||||
align:"center",
|
||||
<#if po.sort=='Y'>
|
||||
sorter: true,
|
||||
</#if>
|
||||
<#if po.classType=='date'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:({text}) =>{
|
||||
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||
},
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
dataIndex: '${po.fieldName}String'
|
||||
<#elseif po.classType=='umeditor'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'htmlSlot' },
|
||||
<#elseif po.classType=='pca'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||
<#elseif po.classType=='file'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'fileSlot' },
|
||||
<#elseif po.classType=='image'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:render.renderAvatar,
|
||||
<#elseif po.classType=='switch'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#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>
|
||||
<#assign switch_extend_arr1=a>
|
||||
<#else>
|
||||
<#assign switch_extend_arr2=a>
|
||||
</#if>
|
||||
</#list>
|
||||
customRender:({text}) => {
|
||||
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||
},
|
||||
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||
dataIndex: '${po.fieldName}_dictText'
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#if po.dictText?default("")?trim?length == 0>
|
||||
customRender:({text}) => {
|
||||
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||
},
|
||||
<#else>
|
||||
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||
</#if>
|
||||
<#else>
|
||||
dataIndex: '${po.fieldName}'
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#assign query_flag=true>
|
||||
<#assign query_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictField}">
|
||||
</#if>
|
||||
<#if po.queryMode=='single'>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
},
|
||||
<#elseif po.classType=='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
<#elseif po.classType=='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType=='list_multi'>
|
||||
component: 'JMultiSelectTag',//暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"query_field_dictCode?default("")"
|
||||
},
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题
|
||||
},
|
||||
<#elseif po.classType=='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.classType=='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType=='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:"${po.dictField}",
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
},
|
||||
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
<#else>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='date'>
|
||||
component: 'RangePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#else>
|
||||
component: 'Input', //TODO 范围查询
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
<#-- 结束循环 -->
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list columns as po><#rt/>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#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>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#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'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#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}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//子表单数据
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list sub.colums as po><#rt/>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#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>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#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'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#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}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
</#if>
|
||||
</#list>
|
||||
//子表表格配置
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
|
||||
<#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: JVxeTypes.date,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='datetime'>
|
||||
type: JVxeTypes.datetime,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='textarea'>
|
||||
type: JVxeTypes.textarea,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif "int,decimal,double,"?contains(col.classType)>
|
||||
type: JVxeTypes.inputNumber,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='list' || col.classType =='radio'>
|
||||
type: JVxeTypes.select,
|
||||
options:[],
|
||||
<#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: JVxeTypes.selectMultiple,
|
||||
options:[],
|
||||
<#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: JVxeTypes.selectSearch,
|
||||
<#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: JVxeTypes.image,
|
||||
token:true,
|
||||
responseName:"message",
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#if col.uploadnum??>
|
||||
number: ${col.uploadnum},
|
||||
</#if>
|
||||
<#elseif col.classType =='file'>
|
||||
type: JVxeTypes.file,
|
||||
token:true,
|
||||
responseName:"message",
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#if col.uploadnum??>
|
||||
number: ${col.uploadnum},
|
||||
</#if>
|
||||
<#elseif col.classType =='switch'>
|
||||
type: JVxeTypes.checkbox,
|
||||
<#if col.dictField == 'is_open'>
|
||||
customValue: ['Y', 'N'],
|
||||
<#else>
|
||||
customValue: ${col.dictField},
|
||||
</#if>
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='popup'>
|
||||
<#if popupBackFields?length gt 0>
|
||||
<#assign popupBackFields = "${popupBackFields}"+","+"${col.dictText}">
|
||||
<#else>
|
||||
<#assign popupBackFields = "${col.dictText}">
|
||||
</#if>
|
||||
type: JVxeTypes.popup,
|
||||
popupCode:"${col.dictTable}",
|
||||
field:"${col.dictField}",
|
||||
orgFields:"${col.dictField}",
|
||||
destFields:"${Format.underlineToHump(col.dictText)}",
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#else>
|
||||
type: JVxeTypes.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>
|
||||
<#-- 循环子表的列 结束 -->
|
||||
]
|
||||
</#if>
|
||||
</#list>
|
||||
@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
|
||||
<!-- 子表单区域 -->
|
||||
<a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs">
|
||||
<!--主表区域 -->
|
||||
<a-tab-pane tab="${tableVo.ftlDescription}" :key="refKeys[0]" :forceRender="true">
|
||||
<BasicForm @register="registerForm" ref="formRef"/>
|
||||
</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">
|
||||
<${sub.entityName}Form ref="${sub.entityName?uncap_first}Form"></${sub.entityName}Form>
|
||||
</a-tab-pane>
|
||||
|
||||
<#else>
|
||||
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index+1}]" :forceRender="true">
|
||||
<JVxeTable
|
||||
keep-source
|
||||
resizable
|
||||
: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"
|
||||
:toolbar="true"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</#if>
|
||||
</#list>
|
||||
</a-tabs>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, unref,reactive} from 'vue';
|
||||
import {BasicModal, useModalInner} from '/@/components/Modal';
|
||||
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||
import { JVxeTable } from '/@/components/jeecg/JVxeTable'
|
||||
import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts'
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
import ${sub.entityName}Form from './${sub.entityName}Form.vue'
|
||||
</#if>
|
||||
</#list>
|
||||
import {formSchema<#list subTables as sub><#if sub.foreignRelationType =='0'>,${sub.entityName?uncap_first}Columns</#if></#list>} from '../${entityName?uncap_first}.data';
|
||||
import {saveOrUpdate<#list subTables as sub>,${sub.entityName?uncap_first}List</#list>} from '../${entityName?uncap_first}.api';
|
||||
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register','success']);
|
||||
const isUpdate = ref(true);
|
||||
const refKeys = ref(['${tableVo.entityName?uncap_first}',<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]);
|
||||
<#assign hasOne2Many = false>
|
||||
<#assign hasOne2One = false>
|
||||
const activeKey = ref('${tableVo.entityName?uncap_first}');
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
<#assign hasOne2Many = true>
|
||||
const ${sub.entityName?uncap_first} = ref();
|
||||
</#if>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
<#assign hasOne2One = true>
|
||||
const ${sub.entityName?uncap_first}Form = ref();
|
||||
</#if>
|
||||
</#list>
|
||||
const tableRefs = {<#list subTables as sub><#if sub.foreignRelationType =='0'>${sub.entityName?uncap_first}, <#assign hasOne2Many = true></#if></#list>};
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
const ${sub.entityName?uncap_first}Table = reactive({
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns:${sub.entityName?uncap_first}Columns
|
||||
})
|
||||
</#if>
|
||||
</#list>
|
||||
//表单配置
|
||||
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await reset();
|
||||
setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter});
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
${sub.entityName?uncap_first}Form.value.initFormData(${sub.entityName?uncap_first}List,data?.record?.id)
|
||||
</#if>
|
||||
</#list>
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
requestSubTableData(${sub.entityName?uncap_first}List, {id:data?.record?.id}, ${sub.entityName?uncap_first}Table)
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
setProps({ disabled: !data?.showFooter })
|
||||
});
|
||||
//方法配置
|
||||
const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys<#if hasOne2One==true>,validateSubForm</#if>);
|
||||
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
|
||||
async function reset(){
|
||||
await resetFields();
|
||||
activeKey.value = ref('${tableVo.entityName?uncap_first}');
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
${sub.entityName?uncap_first}Table.dataSource = [];
|
||||
</#if>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
${sub.entityName?uncap_first}Form.value.resetFields();
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
function classifyIntoFormData(allValues) {
|
||||
let main = Object.assign({}, allValues.formValue)
|
||||
return {
|
||||
...main, // 展开
|
||||
<#assign subManyIndex = 0>
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
${sub.entityName?uncap_first}List: allValues.tablesValue[${subManyIndex}].tableData,
|
||||
<#assign subManyIndex = subManyIndex+1>
|
||||
<#else>
|
||||
${sub.entityName?uncap_first}List: ${sub.entityName?uncap_first}Form.value.getFormData(),
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
}
|
||||
<#if hasOne2One==true>
|
||||
//校验所有一对一子表表单
|
||||
function validateSubForm(allValues){
|
||||
return new Promise((resolve,reject)=>{
|
||||
Promise.all([
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
${sub.entityName?uncap_first}Form.value.validateForm(${sub_index+1}),
|
||||
</#if>
|
||||
</#list>
|
||||
]).then(() => {
|
||||
resolve(allValues)
|
||||
}).catch(e => {
|
||||
if (e.error === VALIDATE_FAILED) {
|
||||
// 如果有未通过表单验证的子表,就自动跳转到它所在的tab
|
||||
activeKey.value = e.index == null ? unref(activeKey) : refKeys.value[e.index]
|
||||
} else {
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
</#if>
|
||||
//表单提交事件
|
||||
async function requestAddOrEdit(values) {
|
||||
try {
|
||||
setModalProps({confirmLoading: true});
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({confirmLoading: false});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,64 @@
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType=='1'>
|
||||
#segment#${sub.entityName}Form.vue
|
||||
<template>
|
||||
<BasicForm @register="registerForm"/>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue';
|
||||
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||
import {${sub.entityName?uncap_first}FormSchema} from '../${entityName?uncap_first}.data';
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
|
||||
|
||||
export default defineComponent({
|
||||
name:"${sub.entityName}Form",
|
||||
components: {BasicForm},
|
||||
emits:['register'],
|
||||
setup(_,{emit}) {
|
||||
const [registerForm, {resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: ${sub.entityName?uncap_first}FormSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
/**
|
||||
*初始化加载数据
|
||||
*/
|
||||
function initFormData(url,id){
|
||||
if(id){
|
||||
defHttp.get({url,params:{id}},{isTransformResponse:false}).then(res=>{
|
||||
res.success && setFieldsValue({...res.result[0]});
|
||||
})
|
||||
}
|
||||
}
|
||||
/**
|
||||
*获取表单数据
|
||||
*/
|
||||
function getFormData(){
|
||||
return [getFieldsValue()];
|
||||
}
|
||||
/**
|
||||
*表单校验
|
||||
*/
|
||||
function validateForm(index){
|
||||
return new Promise((resolve, reject) => {
|
||||
// 验证子表表单
|
||||
validate().then(()=>{
|
||||
return resolve()
|
||||
}).catch(()=> {
|
||||
return reject({ error: VALIDATE_FAILED ,index})
|
||||
})
|
||||
})
|
||||
}
|
||||
return {
|
||||
registerForm,
|
||||
resetFields,
|
||||
initFormData,
|
||||
getFormData,
|
||||
validateForm
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</#if>
|
||||
</#list>
|
||||
@ -93,7 +93,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
|
||||
*/
|
||||
@AutoLog(value = "${tableVo.ftlDescription}-编辑")
|
||||
@ApiOperation(value="${tableVo.ftlDescription}-编辑", notes="${tableVo.ftlDescription}-编辑")
|
||||
@PutMapping(value = "/edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
|
||||
${entityName?uncap_first}Service.updateById(${entityName?uncap_first});
|
||||
return Result.OK("编辑成功!");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user