mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2026-01-24 03:56:53 +08:00
Compare commits
23 Commits
springboot
...
v3.9.0last
| Author | SHA1 | Date | |
|---|---|---|---|
| 41877a6e8b | |||
| b7a3da89ca | |||
| de4a8ce652 | |||
| e533af285c | |||
| 23dc7b3f03 | |||
| e57aef0708 | |||
| 42087c0bf8 | |||
| 606edcc82f | |||
| 9082e986f1 | |||
| 40cd525bba | |||
| d6b6cf079e | |||
| 1b688e7cd2 | |||
| 58915a6410 | |||
| b67096dc54 | |||
| 67795493bd | |||
| e1c8f00bf2 | |||
| 17a81e89a5 | |||
| bcbf775756 | |||
| 462365890e | |||
| b686f9fbd1 | |||
| 872f84d006 | |||
| adc191f03e | |||
| f6f2ef6316 |
@ -106,6 +106,10 @@ JeecgBoot平台的AIGC功能模块,是一套类似`Dify`的`AIGC应用开发
|
||||
| ChatGTP | √ |
|
||||
| Qwq | √ |
|
||||
| 智库 | √ |
|
||||
| claude | √ |
|
||||
| vl模型 | √ |
|
||||
| 千帆大模型 | √ |
|
||||
| 通义千问 | √ |
|
||||
| Ollama本地搭建大模型 | √ |
|
||||
| 等等。。 | √ |
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
|
||||
[中文](./README.md) | English
|
||||
|
||||

|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
中文 | [English](./README.en-US.md)
|
||||
|
||||
JeecgBoot AI低代码平台
|
||||
===============
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
JeecgBoot 低代码开发平台
|
||||
===============
|
||||
|
||||
|
||||
@ -3,9 +3,7 @@ package org.jeecg.common.system.util;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.system.annotation.EnumDict;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
@ -13,6 +11,7 @@ import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
@ -183,10 +182,10 @@ public class ResourceUtil {
|
||||
for (DictModel dm : dictItemList) {
|
||||
String value = dm.getValue();
|
||||
if (keySet.contains(value)) {
|
||||
List<DictModel> list = new ArrayList<>();
|
||||
// 修复bug:获取或创建该dictCode对应的list,而不是每次都创建新的list
|
||||
List<DictModel> list = map.computeIfAbsent(code, k -> new ArrayList<>());
|
||||
list.add(new DictModel(value, dm.getText()));
|
||||
map.put(code, list);
|
||||
break;
|
||||
//break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
package org.jeecg.config.sign.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 签名校验注解
|
||||
* 用于方法级别的签名验证,功能等同于yml中的jeecg.signUrls配置
|
||||
* 参考DragSignatureAspect的设计思路,使用AOP切面实现
|
||||
*
|
||||
* @author GitHub Copilot
|
||||
* @since 2025-12-15
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface SignatureCheck {
|
||||
|
||||
/**
|
||||
* 是否启用签名校验
|
||||
* @return true-启用(默认), false-禁用
|
||||
*/
|
||||
boolean enabled() default true;
|
||||
|
||||
/**
|
||||
* 签名校验失败时的错误消息
|
||||
* @return 错误消息
|
||||
*/
|
||||
String errorMessage() default "Sign签名校验失败!";
|
||||
|
||||
}
|
||||
@ -0,0 +1,93 @@
|
||||
package org.jeecg.config.sign.aspect;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.jeecg.config.sign.annotation.SignatureCheck;
|
||||
import org.jeecg.config.sign.interceptor.SignAuthInterceptor;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 基于AOP的签名验证切面
|
||||
* 复用SignAuthInterceptor的成熟签名验证逻辑
|
||||
*
|
||||
* @author GitHub Copilot
|
||||
* @since 2025-12-15
|
||||
*/
|
||||
@Aspect
|
||||
@Slf4j
|
||||
@Component("signatureCheckAspect")
|
||||
public class SignatureCheckAspect {
|
||||
|
||||
/**
|
||||
* 复用SignAuthInterceptor的签名验证逻辑
|
||||
*/
|
||||
private final SignAuthInterceptor signAuthInterceptor = new SignAuthInterceptor();
|
||||
|
||||
/**
|
||||
* 验签切点:拦截所有标记了@SignatureCheck注解的方法
|
||||
*/
|
||||
@Pointcut("@annotation(org.jeecg.config.sign.annotation.SignatureCheck)")
|
||||
private void signatureCheckPointCut() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始验签
|
||||
*/
|
||||
@Before("signatureCheckPointCut()")
|
||||
public void doSignatureValidation(JoinPoint point) throws Exception {
|
||||
// 获取方法上的注解
|
||||
MethodSignature signature = (MethodSignature) point.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
SignatureCheck signatureCheck = method.getAnnotation(SignatureCheck.class);
|
||||
|
||||
log.info("AOP签名验证: {}.{}", method.getDeclaringClass().getSimpleName(), method.getName());
|
||||
|
||||
// 如果注解被禁用,直接返回
|
||||
if (!signatureCheck.enabled()) {
|
||||
log.info("签名验证已禁用,跳过");
|
||||
return;
|
||||
}
|
||||
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
if (attributes == null) {
|
||||
log.error("无法获取请求上下文");
|
||||
throw new IllegalArgumentException("无法获取请求上下文");
|
||||
}
|
||||
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
log.info("X-SIGN: {}, X-TIMESTAMP: {}", request.getHeader("X-SIGN"), request.getHeader("X-TIMESTAMP"));
|
||||
|
||||
try {
|
||||
// 直接调用SignAuthInterceptor的验证逻辑
|
||||
signAuthInterceptor.validateSignature(request);
|
||||
log.info("AOP签名验证通过");
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
// 使用注解中配置的错误消息,或者保留原始错误消息
|
||||
String errorMessage = signatureCheck.errorMessage();
|
||||
log.error("AOP签名验证失败: {}", e.getMessage());
|
||||
|
||||
if ("Sign签名校验失败!".equals(errorMessage)) {
|
||||
// 如果是默认错误消息,使用原始的详细错误信息
|
||||
throw e;
|
||||
} else {
|
||||
// 如果是自定义错误消息,使用自定义消息
|
||||
throw new IllegalArgumentException(errorMessage, e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 包装其他异常
|
||||
String errorMessage = signatureCheck.errorMessage();
|
||||
log.error("AOP签名验证异常: {}", e.getMessage());
|
||||
throw new IllegalArgumentException(errorMessage, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,10 @@
|
||||
package org.jeecg.config.sign.interceptor;
|
||||
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.SortedMap;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
@ -16,9 +14,8 @@ import org.jeecg.config.sign.util.HttpUtils;
|
||||
import org.jeecg.config.sign.util.SignUtil;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.SortedMap;
|
||||
|
||||
/**
|
||||
* 签名拦截器
|
||||
@ -33,63 +30,94 @@ public class SignAuthInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
log.debug("Sign Interceptor request URI = " + request.getRequestURI());
|
||||
HttpServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
|
||||
//获取全部参数(包括URL和body上的)
|
||||
SortedMap<String, String> allParams = HttpUtils.getAllParams(requestWrapper);
|
||||
//对参数进行签名验证
|
||||
String headerSign = request.getHeader(CommonConstant.X_SIGN);
|
||||
String xTimestamp = request.getHeader(CommonConstant.X_TIMESTAMP);
|
||||
log.info("签名拦截器 Interceptor request URI = " + request.getRequestURI());
|
||||
|
||||
if(oConvertUtils.isEmpty(xTimestamp)){
|
||||
Result<?> result = Result.error("Sign签名校验失败,时间戳为空!");
|
||||
log.error("Sign 签名校验失败!Header xTimestamp 为空");
|
||||
//校验失败返回前端
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("application/json; charset=utf-8");
|
||||
PrintWriter out = response.getWriter();
|
||||
out.print(JSON.toJSON(result));
|
||||
return false;
|
||||
}
|
||||
|
||||
//客户端时间
|
||||
Long clientTimestamp = Long.parseLong(xTimestamp);
|
||||
|
||||
int length = 14;
|
||||
int length1000 = 1000;
|
||||
//1.校验签名时间(兼容X_TIMESTAMP的新老格式)
|
||||
if (xTimestamp.length() == length) {
|
||||
//a. X_TIMESTAMP格式是 yyyyMMddHHmmss (例子:20220308152143)
|
||||
if ((DateUtils.getCurrentTimestamp() - clientTimestamp) > MAX_EXPIRE) {
|
||||
log.error("签名验证失败:X-TIMESTAMP已过期,注意系统时间和服务器时间是否有误差!");
|
||||
throw new IllegalArgumentException("签名验证失败:X-TIMESTAMP已过期");
|
||||
}
|
||||
} else {
|
||||
//b. X_TIMESTAMP格式是 时间戳 (例子:1646552406000)
|
||||
if ((System.currentTimeMillis() - clientTimestamp) > (MAX_EXPIRE * length1000)) {
|
||||
log.error("签名验证失败:X-TIMESTAMP已过期,注意系统时间和服务器时间是否有误差!");
|
||||
throw new IllegalArgumentException("签名验证失败:X-TIMESTAMP已过期");
|
||||
}
|
||||
}
|
||||
|
||||
//2.校验签名
|
||||
boolean isSigned = SignUtil.verifySign(allParams,headerSign);
|
||||
|
||||
if (isSigned) {
|
||||
log.debug("Sign 签名通过!Header Sign : {}",headerSign);
|
||||
try {
|
||||
// 调用验证逻辑
|
||||
validateSignature(request);
|
||||
return true;
|
||||
} else {
|
||||
log.debug("sign allParams: {}", allParams);
|
||||
log.error("request URI = " + request.getRequestURI());
|
||||
log.error("Sign 签名校验失败!Header Sign : {}",headerSign);
|
||||
//校验失败返回前端
|
||||
} catch (IllegalArgumentException e) {
|
||||
// 验证失败,返回错误响应
|
||||
log.error("Sign 签名校验失败!{}", e.getMessage());
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("application/json; charset=utf-8");
|
||||
PrintWriter out = response.getWriter();
|
||||
Result<?> result = Result.error("Sign签名校验失败!");
|
||||
Result<?> result = Result.error(e.getMessage());
|
||||
out.print(JSON.toJSON(result));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 签名验证核心逻辑
|
||||
* 提取出来供AOP切面复用
|
||||
* @param request HTTP请求
|
||||
* @throws IllegalArgumentException 验证失败时抛出异常
|
||||
*/
|
||||
public void validateSignature(HttpServletRequest request) throws IllegalArgumentException {
|
||||
try {
|
||||
log.debug("开始签名验证: {} {}", request.getMethod(), request.getRequestURI());
|
||||
|
||||
HttpServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
|
||||
//获取全部参数(包括URL和body上的)
|
||||
SortedMap<String, String> allParams = HttpUtils.getAllParams(requestWrapper);
|
||||
log.debug("提取参数: {}", allParams);
|
||||
|
||||
//对参数进行签名验证
|
||||
String headerSign = request.getHeader(CommonConstant.X_SIGN);
|
||||
String xTimestamp = request.getHeader(CommonConstant.X_TIMESTAMP);
|
||||
|
||||
if(oConvertUtils.isEmpty(xTimestamp)){
|
||||
log.error("Sign签名校验失败,时间戳为空!");
|
||||
throw new IllegalArgumentException("Sign签名校验失败,请求参数不完整!");
|
||||
}
|
||||
|
||||
//客户端时间
|
||||
Long clientTimestamp = Long.parseLong(xTimestamp);
|
||||
|
||||
int length = 14;
|
||||
int length1000 = 1000;
|
||||
//1.校验签名时间(兼容X_TIMESTAMP的新老格式)
|
||||
if (xTimestamp.length() == length) {
|
||||
//a. X_TIMESTAMP格式是 yyyyMMddHHmmss (例子:20220308152143)
|
||||
long currentTimestamp = DateUtils.getCurrentTimestamp();
|
||||
long timeDiff = currentTimestamp - clientTimestamp;
|
||||
log.debug("时间戳验证(yyyyMMddHHmmss): 时间差{}秒", timeDiff);
|
||||
|
||||
if (timeDiff > MAX_EXPIRE) {
|
||||
log.error("时间戳已过期: {}秒 > {}秒", timeDiff, MAX_EXPIRE);
|
||||
throw new IllegalArgumentException("签名验证失败,请求时效性验证失败!");
|
||||
}
|
||||
} else {
|
||||
//b. X_TIMESTAMP格式是 时间戳 (例子:1646552406000)
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long timeDiff = currentTime - clientTimestamp;
|
||||
long maxExpireMs = MAX_EXPIRE * length1000;
|
||||
log.debug("时间戳验证(Unix): 时间差{}ms", timeDiff);
|
||||
|
||||
if (timeDiff > maxExpireMs) {
|
||||
log.error("时间戳已过期: {}ms > {}ms", timeDiff, maxExpireMs);
|
||||
throw new IllegalArgumentException("签名验证失败,请求时效性验证失败!");
|
||||
}
|
||||
}
|
||||
|
||||
//2.校验签名
|
||||
boolean isSigned = SignUtil.verifySign(allParams,headerSign);
|
||||
|
||||
if (isSigned) {
|
||||
log.debug("签名验证通过");
|
||||
} else {
|
||||
log.error("签名验证失败, 参数: {}", allParams);
|
||||
throw new IllegalArgumentException("Sign签名校验失败!");
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// 重新抛出签名验证异常
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
// 包装其他异常(如IOException)
|
||||
log.error("签名验证异常: {}", e.getMessage());
|
||||
throw new IllegalArgumentException("Sign签名校验失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import org.jeecg.common.util.PasswordUtil;
|
||||
import org.jeecg.common.util.TokenUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.config.sign.annotation.SignatureCheck;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.jeecg.modules.system.entity.*;
|
||||
import org.jeecg.modules.system.service.ISysTenantPackService;
|
||||
@ -260,6 +261,7 @@ public class SysTenantController {
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@SignatureCheck
|
||||
@RequestMapping(value = "/queryById", method = RequestMethod.GET)
|
||||
public Result<SysTenant> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
Result<SysTenant> result = new Result<SysTenant>();
|
||||
@ -507,26 +509,26 @@ public class SysTenantController {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加入租户通过门牌号【低代码应用专用接口】
|
||||
* @param sysTenant
|
||||
*/
|
||||
@PostMapping("/joinTenantByHouseNumber")
|
||||
public Result<Integer> joinTenantByHouseNumber(@RequestBody SysTenant sysTenant){
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
Integer tenantId = sysTenantService.joinTenantByHouseNumber(sysTenant, sysUser.getId());
|
||||
Result<Integer> result = new Result<>();
|
||||
if(tenantId != 0){
|
||||
result.setMessage("申请加入组织成功");
|
||||
result.setSuccess(true);
|
||||
result.setResult(tenantId);
|
||||
return result;
|
||||
}else{
|
||||
result.setMessage("该门牌号不存在");
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * 加入租户通过门牌号【低代码应用专用接口】
|
||||
// * @param sysTenant
|
||||
// */
|
||||
// @PostMapping("/joinTenantByHouseNumber")
|
||||
// public Result<Integer> joinTenantByHouseNumber(@RequestBody SysTenant sysTenant){
|
||||
// LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
// Integer tenantId = sysTenantService.joinTenantByHouseNumber(sysTenant, sysUser.getId());
|
||||
// Result<Integer> result = new Result<>();
|
||||
// if(tenantId != 0){
|
||||
// result.setMessage("申请加入组织成功");
|
||||
// result.setSuccess(true);
|
||||
// result.setResult(tenantId);
|
||||
// return result;
|
||||
// }else{
|
||||
// result.setMessage("该门牌号不存在");
|
||||
// result.setSuccess(false);
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 分页获取租户用户数据(vue3用户租户页面)【低代码应用专用接口】
|
||||
@ -713,6 +715,7 @@ public class SysTenantController {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/invitationUser")
|
||||
@RequiresPermissions("system:tenant:invitation:user")
|
||||
public Result<String> invitationUser(@RequestParam(name="phone") String phone,
|
||||
@RequestParam(name="departId",defaultValue = "") String departId){
|
||||
return sysTenantService.invitationUser(phone,departId);
|
||||
@ -911,43 +914,43 @@ public class SysTenantController {
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同意或拒绝加入租户
|
||||
*/
|
||||
@PutMapping("/agreeOrRefuseJoinTenant")
|
||||
public Result<String> agreeOrRefuseJoinTenant(@RequestParam("tenantId") Integer tenantId,
|
||||
@RequestParam("status") String status){
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
String userId = sysUser.getId();
|
||||
SysTenant tenant = sysTenantService.getById(tenantId);
|
||||
if(null == tenant){
|
||||
return Result.error("不存在该组织");
|
||||
}
|
||||
SysUserTenant sysUserTenant = relationService.getUserTenantByTenantId(userId, tenantId);
|
||||
if (null == sysUserTenant) {
|
||||
return Result.error("该用户不存在该组织中,无权修改");
|
||||
}
|
||||
String content = "";
|
||||
SysUser user = new SysUser();
|
||||
user.setUsername(sysUserTenant.getCreateBy());
|
||||
String realname = oConvertUtils.getString(sysUser.getRealname(),sysUser.getUsername());
|
||||
//成功加入
|
||||
if(CommonConstant.USER_TENANT_NORMAL.equals(status)){
|
||||
//修改租户状态
|
||||
relationService.agreeJoinTenant(userId,tenantId);
|
||||
content = content + realname + "已同意您发送的加入 " + tenant.getName() + " 的邀请";
|
||||
sysTenantService.sendMsgForAgreeAndRefuseJoin(user, content);
|
||||
return Result.OK("您已同意该组织的邀请");
|
||||
}else if(CommonConstant.USER_TENANT_REFUSE.equals(status)){
|
||||
//直接删除关系表即可
|
||||
relationService.refuseJoinTenant(userId,tenantId);
|
||||
content = content + realname + "拒绝了您发送的加入 " + tenant.getName() + " 的邀请";
|
||||
sysTenantService.sendMsgForAgreeAndRefuseJoin(user, content);
|
||||
return Result.OK("您已成功拒绝该组织的邀请");
|
||||
}
|
||||
return Result.error("类型不匹配,禁止修改数据");
|
||||
}
|
||||
// /**
|
||||
// * 同意或拒绝加入租户
|
||||
// */
|
||||
// @PutMapping("/agreeOrRefuseJoinTenant")
|
||||
// public Result<String> agreeOrRefuseJoinTenant(@RequestParam("tenantId") Integer tenantId,
|
||||
// @RequestParam("status") String status){
|
||||
// //是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
// LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
// String userId = sysUser.getId();
|
||||
// SysTenant tenant = sysTenantService.getById(tenantId);
|
||||
// if(null == tenant){
|
||||
// return Result.error("不存在该组织");
|
||||
// }
|
||||
// SysUserTenant sysUserTenant = relationService.getUserTenantByTenantId(userId, tenantId);
|
||||
// if (null == sysUserTenant) {
|
||||
// return Result.error("该用户不存在该组织中,无权修改");
|
||||
// }
|
||||
// String content = "";
|
||||
// SysUser user = new SysUser();
|
||||
// user.setUsername(sysUserTenant.getCreateBy());
|
||||
// String realname = oConvertUtils.getString(sysUser.getRealname(),sysUser.getUsername());
|
||||
// //成功加入
|
||||
// if(CommonConstant.USER_TENANT_NORMAL.equals(status)){
|
||||
// //修改租户状态
|
||||
// relationService.agreeJoinTenant(userId,tenantId);
|
||||
// content = content + realname + "已同意您发送的加入 " + tenant.getName() + " 的邀请";
|
||||
// sysTenantService.sendMsgForAgreeAndRefuseJoin(user, content);
|
||||
// return Result.OK("您已同意该组织的邀请");
|
||||
// }else if(CommonConstant.USER_TENANT_REFUSE.equals(status)){
|
||||
// //直接删除关系表即可
|
||||
// relationService.refuseJoinTenant(userId,tenantId);
|
||||
// content = content + realname + "拒绝了您发送的加入 " + tenant.getName() + " 的邀请";
|
||||
// sysTenantService.sendMsgForAgreeAndRefuseJoin(user, content);
|
||||
// return Result.OK("您已成功拒绝该组织的邀请");
|
||||
// }
|
||||
// return Result.error("类型不匹配,禁止修改数据");
|
||||
// }
|
||||
|
||||
/**
|
||||
* 目前只给敲敲云租户下删除用户使用
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
@ -20,7 +22,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@ -48,6 +49,7 @@ public class SysUserOnlineController {
|
||||
@Resource
|
||||
private BaseCommonService baseCommonService;
|
||||
|
||||
@RequiresPermissions("system:online:list")
|
||||
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
||||
public Result<Page<SysUserOnlineVO>> list(@RequestParam(name="username", required=false) String username,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
|
||||
@ -100,6 +102,7 @@ public class SysUserOnlineController {
|
||||
/**
|
||||
* 强退用户
|
||||
*/
|
||||
@RequiresPermissions("system:online:forceLogout")
|
||||
@RequestMapping(value = "/forceLogout",method = RequestMethod.POST)
|
||||
public Result<Object> forceLogout(@RequestBody SysUserOnlineVO online) {
|
||||
//用户退出逻辑
|
||||
|
||||
@ -371,11 +371,19 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
if (isCustomDataSource) {
|
||||
DynamicDataSourceContextHolder.push(dataSource);
|
||||
}
|
||||
List<DictModel> restData = sysDictMapper.queryTableDictByKeysAndFilterSql(table, text, code, filterSql, codeValues);
|
||||
// 清理自定义的数据源
|
||||
if (isCustomDataSource) {
|
||||
DynamicDataSourceContextHolder.clear();
|
||||
//update-begin---author:jarysun ---date:20251020 for:[issues/#9002]解决表字典查询出现异常之后,数据源不能恢复问题------------
|
||||
List<DictModel> restData = null;
|
||||
|
||||
try {
|
||||
restData = sysDictMapper.queryTableDictByKeysAndFilterSql(table, text, code, filterSql, codeValues);
|
||||
} finally {
|
||||
// 清理自定义的数据源
|
||||
if (isCustomDataSource) {
|
||||
DynamicDataSourceContextHolder.clear();
|
||||
}
|
||||
}
|
||||
//update-end---author:jarysun ---date:20251020 for:[issues/#9002]解决表字典查询出现异常之后,数据源不能恢复问题------------
|
||||
|
||||
return restData;
|
||||
}
|
||||
|
||||
|
||||
@ -229,7 +229,7 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
LambdaQueryWrapper<SysDepart> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// 根据 source_identifier 字段查询
|
||||
// 代码逻辑说明: 【issues/6017】钉钉同步部门时没有最顶层的部门名,同步用户时,用户没有部门信息---
|
||||
queryWrapper.and(item -> item.eq(SysDepart::getId, departmentTree.getSource_identifier()).or().eq(SysDepart::getDingIdentifier,departmentTree.getDept_id()));
|
||||
queryWrapper.and(item -> item.eq(SysDepart::getId, departmentTree.getSource_identifier()).or().eq(SysDepart::getDingIdentifier,oConvertUtils.getString(departmentTree.getDept_id())));
|
||||
SysDepart sysDepart = sysDepartService.getOne(queryWrapper);
|
||||
if (sysDepart != null) {
|
||||
// 执行更新操作
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<div>
|
||||
<#assign list_need_category=false>
|
||||
<#assign list_need_pca=false>
|
||||
@ -33,7 +33,7 @@
|
||||
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'button'>
|
||||
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
|
||||
</#if>
|
||||
@ -303,7 +303,7 @@
|
||||
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -339,7 +339,7 @@
|
||||
auth: '${entityPackage}:${tableName}:delete'
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -378,7 +378,7 @@
|
||||
</#if>
|
||||
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='button'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -355,13 +355,19 @@ export const formSchema: FormSchema[] = [
|
||||
<#elseif po.classType=='list'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
dictCode:"${form_field_dictCode}",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}",
|
||||
type: "radio"
|
||||
type: "radio",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||
<#elseif po.classType=='list_multi'>
|
||||
|
||||
@ -108,7 +108,7 @@
|
||||
};
|
||||
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='form'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<#include "/common/utils.ftl">
|
||||
<#include "/common/utils.ftl">
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<#assign query_field_no=0>
|
||||
@ -110,7 +110,7 @@
|
||||
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'button'>
|
||||
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
|
||||
</#if>
|
||||
@ -368,7 +368,7 @@
|
||||
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -404,7 +404,7 @@
|
||||
auth: '${entityPackage}:${tableName}:delete'
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -484,7 +484,7 @@
|
||||
</#if>
|
||||
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='button'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -78,7 +78,7 @@
|
||||
visible.value = false;
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='form'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<#include "/common/utils.ftl">
|
||||
<#include "/common/utils.ftl">
|
||||
<#assign pidFieldName = "">
|
||||
<#assign hasChildrenField = "">
|
||||
<#assign bpm_flag=false>
|
||||
@ -38,7 +38,7 @@
|
||||
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'button'>
|
||||
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
|
||||
</#if>
|
||||
@ -447,7 +447,7 @@
|
||||
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -483,7 +483,7 @@
|
||||
auth: '${entityPackage}:${tableName}:delete'
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -544,7 +544,7 @@
|
||||
</#if>
|
||||
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='button'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -381,13 +381,19 @@ export const formSchema: FormSchema[] = [
|
||||
<#elseif po.classType=='list'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
dictCode:"${form_field_dictCode}",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}",
|
||||
type: "radio"
|
||||
type: "radio",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||
<#elseif po.classType=='list_multi'>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<#include "/common/utils.ftl">
|
||||
<#include "/common/utils.ftl">
|
||||
<#assign pidFieldName = "">
|
||||
<#assign hasChildrenField = "">
|
||||
<#list originalColumns as po>
|
||||
@ -170,7 +170,7 @@
|
||||
};
|
||||
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='form'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<#include "/common/utils.ftl">
|
||||
<#include "/common/utils.ftl">
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<#assign pidFieldName = "">
|
||||
@ -120,7 +120,7 @@
|
||||
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'button'>
|
||||
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
|
||||
</#if>
|
||||
@ -518,7 +518,7 @@
|
||||
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -559,7 +559,7 @@
|
||||
auth: '${entityPackage}:${tableName}:delete'
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -597,7 +597,7 @@
|
||||
}
|
||||
</#if>
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='button'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<div class="p-2 cgformErpList">
|
||||
<#assign list_need_category=false>
|
||||
<#assign list_need_pca=false>
|
||||
@ -33,7 +33,7 @@
|
||||
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'button'>
|
||||
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
|
||||
</#if>
|
||||
@ -350,7 +350,7 @@
|
||||
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -385,7 +385,7 @@
|
||||
auth: '${entityPackage}:${tableName}:delete'
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -444,7 +444,7 @@
|
||||
</#if>
|
||||
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='button'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -350,13 +350,19 @@ export const formSchema: FormSchema[] = [
|
||||
<#elseif po.classType=='list'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
dictCode:"${form_field_dictCode}",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}",
|
||||
type: "radio"
|
||||
type: "radio",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||
<#elseif po.classType=='list_multi'>
|
||||
@ -686,7 +692,10 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
dictCode:"${form_field_dictCode}",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||
<#elseif po.classType=='list_multi'>
|
||||
|
||||
@ -107,7 +107,7 @@
|
||||
}
|
||||
};
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='form'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -114,7 +114,7 @@
|
||||
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'button'>
|
||||
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
|
||||
</#if>
|
||||
@ -390,7 +390,7 @@
|
||||
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
|
||||
},
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -427,7 +427,7 @@
|
||||
auth: '${entityPackage}:${tableName}:delete'
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -465,7 +465,7 @@
|
||||
}
|
||||
</#if>
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='button'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -80,7 +80,7 @@
|
||||
}
|
||||
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='form'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<#-- ** 引入全局工具方法 ** -->
|
||||
<#-- ** 引入全局工具方法 ** -->
|
||||
<#include "/common/utils.ftl">
|
||||
<template>
|
||||
<div>
|
||||
@ -45,7 +45,7 @@
|
||||
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'button'>
|
||||
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
|
||||
</#if>
|
||||
@ -355,7 +355,7 @@
|
||||
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -391,7 +391,7 @@
|
||||
auth: '${entityPackage}:${tableName}:delete'
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -450,7 +450,7 @@
|
||||
</#if>
|
||||
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='button'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -351,13 +351,19 @@ export const formSchema: FormSchema[] = [
|
||||
<#elseif po.classType=='list'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
dictCode:"${form_field_dictCode}",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}",
|
||||
type: "radio"
|
||||
type: "radio",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||
<#elseif po.classType=='list_multi'>
|
||||
@ -672,13 +678,19 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
|
||||
<#elseif po.classType=='list'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
dictCode:"${form_field_dictCode}",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}",
|
||||
type: "radio"
|
||||
type: "radio",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||
<#elseif po.classType=='list_multi'>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<#include "/common/utils.ftl">
|
||||
<#include "/common/utils.ftl">
|
||||
<template>
|
||||
<#assign buttonList=[]>
|
||||
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
|
||||
@ -253,7 +253,7 @@
|
||||
</#list>
|
||||
};
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='form'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<div>
|
||||
<#assign list_need_category=false>
|
||||
<#assign list_need_pca=false>
|
||||
@ -32,7 +32,7 @@
|
||||
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'button'>
|
||||
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
|
||||
</#if>
|
||||
@ -330,7 +330,7 @@
|
||||
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -366,7 +366,7 @@
|
||||
auth: '${entityPackage}:${tableName}:delete'
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -425,7 +425,7 @@
|
||||
</#if>
|
||||
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='button'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -351,13 +351,19 @@ export const formSchema: FormSchema[] = [
|
||||
<#elseif po.classType=='list'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
dictCode:"${form_field_dictCode}",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}",
|
||||
type: "radio"
|
||||
type: "radio",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||
<#elseif po.classType=='list_multi'>
|
||||
@ -599,13 +605,19 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
|
||||
<#elseif po.classType=='list'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
dictCode:"${form_field_dictCode}",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}",
|
||||
type: "radio"
|
||||
type: "radio",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||
<#elseif po.classType=='list_multi'>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<#include "/common/utils.ftl">
|
||||
<#include "/common/utils.ftl">
|
||||
<template>
|
||||
<#assign buttonList=[]>
|
||||
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
|
||||
@ -253,7 +253,7 @@
|
||||
</#list>
|
||||
};
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='form'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<#include "/common/utils.ftl">
|
||||
<#include "/common/utils.ftl">
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<#assign query_field_no=0>
|
||||
@ -113,7 +113,7 @@
|
||||
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'button'>
|
||||
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
|
||||
</#if>
|
||||
@ -364,7 +364,7 @@
|
||||
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -401,7 +401,7 @@
|
||||
}
|
||||
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -441,7 +441,7 @@
|
||||
</#if>
|
||||
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='button'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<#include "/common/utils.ftl">
|
||||
<#include "/common/utils.ftl">
|
||||
<template>
|
||||
<#assign buttonList=[]>
|
||||
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
|
||||
@ -59,7 +59,7 @@
|
||||
closeModal();
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='form'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
@ -75,7 +75,7 @@
|
||||
handleSubmit,
|
||||
submitSuccess,
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='form'>
|
||||
handle${btn.buttonCode?cap_first},
|
||||
</#if>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<div>
|
||||
<#assign list_need_category=false>
|
||||
<#assign list_need_pca=false>
|
||||
@ -32,7 +32,7 @@
|
||||
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'button'>
|
||||
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
|
||||
</#if>
|
||||
@ -329,7 +329,7 @@
|
||||
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -365,7 +365,7 @@
|
||||
auth: '${entityPackage}:${tableName}:delete'
|
||||
}
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle == 'link'>
|
||||
,{
|
||||
label: '${btn.buttonName}',
|
||||
@ -424,7 +424,7 @@
|
||||
</#if>
|
||||
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='button'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -351,13 +351,19 @@ export const formSchema: FormSchema[] = [
|
||||
<#elseif po.classType=='list'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
dictCode:"${form_field_dictCode}",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}",
|
||||
type: "radio"
|
||||
type: "radio",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||
<#elseif po.classType=='list_multi'>
|
||||
@ -612,13 +618,19 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
|
||||
<#elseif po.classType=='list'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
dictCode:"${form_field_dictCode}",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}",
|
||||
type: "radio"
|
||||
type: "radio",
|
||||
<#if po.fieldDbType=='int'>
|
||||
stringToNumber: true
|
||||
</#if>
|
||||
},
|
||||
<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- -->
|
||||
<#elseif po.classType=='list_multi'>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<#include "/common/utils.ftl">
|
||||
<#include "/common/utils.ftl">
|
||||
<template>
|
||||
<#assign buttonList=[]>
|
||||
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
|
||||
@ -286,7 +286,7 @@
|
||||
</#list>
|
||||
};
|
||||
<#if buttonList?size gt 0>
|
||||
<#list buttonList?filter(it -> it.orderNum?? && it.orderNum != null)?sort_by("orderNum") as btn>
|
||||
<#list buttonList as btn>
|
||||
<#if btn.buttonStyle=='form'>
|
||||
function handle${btn.buttonCode?cap_first}(){
|
||||
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
-- author:scott---date:20251212--for:在线用户接口权限配置
|
||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES ('1999406402585542657', '1594930803956920321', '在线用户列表接口', NULL, NULL, 0, NULL, NULL, 2, 'system:online:list', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-12-12 17:10:08', NULL, NULL, 0, 0, '1', 0);
|
||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES ('1999406500300242946', '1594930803956920321', '强制用户退出接口', NULL, NULL, 0, NULL, NULL, 2, 'system:online:forceLogout', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-12-12 17:10:32', NULL, NULL, 0, 0, '1', 0);
|
||||
@ -57,7 +57,7 @@
|
||||
<!-- 积木报表-->
|
||||
<jimureport-spring-boot-starter.version>2.2.0</jimureport-spring-boot-starter.version>
|
||||
<jimubi-spring-boot-starter.version>2.2.0</jimubi-spring-boot-starter.version>
|
||||
<minidao.version>1.10.16</minidao.version>
|
||||
<minidao.version>1.10.18</minidao.version>
|
||||
<autopoi-web.version>2.0.2</autopoi-web.version>
|
||||
|
||||
<!-- 持久层 -->
|
||||
@ -132,6 +132,11 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-launcher</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- Lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
@ -475,17 +480,6 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<version>5.6.7.Final</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- AutoPoi Excel工具类-->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework</groupId>
|
||||
|
||||
@ -60,7 +60,7 @@
|
||||
import { useSelectBiz } from '/@/components/Form/src/jeecg/hooks/useSelectBiz';
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
import { selectProps } from '/@/components/Form/src/jeecg/props/props';
|
||||
|
||||
import { isArray, cloneDeep } from 'lodash-es';
|
||||
export default defineComponent({
|
||||
name: 'UserSelectModal',
|
||||
components: {
|
||||
@ -115,8 +115,14 @@
|
||||
}
|
||||
// 代码逻辑说明: VUEN-1112 一对多 用户选择 未显示选择条数,及清空
|
||||
setTimeout(() => {
|
||||
// update-begin--author:liaozhiyang---date:20260120--for:【issues/9275】用户组件第二次点击取消时勾选值还是回显了
|
||||
let selectedData = selectValues['value'];
|
||||
if (isArray(selectedData)) {
|
||||
selectedData = cloneDeep(selectedData);
|
||||
}
|
||||
// update-end--author:liaozhiyang---date:20260120--for:【issues/9275】用户组件第二次点击取消时勾选值还是回显了
|
||||
if (tableRef.value) {
|
||||
tableRef.value.setSelectedRowKeys(selectValues['value'] || []);
|
||||
tableRef.value.setSelectedRowKeys(selectedData || []);
|
||||
}
|
||||
}, 800);
|
||||
});
|
||||
|
||||
@ -106,7 +106,8 @@ export function useTableScroll(
|
||||
const paddingHeight = 32;
|
||||
// Pager height
|
||||
let paginationHeight = 2;
|
||||
if (!isBoolean(pagination)) {
|
||||
// 【issues/9217】当配置了pagination: true时,BasicTable组件自适应高度异常
|
||||
if (pagination !== false) {
|
||||
paginationEl = tableEl.querySelector('.ant-pagination') as HTMLElement;
|
||||
if (paginationEl) {
|
||||
const offsetHeight = paginationEl.offsetHeight;
|
||||
|
||||
@ -38,7 +38,10 @@ export function usePagination(props: JVxeTableProps, methods: JVxeTableMethods)
|
||||
|
||||
function handleShowSizeChange(current, pageSize) {
|
||||
innerPagination.pageSize = pageSize;
|
||||
methods.trigger('pageChange', { current, pageSize });
|
||||
// -update-begin--author:liaozhiyang---date:20251209---for:【issues/9169】切换页码时,pageChange事件加载了两次
|
||||
// 因为 handleShowSizeChange先触发,紧接着会触发 handleChange,所以可以注释掉。
|
||||
// methods.trigger('pageChange', { current, pageSize });
|
||||
// -update-end--author:liaozhiyang---date:20251209---for:【issues/9169】切换页码时,pageChange事件加载了两次
|
||||
}
|
||||
|
||||
/** 渲染分页器 */
|
||||
|
||||
@ -75,6 +75,10 @@ export function useListPage(options: ListPageOptions) {
|
||||
if (options?.tableProps?.useSearchForm !== false) {
|
||||
paramsForm = await getForm().validate();
|
||||
console.log('paramsForm', paramsForm);
|
||||
// 在这里把执行beforeFetch
|
||||
if (options?.tableProps?.beforeFetch) {
|
||||
paramsForm = await options?.tableProps?.beforeFetch(paramsForm);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
@ -132,8 +136,8 @@ export function useListPage(options: ListPageOptions) {
|
||||
for (const column of columns) {
|
||||
if(!column.defaultHidden){
|
||||
let dataIndex = column?.dataIndex;
|
||||
if(column?.dataIndex!.toString().indexOf('_dictText')){
|
||||
dataIndex = column?.dataIndex!.toString().replace('_dictText','')
|
||||
if(column?.dataIndex?.toString()?.indexOf('_dictText') !== -1){
|
||||
dataIndex = column?.dataIndex?.toString().replace('_dictText','')
|
||||
}
|
||||
exportFields.push(dataIndex);
|
||||
} else {
|
||||
|
||||
@ -45,15 +45,17 @@ const render = {
|
||||
*/
|
||||
renderDict: (v, code, renderTag = false) => {
|
||||
let text = '';
|
||||
let color = '';
|
||||
let array = getDictItemsByCode(code) || [];
|
||||
let obj = array.filter((item) => {
|
||||
return item.value == v;
|
||||
});
|
||||
if (obj.length > 0) {
|
||||
text = obj[0].text;
|
||||
color = obj[0].color;
|
||||
}
|
||||
//【jeecgboot-vue3/issues/903】render.renderDict使用tag渲染报警告问题 #903
|
||||
return isEmpty(text) || !renderTag ? h('span', text) : h(Tag, () => text);
|
||||
return isEmpty(text) || !renderTag ? h('span', text) : h(Tag,{ color }, () => text);
|
||||
},
|
||||
/**
|
||||
* 渲染图片
|
||||
|
||||
Reference in New Issue
Block a user