【版本合并】 branch 'origin/master' into springboot3

This commit is contained in:
JEECG
2024-10-08 19:30:14 +08:00
418 changed files with 13881 additions and 4476 deletions

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-system-api</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>3.7.0</version>
<version>3.7.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -597,7 +597,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return
*/
@GetMapping("/sys/api/loadDictItemByKeyword")
List<DictModel> loadDictItemByKeyword(@RequestParam("dictCode") String dictCode, @RequestParam("keyword") String keyword, @RequestParam(value = "pageSize", required = false) Integer pageSize);
List<DictModel> loadDictItemByKeyword(@RequestParam("dictCode") String dictCode, @RequestParam("keyword") String keyword, @RequestParam(value = "pageNo", defaultValue = "1", required = false) Integer pageNo, @RequestParam(value = "pageSize", required = false) Integer pageSize);
/**
* 47 根据多个部门id(逗号分隔),查询返回多个部门信息

View File

@ -382,7 +382,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
}
@Override
public List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize) {
public List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageNo, Integer pageSize) {
return null;
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-system-api</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>3.7.0</version>
<version>3.7.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -457,7 +457,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @param pageSize 分页条数
* @return
*/
List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize);
List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageNo, Integer pageSize);
/**
* 新增数据日志

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-module-system</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>3.7.0</version>
<version>3.7.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-module-system</artifactId>
<version>3.7.0</version>
<version>3.7.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -1,5 +1,6 @@
package org.jeecg.config.jimureport;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.dto.LogDTO;
import org.jeecg.common.system.api.ISysBaseAPI;
@ -13,6 +14,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;

View File

@ -98,7 +98,7 @@ public class SystemApiController {
try {
SensitiveInfoUtil.handlerObject(loginUser, true);
} catch (IllegalAccessException e) {
e.printStackTrace();
log.error(e.getMessage(), e);
}
return loginUser;
}
@ -666,8 +666,11 @@ public class SystemApiController {
* @return
*/
@GetMapping("/loadDictItemByKeyword")
public List<DictModel> loadDictItemByKeyword(@RequestParam("dictCode") String dictCode, @RequestParam("keyword") String keyword, @RequestParam(value = "pageSize", required = false) Integer pageSize) {
return sysBaseApi.loadDictItemByKeyword(dictCode, keyword, pageSize);
public List<DictModel> loadDictItemByKeyword(@RequestParam("dictCode") String dictCode,
@RequestParam("keyword") String keyword,
@RequestParam(value = "pageNo", defaultValue = "1", required = false) Integer pageNo,
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
return sysBaseApi.loadDictItemByKeyword(dictCode, keyword,pageNo, pageSize);
}
/**

View File

@ -26,27 +26,31 @@ public class ActuatorMemoryController {
/**
* 内存详情
* @return
* @throws Exception
*/
@GetMapping("/info")
public Result<?> getRedisInfo() throws Exception {
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
JSONObject operatingSystemJson = JSONObject.parseObject(JSONObject.toJSONString(operatingSystemMXBean));
long totalPhysicalMemory = operatingSystemJson.getLongValue("totalPhysicalMemorySize");
long freePhysicalMemory = operatingSystemJson.getLongValue("freePhysicalMemorySize");
long usedPhysicalMemory = totalPhysicalMemory - freePhysicalMemory;
public Result<?> getRedisInfo() {
Runtime runtime = Runtime.getRuntime();
Map<String,Number> result = new HashMap<>();
result.put("memory.physical.total", totalPhysicalMemory);
result.put("memory.physical.used", freePhysicalMemory);
result.put("memory.physical.free", usedPhysicalMemory);
result.put("memory.physical.usage", NumberUtil.div(usedPhysicalMemory, totalPhysicalMemory));
result.put("memory.runtime.total", runtime.totalMemory());
result.put("memory.runtime.used", runtime.freeMemory());
result.put("memory.runtime.max", runtime.totalMemory() - runtime.freeMemory());
result.put("memory.runtime.free", runtime.maxMemory() - runtime.totalMemory() + runtime.freeMemory());
result.put("memory.runtime.usage", NumberUtil.div(runtime.totalMemory() - runtime.freeMemory(), runtime.totalMemory()));
return Result.ok(result);
//update-begin---author:chenrui ---date:20240705 for[TV360X-1695]内存信息-立即更新 功能报错 #6635------------
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
if (operatingSystemMXBean instanceof com.sun.management.OperatingSystemMXBean) {
com.sun.management.OperatingSystemMXBean opBean = (com.sun.management.OperatingSystemMXBean) operatingSystemMXBean;
// JSONObject operatingSystemJson = JSONObject.parseObject(JSONObject.toJSONString(operatingSystemMXBean));
long totalPhysicalMemory = opBean.getTotalPhysicalMemorySize();
long freePhysicalMemory = opBean.getFreePhysicalMemorySize();
long usedPhysicalMemory = totalPhysicalMemory - freePhysicalMemory;
result.put("memory.physical.total", totalPhysicalMemory);
result.put("memory.physical.used", freePhysicalMemory);
result.put("memory.physical.free", usedPhysicalMemory);
result.put("memory.physical.usage", NumberUtil.div(usedPhysicalMemory, totalPhysicalMemory));
}
//update-end---author:chenrui ---date:20240705 for[TV360X-1695]内存信息-立即更新 功能报错 #6635------------
return Result.ok(result);
}
}

View File

@ -15,6 +15,7 @@ import org.jeecg.common.constant.SymbolConstant;
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.entity.QuartzJob;
import org.jeecg.modules.quartz.service.IQuartzJobService;
import org.jeecgframework.poi.excel.ExcelImportUtil;
@ -206,6 +207,12 @@ public class QuartzJobController {
public ModelAndView exportXls(HttpServletRequest request, QuartzJob quartzJob) {
// Step.1 组装查询条件
QueryWrapper<QuartzJob> queryWrapper = QueryGenerator.initQueryWrapper(quartzJob, request.getParameterMap());
// 过滤选中数据
String selections = request.getParameter("selections");
if (oConvertUtils.isNotEmpty(selections)) {
List<String> selectionList = Arrays.asList(selections.split(","));
queryWrapper.in("id",selectionList);
}
// Step.2 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
List<QuartzJob> pageList = quartzJobService.list(queryWrapper);

View File

@ -51,7 +51,7 @@ public class CommonController {
*/
@GetMapping("/403")
public Result<?> noauth() {
return Result.error("没有权限,请联系管理员授权,后刷新缓存!");
return Result.error("没有权限,请联系管理员分配权限!");
}
/**

View File

@ -5,6 +5,7 @@ import java.util.Date;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
@ -217,13 +218,21 @@ public class SysAnnouncementSendController {
@GetMapping(value = "/getMyAnnouncementSend")
public Result<IPage<AnnouncementSendModel>> getMyAnnouncementSend(AnnouncementSendModel announcementSendModel,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
Result<IPage<AnnouncementSendModel>> result = new Result<IPage<AnnouncementSendModel>>();
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
String userId = sysUser.getId();
announcementSendModel.setUserId(userId);
announcementSendModel.setPageNo((pageNo-1)*pageSize);
announcementSendModel.setPageSize(pageSize);
//update-begin---author:wangshuai---date:2024-06-11---for:【TV360X-545】我的消息列表不能通过时间范围查询---
if(StringUtils.isNotEmpty(announcementSendModel.getSendTimeBegin())){
announcementSendModel.setSendTimeBegin(announcementSendModel.getSendTimeBegin() + " 00:00:00");
}
if(StringUtils.isNotEmpty(announcementSendModel.getSendTimeBegin())){
announcementSendModel.setSendTimeEnd(announcementSendModel.getSendTimeEnd() + " 23:59:59");
}
//update-end---author:wangshuai---date:2024-06-11---for:【TV360X-545】我的消息列表不能通过时间范围查询---
Page<AnnouncementSendModel> pageList = new Page<AnnouncementSendModel>(pageNo,pageSize);
pageList = sysAnnouncementSendService.getMyAnnouncementSendPage(pageList, announcementSendModel);
result.setResult(pageList);

View File

@ -364,9 +364,17 @@ public class SysDepartController {
//return arg0.getOrgCode().compareTo(arg1.getOrgCode());
//}
//});
// 过滤选中数据
String selections = request.getParameter("selections");
List<String> idList = new ArrayList<>();
if (oConvertUtils.isNotEmpty(selections)) {
idList = Arrays.asList(selections.split(","));
}
//step.2 组装导出数据
Integer tenantId = sysDepart == null ? null : sysDepart.getTenantId();
List<SysDepartExportVo> sysDepartExportVos = sysDepartService.getExportDepart(tenantId);
//update-begin---author:wangshuai---date:2024-07-05---for:【TV360X-1671】部门管理不支持选中的记录导出---
List<SysDepartExportVo> sysDepartExportVos = sysDepartService.getExportDepart(tenantId,idList);
//update-end---author:wangshuai---date:2024-07-05---for:【TV360X-1671】部门管理不支持选中的记录导出---
//导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME, "部门列表");
mv.addObject(NormalExcelConstants.CLASS, SysDepartExportVo.class);

View File

@ -156,7 +156,8 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
@RequiresPermissions("system:depart:role:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.sysDepartRoleService.removeByIds(Arrays.asList(ids.split(",")));
this.sysDepartRoleService.deleteDepartRole(Arrays.asList(ids.split(",")));
//this.sysDepartRoleService.removeByIds(Arrays.asList(ids.split(",")));
return Result.ok("批量删除成功!");
}

View File

@ -2,11 +2,13 @@ package org.jeecg.modules.system.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
@ -19,10 +21,7 @@ import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.DictQuery;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.ImportExcelUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.common.util.*;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
import org.jeecg.config.shiro.ShiroRealm;
import org.jeecg.modules.system.entity.SysDict;
@ -78,8 +77,14 @@ public class SysDictController {
private ShiroRealm shiroRealm;
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Result<IPage<SysDict>> queryPageList(SysDict sysDict,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
public Result<IPage<SysDict>> queryPageList(
SysDict sysDict,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
// 查询关键字模糊筛选code和name
@RequestParam(name = "keywords", required = false) String keywords,
HttpServletRequest req
) {
Result<IPage<SysDict>> result = new Result<IPage<SysDict>>();
//------------------------------------------------------------------------------------------------
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
@ -88,7 +93,12 @@ public class SysDictController {
}
//------------------------------------------------------------------------------------------------
QueryWrapper<SysDict> queryWrapper = QueryGenerator.initQueryWrapper(sysDict, req.getParameterMap());
Page<SysDict> page = new Page<SysDict>(pageNo, pageSize);
// 查询关键字模糊筛选code和name
if (oConvertUtils.isNotEmpty(keywords)) {
queryWrapper.and(i -> i.like("dict_code", keywords).or().like("dict_name", keywords));
}
Page<SysDict> page = new Page<>(pageNo, pageSize);
IPage<SysDict> pageList = sysDictService.page(page, queryWrapper);
log.debug("查询当前页:"+pageList.getCurrent());
log.debug("查询当前页数量:"+pageList.getSize());
@ -202,7 +212,8 @@ public class SysDictController {
public Result<List<DictModel>> loadDict(@PathVariable("dictCode") String dictCode,
@RequestParam(name="keyword",required = false) String keyword,
@RequestParam(value = "sign",required = false) String sign,
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
@RequestParam(name = "pageNo", defaultValue = "1", required = false) Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10", required = false) Integer pageSize) {
//update-begin-author:taoyan date:2023-5-22 for: /issues/4905 因为中括号(%5)的问题导致的 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误 #4905 RouteToRequestUrlFilter
if(keyword!=null && keyword.indexOf("%5")>=0){
@ -217,7 +228,7 @@ public class SysDictController {
log.info(" 加载字典表数据,加载关键字: "+ keyword);
Result<List<DictModel>> result = new Result<List<DictModel>>();
try {
List<DictModel> ls = sysDictService.loadDict(dictCode, keyword, pageSize);
List<DictModel> ls = sysDictService.loadDict(dictCode, keyword, pageNo,pageSize);
if (ls == null) {
result.error500("字典Code格式不正确");
return result;
@ -249,12 +260,12 @@ public class SysDictController {
@RequestParam(value = "sign", required = false) String sign,
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
// 首次查询查出来用户选中的值,并且不分页
Result<List<DictModel>> firstRes = this.loadDict(dictCode, keyword, sign, null);
Result<List<DictModel>> firstRes = this.loadDict(dictCode, keyword, sign,null, null);
if (!firstRes.isSuccess()) {
return firstRes;
}
// 然后再查询出第一页的数据
Result<List<DictModel>> result = this.loadDict(dictCode, "", sign, pageSize);
Result<List<DictModel>> result = this.loadDict(dictCode, "", sign,1, pageSize);
if (!result.isSuccess()) {
return result;
}
@ -666,6 +677,45 @@ public class SysDictController {
return Result.error("操作失败!");
}
}
/**
* 还原被逻辑删除的用户
*
* @param jsonObject
* @return
*/
@RequestMapping(value = "/putRecycleBin", method = RequestMethod.PUT)
public Result putRecycleBin(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
try {
String ids = jsonObject.getString("ids");
if (StringUtils.isNotBlank(ids)) {
sysDictService.revertLogicDeleted(Arrays.asList(ids.split(",")));
return Result.ok("操作成功!");
}
} catch (Exception e) {
e.printStackTrace();
return Result.error("操作失败!");
}
return Result.ok("还原成功");
}
/**
* 彻底删除字典
*
* @param ids 被删除的字典ID多个id用半角逗号分割
* @return
*/
@RequiresPermissions("system:dict:deleteRecycleBin")
@RequestMapping(value = "/deleteRecycleBin", method = RequestMethod.DELETE)
public Result deleteRecycleBin(@RequestParam("ids") String ids) {
try {
if (StringUtils.isNotBlank(ids)) {
sysDictService.removeLogicDeleted(Arrays.asList(ids.split(",")));
}
return Result.ok("删除成功!");
} catch (Exception e) {
e.printStackTrace();
return Result.error("删除失败!");
}
}
/**
* VUEN-2584【issue】平台sql注入漏洞几个问题

View File

@ -4,7 +4,9 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.base.controller.JeecgController;
@ -14,6 +16,7 @@ import org.jeecg.modules.system.service.ISysGatewayRouteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
/**
@ -74,4 +77,72 @@ public class SysGatewayRouteController extends JeecgController<SysGatewayRoute,
return Result.ok("删除路由成功");
}
/**
* 查询被删除的列表
* @return
*/
@RequestMapping(value = "/deleteList", method = RequestMethod.GET)
public Result<List<SysGatewayRoute>> deleteList(HttpServletRequest request) {
Result<List<SysGatewayRoute>> result = new Result<>();
List<SysGatewayRoute> list = sysGatewayRouteService.getDeletelist();
result.setSuccess(true);
result.setResult(list);
return result;
}
/**
* 还原被逻辑删除的路由
*
* @param jsonObject
* @return
*/
@RequiresPermissions("system:gateway:putRecycleBin")
@RequestMapping(value = "/putRecycleBin", method = RequestMethod.PUT)
public Result putRecycleBin(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
try {
String ids = jsonObject.getString("ids");
if (StringUtils.isNotBlank(ids)) {
sysGatewayRouteService.revertLogicDeleted(Arrays.asList(ids.split(",")));
return Result.ok("操作成功!");
}
} catch (Exception e) {
e.printStackTrace();
return Result.error("操作失败!");
}
return Result.ok("还原成功");
}
/**
* 彻底删除路由
*
* @param ids 被删除的路由ID多个id用半角逗号分割
* @return
*/
@RequiresPermissions("system:gateway:deleteRecycleBin")
@RequestMapping(value = "/deleteRecycleBin", method = RequestMethod.DELETE)
public Result deleteRecycleBin(@RequestParam("ids") String ids) {
try {
if (StringUtils.isNotBlank(ids)) {
sysGatewayRouteService.deleteLogicDeleted(Arrays.asList(ids.split(",")));
}
return Result.ok("删除成功!");
} catch (Exception e) {
e.printStackTrace();
return Result.error("删除失败!");
}
}
/**
* 复制路由
*
* @param id 路由id
* @return
*/
@RequiresPermissions("system:gateway:copyRoute")
@RequestMapping(value = "/copyRoute", method = RequestMethod.GET)
public Result<SysGatewayRoute> copyRoute(@RequestParam(name = "id", required = true) String id, HttpServletRequest req) {
Result<SysGatewayRoute> result = new Result<>();
SysGatewayRoute sysGatewayRoute= sysGatewayRouteService.copyRoute(id);
result.setResult(sysGatewayRoute);
result.setSuccess(true);
return result;
}
}

View File

@ -604,9 +604,8 @@ public class SysPermissionController {
log.info("======角色授权成功=====耗时:" + (System.currentTimeMillis() - start) + "毫秒");
//update-begin---author:scott ---date:2024-06-18 for【TV360X-1320】分配权限必须退出重新登录才生效造成很多用户困扰---
// 获取当前用户的Subject对象
Subject currentUser = SecurityUtils.getSubject();
// 清除当前用户的授权缓存信息
Subject currentUser = SecurityUtils.getSubject();
if (currentUser.isAuthenticated()) {
shiroRealm.clearCache(currentUser.getPrincipals());
}

View File

@ -219,26 +219,31 @@ public class SysPositionController {
* @param response
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
public ModelAndView exportXls(SysPosition sysPosition,HttpServletRequest request, HttpServletResponse response) {
// Step.1 组装查询条件
QueryWrapper<SysPosition> queryWrapper = null;
try {
String paramsStr = request.getParameter("paramsStr");
if (oConvertUtils.isNotEmpty(paramsStr)) {
String deString = URLDecoder.decode(paramsStr, "UTF-8");
SysPosition sysPosition = JSON.parseObject(deString, SysPosition.class);
sysPosition = JSON.parseObject(deString, SysPosition.class);
//------------------------------------------------------------------------------------------------
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
sysPosition.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(),0));
}
//------------------------------------------------------------------------------------------------
queryWrapper = QueryGenerator.initQueryWrapper(sysPosition, request.getParameterMap());
}
queryWrapper = QueryGenerator.initQueryWrapper(sysPosition, request.getParameterMap());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//update-begin--Author:liusq Date:20240715 for[03]职务导出,如果选择数据则只导出相关数据--------------------
String selections = request.getParameter("selections");
if(!oConvertUtils.isEmpty(selections)){
queryWrapper.in("id",selections.split(","));
}
//update-end--Author:liusq Date:20240715 for[03]职务导出,如果选择数据则只导出相关数据----------------------
//Step.2 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
List<SysPosition> pageList = sysPositionService.list(queryWrapper);

View File

@ -220,7 +220,7 @@ public class SysRoleController {
String username = "admin";
if(getRoleCount == 0 && !username.equals(sysUser.getUsername())){
baseCommonService.addLog("未经授权删除非本租户下的角色ID" + id + ",操作人:" + sysUser.getUsername(), CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_4);
return Result.error("删除角色失败,删除角色不属于登录租户!");
return Result.error("删除角色失败,当前角色不在此租户中。");
}
}

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
@ -41,7 +42,8 @@ public class SysTableWhiteListController extends JeecgController<SysTableWhiteLi
* @param req
* @return
*/
@RequiresRoles("admin")
//@RequiresRoles("admin")
@RequiresPermissions("system:tableWhite:list")
@GetMapping(value = "/list")
public Result<?> queryPageList(
SysTableWhiteList sysTableWhiteList,
@ -63,7 +65,8 @@ public class SysTableWhiteListController extends JeecgController<SysTableWhiteLi
*/
@AutoLog(value = "系统表白名单-添加")
@Operation(summary = "系统表白名单-添加")
@RequiresRoles("admin")
//@RequiresRoles("admin")
@RequiresPermissions("system:tableWhite:add")
@PostMapping(value = "/add")
public Result<?> add(@RequestBody SysTableWhiteList sysTableWhiteList) {
if (sysTableWhiteListService.add(sysTableWhiteList)) {
@ -81,7 +84,8 @@ public class SysTableWhiteListController extends JeecgController<SysTableWhiteLi
*/
@AutoLog(value = "系统表白名单-编辑")
@Operation(summary = "系统表白名单-编辑")
@RequiresRoles("admin")
//@RequiresRoles("admin")
@RequiresPermissions("system:tableWhite:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<?> edit(@RequestBody SysTableWhiteList sysTableWhiteList) {
if (sysTableWhiteListService.edit(sysTableWhiteList)) {
@ -99,7 +103,8 @@ public class SysTableWhiteListController extends JeecgController<SysTableWhiteLi
*/
@AutoLog(value = "系统表白名单-通过id删除")
@Operation(summary = "系统表白名单-通过id删除")
@RequiresRoles("admin")
// @RequiresRoles("admin")
@RequiresPermissions("system:tableWhite:delete")
@DeleteMapping(value = "/delete")
public Result<?> delete(@RequestParam(name = "id") String id) {
if (sysTableWhiteListService.deleteByIds(id)) {
@ -117,7 +122,8 @@ public class SysTableWhiteListController extends JeecgController<SysTableWhiteLi
*/
@AutoLog(value = "系统表白名单-批量删除")
@Operation(summary = "系统表白名单-批量删除")
@RequiresRoles("admin")
// @RequiresRoles("admin")
@RequiresPermissions("system:tableWhite:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<?> deleteBatch(@RequestParam(name = "ids") String ids) {
if (sysTableWhiteListService.deleteByIds(ids)) {
@ -135,7 +141,8 @@ public class SysTableWhiteListController extends JeecgController<SysTableWhiteLi
*/
@AutoLog(value = "系统表白名单-通过id查询")
@Operation(summary = "系统表白名单-通过id查询")
@RequiresRoles("admin")
// @RequiresRoles("admin")
@RequiresPermissions("system:tableWhite:queryById")
@GetMapping(value = "/queryById")
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
SysTableWhiteList sysTableWhiteList = sysTableWhiteListService.getById(id);

View File

@ -205,7 +205,8 @@ public class SysUserController {
// 修改用户走一个service 保证事务
//获取租户ids
String relTenantIds = jsonObject.getString("relTenantIds");
sysUserService.editUser(user, roles, departs, relTenantIds);
String updateFromPage = jsonObject.getString("updateFromPage");
sysUserService.editUser(user, roles, departs, relTenantIds, updateFromPage);
result.success("修改成功!");
}
} catch (Exception e) {
@ -222,7 +223,12 @@ public class SysUserController {
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
baseCommonService.addLog("删除用户id " +id ,CommonConstant.LOG_TYPE_2, 3);
List<String> userNameList = sysUserService.userIdToUsername(Arrays.asList(id));
this.sysUserService.deleteUser(id);
if (!userNameList.isEmpty()) {
String joinedString = String.join(",", userNameList);
}
return Result.ok("删除用户成功");
}
@ -233,7 +239,13 @@ public class SysUserController {
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
baseCommonService.addLog("批量删除用户, ids " +ids ,CommonConstant.LOG_TYPE_2, 3);
List<String> userNameList = sysUserService.userIdToUsername(Arrays.asList(ids.split(",")));
this.sysUserService.deleteBatchUsers(ids);
// 用户变更,触发同步工作流
if (!userNameList.isEmpty()) {
String joinedString = String.join(",", userNameList);
}
return Result.ok("批量删除用户成功");
}
@ -906,6 +918,9 @@ public class SysUserController {
boolean b = sysUserDepartService.remove(queryWrapper);
if(b){
departRoleUserService.removeDeptRoleUser(Arrays.asList(userIds.split(",")),depId);
}else{
result.error500("删除失败,目标用户不在当前部门!");
return result;
}
result.success("删除成功!");
}catch(Exception e) {
@ -1261,6 +1276,12 @@ public class SysUserController {
updateUser.setUpdateBy(JwtUtil.getUserNameByToken(request));
updateUser.setUpdateTime(new Date());
sysUserService.revertLogicDeleted(Arrays.asList(userIds.split(",")), updateUser);
// 用户变更,触发同步工作流
List<String> userNameList = sysUserService.userIdToUsername(Arrays.asList(userIds.split(",")));
if (!userNameList.isEmpty()) {
String joinedString = String.join(",", userNameList);
}
}
return Result.ok("还原成功");
}
@ -1286,7 +1307,7 @@ public class SysUserController {
* @param jsonObject
* @return
*/
@RequiresRoles({"admin"})
@RequiresPermissions("system:user:app:edit")
@RequestMapping(value = "/appEdit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<SysUser> appEdit(HttpServletRequest request,@RequestBody JSONObject jsonObject) {
Result<SysUser> result = new Result<SysUser>();

View File

@ -11,12 +11,14 @@ import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import me.zhyd.oauth.utils.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.enums.MessageTypeEnum;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.*;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysThirdAccount;
import org.jeecg.modules.system.entity.SysThirdAppConfig;
import org.jeecg.modules.system.entity.SysUser;
@ -25,6 +27,7 @@ import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.system.service.ISysThirdAccountService;
import org.jeecg.modules.system.service.ISysThirdAppConfigService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
@ -60,6 +63,8 @@ public class ThirdLoginController {
private RedisUtil redisUtil;
@Autowired
private AuthRequestFactory factory;
@Autowired
private ISysDepartService sysDepartService;
@Autowired
private ThirdAppWechatEnterpriseServiceImpl thirdAppWechatEnterpriseService;
@ -250,8 +255,8 @@ public class ThirdLoginController {
}
//update-end-author:wangshuai date:20201118 for:如果真实姓名和头像不存在就取第三方登录的
JSONObject obj = new JSONObject();
//TODO 第三方登确定登录租户和部门逻辑
//第三方登确定登录租户和部门逻辑
this.setUserTenantAndDepart(sysUser,obj,result);
//用户登录信息
obj.put("userInfo", sysUser);
//获取字典缓存【解决 #jeecg-boot/issues/3998】
@ -528,4 +533,28 @@ public class ThirdLoginController {
return Result.error("注册失败");
}
}
/**
* 设置用户租户和部门信息
*
* @param sysUser
* @param obj
* @param result
*/
private void setUserTenantAndDepart(SysUser sysUser, JSONObject obj, Result<JSONObject> result) {
//1.设置登录租户
sysUserService.setLoginTenant(sysUser, obj, sysUser.getUsername(), result);
//2.设置登录部门
String orgCode = sysUser.getOrgCode();
//部门不为空还是用原来的部门code
if(StringUtils.isEmpty(orgCode)){
List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
//部门不为空取第一个作为当前登录部门
if(CollectionUtil.isNotEmpty(departs)){
orgCode = departs.get(0).getOrgCode();
sysUser.setOrgCode(orgCode);
this.sysUserService.updateUserDepart(sysUser.getUsername(), orgCode,null);
}
}
}
}

View File

@ -1,6 +1,8 @@
package org.jeecg.modules.system.controller;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.system.util.XssUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -22,8 +24,13 @@ public class WechatVerifyController {
*/
@RequestMapping(value = "/WW_verify_{code}.txt")
public void mpVerify(@PathVariable("code") String code, HttpServletResponse response) {
if(StringUtils.isEmpty(code)){
log.error("企业微信证书验证失败!(code为空)");
return;
}
try {
PrintWriter writer = response.getWriter();
code = XssUtils.scriptXss(code);
writer.write(code);
writer.close();
} catch (Exception e) {

View File

@ -1,6 +1,7 @@
package org.jeecg.modules.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
@ -76,4 +77,11 @@ public class SysComment implements Serializable {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@Schema(description = "更新日期")
private Date updateTime;
/**
* 不是数据库字段,用于评论跳转
*/
@TableField(exist = false)
private String tableId;
}

View File

@ -2,6 +2,7 @@ package org.jeecg.modules.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
@ -96,6 +97,12 @@ public class SysGatewayRoute implements Serializable {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@Schema(description = "创建日期")
private Date createTime;
/**
* 删除状态0未删除1已删除
*/
@TableLogic
private Integer delFlag;
/* *//**更新人*//*
@Schema(description = "更新人")
private String updateBy;

View File

@ -46,7 +46,7 @@ public class SysPosition {
/**
* 职级
*/
@Excel(name = "职级", width = 15,dicCode ="position_rank")
//@Excel(name = "职级", width = 15,dicCode ="position_rank")
@Schema(description = "职级")
@Dict(dicCode = "position_rank")
private java.lang.String postRank;

View File

@ -177,5 +177,5 @@ public interface SysDepartMapper extends BaseMapper<SysDepart> {
* @param parentId
* @return
*/
List<SysDepartExportVo> getSysDepartList(@Param("parentId") String parentId,@Param("tenantId") Integer tenantId);
List<SysDepartExportVo> getSysDepartList(@Param("parentId") String parentId,@Param("tenantId") Integer tenantId, List<String> idList);
}

View File

@ -14,4 +14,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/
public interface SysDepartRolePermissionMapper extends BaseMapper<SysDepartRolePermission> {
void deleteByRoleIds(@Param("ids")List<String> ids);
}

View File

@ -14,4 +14,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/
public interface SysDepartRoleUserMapper extends BaseMapper<SysDepartRoleUser> {
void deleteByRoleIds(@Param("ids")List<String> ids);
}

View File

@ -200,4 +200,18 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
*/
@Select("select * from sys_dict where del_flag = 1 and tenant_id = #{tenantId}")
List<SysDict> queryDeleteListBtTenantId(@Param("tenantId") Integer tenantId);
/**
* 还原被逻辑删除的数据根据id
* @param ids
* @return
*/
int revertLogicDeleted(@Param("ids") List<String> ids);
/**
* 彻底删除的数据根据ids
* @param ids
* @return
*/
int removeLogicDeleted(@Param("ids")List<String> ids);
}

View File

@ -1,8 +1,12 @@
package org.jeecg.modules.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.system.entity.SysGatewayRoute;
import java.util.List;
/**
* @Description: gateway路由管理
* @Author: jeecg-boot
@ -10,5 +14,22 @@ import org.jeecg.modules.system.entity.SysGatewayRoute;
* @Version: V1.0
*/
public interface SysGatewayRouteMapper extends BaseMapper<SysGatewayRoute> {
/**
* 还原逻辑删除
* @param ids
*/
int revertLogicDeleted(@Param("ids") List<String> ids);
/**
*彻底删除
* @param ids
*/
int deleteLogicDeleted(@Param("ids") List<String> ids);
/**
* 查询删除的列表
* @return
*/
@Select("select * from sys_gateway_route where del_flag = 1")
List<SysGatewayRoute> queryDeleteList();
}

View File

@ -47,7 +47,10 @@
<!-- 获取用户未读消息数量 -->
<select id="getUnreadMessageCountByUserId" resultType="java.lang.Integer">
select count(1) from sys_announcement_send where user_id = #{userId} and read_flag = 0 and create_time &gt;= #{beginDate}
<!-- update by wangshuai 2024-07-02【TV360X-1682】撤销之后数量还显示但是点开面板没有这条数据他会一直显示有数据需要联查判断已经发送的-->
select count(1) from sys_announcement_send sas
right join sys_announcement sa on sas.annt_id = sa.id and sa.send_status = '1'
where sas.user_id = #{userId} and sas.read_flag = 0 and sas.create_time &gt;= #{beginDate}
</select>
<!-- 查询消息记录 -->

View File

@ -58,6 +58,10 @@
<if test="announcementSendModel.msgCategory !=null and announcementSendModel.msgCategory != ''">
and sa.msg_category = #{announcementSendModel.msgCategory}
</if>
<if test="announcementSendModel.sendTimeBegin !=null and announcementSendModel.sendTimeBegin != ''
and announcementSendModel.sendTimeEnd != '' and announcementSendModel.sendTimeEnd != ''">
and sa.send_time between #{announcementSendModel.sendTimeBegin} and #{announcementSendModel.sendTimeEnd}
</if>
order by sas.read_flag,sa.send_time desc
</select>

View File

@ -182,9 +182,15 @@
parent_id = #{parentId}
</when>
<otherwise>
parent_id IS NULL OR parent_id=''
(parent_id IS NULL OR parent_id='')
</otherwise>
</choose>
<if test="idList != null and !idList.isEmpty()">
and id in
<foreach item="id" index="index" collection="idList" open="(" separator="," close=")">
#{id}
</foreach>
</if>
ORDER BY depart_order DESC
</select>
</mapper>

View File

@ -2,4 +2,11 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.system.mapper.SysDepartRolePermissionMapper">
<delete id="deleteByRoleIds">
DELETE FROM sys_depart_role_permission
WHERE role_id IN
<foreach collection="ids" item="roleId" open="(" close=")" separator="," >
#{roleId}
</foreach>
</delete>
</mapper>

View File

@ -2,4 +2,11 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.system.mapper.SysDepartRoleUserMapper">
<delete id="deleteByRoleIds">
DELETE FROM sys_depart_role_user
WHERE drole_id IN
<foreach collection="ids" item="roleId" open="(" close=")" separator="," >
#{roleId}
</foreach>
</delete>
</mapper>

View File

@ -217,5 +217,29 @@
and tenant_id = #{tenantId}
</select>
<!-- 还原被逻辑删除的字典 -->
<update id="revertLogicDeleted">
UPDATE
sys_dict
SET
del_flag = 0
WHERE
del_flag = 1
AND id IN
<foreach collection="ids" item="dictId" open="(" close=")" separator="," >
#{dictId}
</foreach>
</update>
<!-- 彻底删除字典 -->
<delete id="removeLogicDeleted">
DELETE FROM sys_dict
WHERE
del_flag = 1
AND id IN
<foreach collection="ids" item="dictId" open="(" close=")" separator="," >
#{dictId}
</foreach>
</delete>
</mapper>

View File

@ -2,4 +2,29 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.system.mapper.SysGatewayRouteMapper">
<!-- 还原被逻辑删除的路由 -->
<update id="revertLogicDeleted">
UPDATE
sys_gateway_route
SET
del_flag = 0
WHERE
del_flag = 1
AND id IN
<foreach collection="ids" item="routeId" open="(" close=")" separator="," >
#{routeId}
</foreach>
</update>
<!-- 彻底删除路由 -->
<delete id="deleteLogicDeleted">
DELETE FROM sys_gateway_route
WHERE
del_flag = 1
AND id IN
<foreach collection="ids" item="routeId" open="(" close=")" separator="," >
#{routeId}
</foreach>
</delete>
</mapper>

View File

@ -181,7 +181,29 @@
<!-- 查询部门权限数据 -->
<select id="queryDepartPermissionList" parameterType="String" resultType="org.jeecg.modules.system.entity.SysPermission">
SELECT * FROM sys_permission
SELECT
id,
parent_id,
name,
url,
component,
is_route,
component_name,
redirect,
menu_type,
perms,
perms_type,
sort_no,
always_show,
icon,
is_leaf AS leaf,
keep_alive,
hidden,
hide_tab,
rule_flag,
status,
internal_or_external
FROM sys_permission
where del_flag = 0
and id in (
select permission_id from sys_depart_permission where depart_id = #{departId}

View File

@ -10,9 +10,20 @@
AND role_name like #{bindKeyword}
</if>
<if test="role.roleCode!='' and role.roleCode!=null">
<bind name="bindRoleCode" value="'%'+role.roleCode+'%'"/>
AND role_code like #{bindRoleCode}
<choose>
<when test="role.roleCode.indexOf(',') != -1">
AND role_code in
<foreach item="item" index="index" collection="role.roleCode.split(',')" open="(" separator="," close=")">
#{item}
</foreach>
</when>
<otherwise>
<bind name="bindRoleCode" value="'%'+role.roleCode+'%'"/>
AND role_code like #{bindRoleCode}
</otherwise>
</choose>
</if>
order by create_time desc
</select>

View File

@ -23,9 +23,10 @@
<!-- 根据部门查询部门用户 分页 -->
<select id="queryDepartUserPageList" resultType="org.jeecg.modules.system.entity.SysUser">
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
<!-- update by wangshuai 2024-07-03【issues/6342】部门人员选择组件出现人员重复-->
select DISTINCT a.* from sys_user a
left join sys_user_depart b on b.user_id = a.id
left join sys_depart c on b.dep_id = c.id
<bind name="bindOrgCode" value="orgCode+'%'"/>
where a.del_flag = 0 and a.status = 1 and c.org_code like #{bindOrgCode} and a.username!='_reserve_user_external'
<if test="username!=null and username!=''">

View File

@ -74,4 +74,13 @@ public class AnnouncementSendModel implements Serializable {
*/
private java.lang.String msgAbstract;
/**
* 发布开始日期
*/
private java.lang.String sendTimeBegin;
/**
* 发布结束日期
*/
private java.lang.String sendTimeEnd;
}

View File

@ -21,4 +21,9 @@ public interface ISysDepartRoleService extends IService<SysDepartRole> {
*/
List<SysDepartRole> queryDeptRoleByDeptAndUser(String orgCode, String userId);
/**
* 删除部门角色和对应关联表信息
* @param ids
*/
void deleteDepartRole(List<String> ids);
}

View File

@ -229,9 +229,10 @@ public interface ISysDepartService extends IService<SysDepart>{
/**
* 根据租户id导出部门
* @param tenantId
* @param idList
* @return
*/
List<SysDepartExportVo> getExportDepart(Integer tenantId);
List<SysDepartExportVo> getExportDepart(Integer tenantId, List<String> idList);
/**
* 导出系统部门excel

View File

@ -194,7 +194,7 @@ public interface ISysDictService extends IService<SysDict> {
* @return
*/
@Deprecated
public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize);
public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageNo, int pageSize);
/**
* 查询字典表所有数据
@ -264,10 +264,11 @@ public interface ISysDictService extends IService<SysDict> {
*
* @param dictCode 字典code格式table,text,code
* @param keyword
* @param pageNo
* @param pageSize 每页条数
* @return
*/
List<DictModel> loadDict(String dictCode, String keyword, Integer pageSize);
List<DictModel> loadDict(String dictCode, String keyword, Integer pageNo, Integer pageSize);
/**
* 根据应用id获取字典列表和详情
@ -287,4 +288,16 @@ public interface ISysDictService extends IService<SysDict> {
* @param sysDictVo
*/
void editDictByLowAppId(SysDictVo sysDictVo);
/**
* 还原逻辑删除
* @param ids
*/
boolean revertLogicDeleted(List<String> ids);
/**
* 彻底删除数据
* @param ids
*/
boolean removeLogicDeleted(List<String> ids);
}

View File

@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.entity.SysGatewayRoute;
import java.util.List;
/**
* @Description: gateway路由管理
* @Author: jeecg-boot
@ -35,4 +37,28 @@ public interface ISysGatewayRouteService extends IService<SysGatewayRoute> {
*/
void clearRedis();
/**
* 还原逻辑删除
* @param ids
*/
void revertLogicDeleted(List<String> ids);
/**
* 彻底删除
* @param ids
*/
void deleteLogicDeleted(List<String> ids);
/**
* 复制路由
* @param id
* @return
*/
SysGatewayRoute copyRoute(String id);
/**
* 获取删除列表
* @return
*/
List<SysGatewayRoute> getDeletelist();
}

View File

@ -89,7 +89,7 @@ public interface ISysUserService extends IService<SysUser> {
* @param user
* @param roles
*/
public void addUserWithRole(SysUser user, String roles);
public void addUserWithRole(SysUser user,String roles);
/**
@ -97,7 +97,7 @@ public interface ISysUserService extends IService<SysUser> {
* @param user
* @param roles
*/
public void editUserWithRole(SysUser user, String roles);
public void editUserWithRole(SysUser user,String roles);
/**
* 获取用户的授权角色
@ -113,7 +113,7 @@ public interface ISysUserService extends IService<SysUser> {
* @param version 前端UI版本
* @return
*/
public SysRoleIndex getDynamicIndexByUserRole(String username, String version);
public SysRoleIndex getDynamicIndexByUserRole(String username,String version);
/**
* 查询用户信息包括 部门信息
@ -177,7 +177,7 @@ public interface ISysUserService extends IService<SysUser> {
* @param username 用户账户名称
* @return
*/
public IPage<SysUser> getUserByRoleId(Page<SysUser> page, String roleId, String username);
public IPage<SysUser> getUserByRoleId(Page<SysUser> page,String roleId, String username);
/**
* 通过用户名获取用户角色集合
@ -311,8 +311,9 @@ public interface ISysUserService extends IService<SysUser> {
* @param roles 选择的角色id多个以逗号隔开
* @param departs 选择的部门id多个以逗号隔开
* @param relTenantIds 多个租户id
* @param updateFromPage 更新来自的页面 [TV360X-1686]
*/
void editUser(SysUser user, String roles, String departs, String relTenantIds);
void editUser(SysUser user, String roles, String departs, String relTenantIds, String updateFromPage);
/**
* userId转为username
@ -355,7 +356,7 @@ public interface ISysUserService extends IService<SysUser> {
* @param sysUser
* @return
*/
Result<JSONObject> setLoginTenant(SysUser sysUser, JSONObject obj, String username, Result<JSONObject> result);
Result<JSONObject> setLoginTenant(SysUser sysUser, JSONObject obj, String username, Result<JSONObject> result);
//--- author:taoyan date:20221231 for: QQYUN-3515【应用】应用下的组织机构管理功能细节实现 ---
/**
@ -399,7 +400,7 @@ public interface ISysUserService extends IService<SysUser> {
*/
void editTenantUser(SysUser sysUser, String tenantId, String departs, String roles);
/**
/**
* 修改用户账号状态
* @param id 账号id
* @param status 账号状态

View File

@ -1531,8 +1531,8 @@ public class SysBaseApiImpl implements ISysBaseAPI {
* @return
*/
@Override
public List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize) {
return sysDictService.loadDict(dictCode, keyword, pageSize);
public List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageNo, Integer pageSize) {
return sysDictService.loadDict(dictCode, keyword,pageNo, pageSize);
}
@Override

View File

@ -276,15 +276,30 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
// update-begin-author:taoyan date:2023-5-10 for: QQYUN-4744【系统通知】6、系统通知@人后,对方看不到是哪个表单@的,没有超链接
String tableName = sysComment.getTableName();
String prefix = "desform:";
if(tableName!=null && tableName.startsWith(prefix)){
Map<String, Object> data = new HashMap<>();
data.put(CommonConstant.NOTICE_MSG_BUS_TYPE, "comment");
JSONObject params = new JSONObject();
params.put("code", tableName.substring(prefix.length()));
params.put("dataId", sysComment.getTableDataId());
params.put("type", "designForm");
data.put(CommonConstant.NOTICE_MSG_SUMMARY, params);
md.setData(data);
if (tableName != null) {
// 表单设计器
if (tableName.startsWith(prefix)) {
Map<String, Object> data = new HashMap<>();
data.put(CommonConstant.NOTICE_MSG_BUS_TYPE, "comment");
JSONObject params = new JSONObject();
params.put("code", tableName.substring(prefix.length()));
params.put("dataId", sysComment.getTableDataId());
params.put("type", "designForm");
data.put(CommonConstant.NOTICE_MSG_SUMMARY, params);
md.setData(data);
}
// Online表单判断是否携带id
else if (oConvertUtils.isNotEmpty(sysComment.getTableId())) {
Map<String, Object> data = new HashMap<>();
data.put(CommonConstant.NOTICE_MSG_BUS_TYPE, "comment");
JSONObject params = new JSONObject();
params.put("code", tableName);
params.put("formId", sysComment.getTableId());
params.put("dataId", sysComment.getTableDataId());
params.put("type", "cgform");
data.put(CommonConstant.NOTICE_MSG_SUMMARY, params);
md.setData(data);
}
}
// update-end-author:taoyan date:2023-5-10 for: QQYUN-4744【系统通知】6、系统通知@人后,对方看不到是哪个表单@的,没有超链接

View File

@ -2,10 +2,14 @@ package org.jeecg.modules.system.service.impl;
import org.jeecg.modules.system.entity.SysDepartRole;
import org.jeecg.modules.system.mapper.SysDepartRoleMapper;
import org.jeecg.modules.system.mapper.SysDepartRolePermissionMapper;
import org.jeecg.modules.system.mapper.SysDepartRoleUserMapper;
import org.jeecg.modules.system.service.ISysDepartRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@ -18,8 +22,26 @@ import java.util.List;
@Service
public class SysDepartRoleServiceImpl extends ServiceImpl<SysDepartRoleMapper, SysDepartRole> implements ISysDepartRoleService {
@Autowired
SysDepartRolePermissionMapper sysDepartRolePermissionMapper;
@Autowired
SysDepartRoleUserMapper sysDepartRoleUserMapper;
@Override
public List<SysDepartRole> queryDeptRoleByDeptAndUser(String orgCode, String userId) {
return this.baseMapper.queryDeptRoleByDeptAndUser(orgCode,userId);
}
/**
* 删除部门角色和对应关联表信息
* @param ids
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteDepartRole(List<String> ids) {
this.baseMapper.deleteBatchIds(ids);
this.sysDepartRolePermissionMapper.deleteByRoleIds(ids);
this.sysDepartRoleUserMapper.deleteByRoleIds(ids);
}
}

View File

@ -1223,12 +1223,13 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
/**
* 系统部门导出
* @param tenantId
* @param idList 需要查询部门sql的id集合
* @return
*/
@Override
public List<SysDepartExportVo> getExportDepart(Integer tenantId) {
public List<SysDepartExportVo> getExportDepart(Integer tenantId, List<String> idList) {
//获取父级部门
List<SysDepartExportVo> parentDepart = departMapper.getSysDepartList("", tenantId);
List<SysDepartExportVo> parentDepart = departMapper.getSysDepartList("", tenantId, idList);
//子部门
List<SysDepartExportVo> childrenDepart = new ArrayList<>();
//把一级部门名称放在里面
@ -1245,7 +1246,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
List<String> path = new ArrayList<>();
path.add(sysDepart.getDepartName());
//创建子部门路径
findSysDepartPath(sysDepart, path, tenantId, childrenDepart, departIdList);
findSysDepartPath(sysDepart, path, tenantId, childrenDepart, departIdList, idList);
path.clear();
}
exportDepartVoList.addAll(childrenDepart);
@ -1353,11 +1354,12 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
* @param tenantId 租户id
* @param childrenDepart 子部门
* @param departIdList 部门id集合
* @param idList 需要查询sql的部门id集合
*/
private void findSysDepartPath(SysDepartExportVo departVo, List<String> path, Integer tenantId, List<SysDepartExportVo> childrenDepart, List<String> departIdList) {
private void findSysDepartPath(SysDepartExportVo departVo, List<String> path, Integer tenantId, List<SysDepartExportVo> childrenDepart, List<String> departIdList, List<String> idList) {
//step 1.查询子部门的数据
//获取租户id和部门父id获取的部门数据
List<SysDepartExportVo> departList = departMapper.getSysDepartList(departVo.getId(), tenantId);
List<SysDepartExportVo> departList = departMapper.getSysDepartList(departVo.getId(), tenantId, idList);
//部门为空判断
if (departList == null || departList.size() <= 0) {
//判断最后一个子部门是否已拼接
@ -1379,7 +1381,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
childrenDepart.add(departVo);
}
//step 3.递归查询子路径,直到找不到为止
findSysDepartPath(exportDepartVo, cPath, tenantId, childrenDepart, departIdList);
findSysDepartPath(exportDepartVo, cPath, tenantId, childrenDepart, departIdList, idList);
}
}
//========================end 系统下部门与人员导入 ==================================================================

View File

@ -23,6 +23,7 @@ import org.jeecg.common.system.vo.DictQuery;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.SqlInjectionUtil;
import org.jeecg.common.util.dynamic.db.DbTypeUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
import org.jeecg.modules.system.entity.SysDict;
@ -94,6 +95,11 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
// 4.执行SQL 查询是否存在值
try{
//update-begin---author:chenrui ---date:20240715 for[TV360X-49]postgres日期、年月日时分秒唯一校验报错------------
if(DbTypeUtils.dbTypeIsPostgre(CommonUtils.getDatabaseTypeEnum())){
duplicateCheckVo.setFieldName("CAST("+duplicateCheckVo.getFieldName()+" as text)");
}
//update-end---author:chenrui ---date:20240715 for[TV360X-49]postgres日期、年月日时分秒唯一校验报错------------
if (StringUtils.isNotBlank(duplicateCheckVo.getDataId())) {
// [1].编辑页面校验
count = sysDictMapper.duplicateCheckCountSql(duplicateCheckVo);
@ -504,8 +510,9 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
// }
@Override
public List<DictModel> queryLittleTableDictItems(String tableSql, String text, String code, String condition, String keyword, int pageSize) {
Page<DictModel> page = new Page<DictModel>(1, pageSize);
public List<DictModel> queryLittleTableDictItems(String tableSql, String text, String code, String condition, String keyword, int pageNo, int pageSize) {
int current = oConvertUtils.getInt(pageNo, 1);
Page<DictModel> page = new Page<DictModel>(current, pageSize);
page.setSearchCount(false);
//为了防止sqljeecg提供了防注入的方法可以在拼接 SQL 语句时自动对参数进行转义避免SQL注入攻击
@ -743,7 +750,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
}
@Override
public List<DictModel> loadDict(String dictCode, String keyword, Integer pageSize) {
public List<DictModel> loadDict(String dictCode, String keyword, Integer pageNo, Integer pageSize) {
// 【QQYUN-6533】表字典白名单check
sysBaseAPI.dictTableWhiteListCheckByDict(dictCode);
// 1.表字典黑名单check
@ -777,7 +784,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
}
List<DictModel> ls;
if (pageSize != null) {
ls = this.queryLittleTableDictItems(params[0], params[1], params[2], condition, keyword, pageSize);
ls = this.queryLittleTableDictItems(params[0], params[1], params[2], condition, keyword, pageNo,pageSize);
} else {
ls = this.queryAllTableDictItems(params[0], params[1], params[2], condition, keyword);
}
@ -834,6 +841,30 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
redisUtil.removeAll(CacheConstant.SYS_DICT_CACHE + "::" + dict.getDictCode());
}
/**
* 还原逻辑删除
* @param ids
*/
@Override
public boolean revertLogicDeleted(List<String> ids) {
return baseMapper.revertLogicDeleted(ids) > 0;
}
/**
* 彻底删除
* @param ids
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean removeLogicDeleted(List<String> ids) {
// 1. 删除字典
int line = this.baseMapper.removeLogicDeleted(ids);
// 2. 删除字典选项配置
line += this.sysDictItemMapper.delete(new LambdaQueryWrapper<SysDictItem>().in(SysDictItem::getDictId, ids));
return line > 0;
}
/**
* 添加字典
* @param dictName

View File

@ -1,6 +1,7 @@
package org.jeecg.modules.system.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -14,14 +15,15 @@ import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.entity.SysGatewayRoute;
import org.jeecg.modules.system.mapper.SysGatewayRouteMapper;
import org.jeecg.modules.system.service.ISysGatewayRouteService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @Description: gateway路由管理
@ -37,7 +39,7 @@ public class SysGatewayRouteServiceImpl extends ServiceImpl<SysGatewayRouteMappe
private RedisTemplate<String, Object> redisTemplate;
private static final String STRING_STATUS = "status";
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MMdd");
@Override
public void addRoute2Redis(String key) {
List<SysGatewayRoute> ls = this.list(new LambdaQueryWrapper<SysGatewayRoute>());
@ -46,7 +48,13 @@ public class SysGatewayRouteServiceImpl extends ServiceImpl<SysGatewayRouteMappe
@Override
public void deleteById(String id) {
//1.将状态修改成禁用
SysGatewayRoute route = new SysGatewayRoute();
route.setId(id);
route.setStatus(0);
this.baseMapper.updateById(route);
this.removeById(id);
//2.刷新路由
this.resreshRouter(id);
}
@ -71,6 +79,8 @@ public class SysGatewayRouteServiceImpl extends ServiceImpl<SysGatewayRouteMappe
route.setRouterId(json.getString("routerId"));
route.setName(json.getString("name"));
route.setPredicates(json.getString("predicates"));
//初始化删除状态
route.setDelFlag(CommonConstant.DEL_FLAG_0);
String filters = json.getString("filters");
if (ObjectUtil.isEmpty(filters)) {
filters = "[]";
@ -109,5 +119,70 @@ public class SysGatewayRouteServiceImpl extends ServiceImpl<SysGatewayRouteMappe
redisTemplate.opsForValue().set(CacheConstant.GATEWAY_ROUTES, null);
}
/**
* 还原逻辑删除
* @param ids
*/
@Override
public void revertLogicDeleted(List<String> ids) {
this.baseMapper.revertLogicDeleted(ids);
resreshRouter(null);
}
/**
* 彻底删除
* @param ids
*/
@Override
public void deleteLogicDeleted(List<String> ids) {
this.baseMapper.deleteLogicDeleted(ids);
resreshRouter(ids.get(0));
}
/**
* 路由复制
* @param id
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public SysGatewayRoute copyRoute(String id) {
log.info("--gateway 路由复制--");
SysGatewayRoute targetRoute = new SysGatewayRoute();
try {
SysGatewayRoute sourceRoute = this.baseMapper.selectById(id);
//1.复制路由
BeanUtils.copyProperties(sourceRoute,targetRoute);
//1.1 获取当前日期
String formattedDate = dateFormat.format(new Date());
String copyRouteName = sourceRoute.getName() + "_copy_";
//1.2 判断数据库是否存在
Long count = this.baseMapper.selectCount(new LambdaQueryWrapper<SysGatewayRoute>().eq(SysGatewayRoute::getName, copyRouteName + formattedDate));
//1.3 新的路由名称
copyRouteName += count > 0?RandomUtil.randomNumbers(4):formattedDate;
targetRoute.setId(null);
targetRoute.setName(copyRouteName);
targetRoute.setCreateTime(new Date());
targetRoute.setStatus(0);
targetRoute.setDelFlag(CommonConstant.DEL_FLAG_0);
this.baseMapper.insert(targetRoute);
//2.刷新路由
resreshRouter(null);
} catch (Exception e) {
log.error("路由配置解析失败", e);
resreshRouter(null);
e.printStackTrace();
}
return targetRoute;
}
/**
* 查询删除列表
* @return
*/
@Override
public List<SysGatewayRoute> getDeletelist() {
return baseMapper.queryDeleteList();
}
}

View File

@ -174,7 +174,15 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
//update-end---author:liusq ---date:20231215 for逗号分割多个用户翻译问题------------
//update-begin---author:wangshuai ---date:20220608 for[VUEN-1238]邮箱回复时发送到显示的为用户id------------
if(oConvertUtils.isNotEmpty(id)){
query.eq(SysUser::getId, id);
//update-begin---author:wangshuai ---date:2024-06-25 for【TV360X-1482】写信选择用户后第一次回显没翻译------------
String COMMA = ",";
if(oConvertUtils.isNotEmpty(isMultiTranslate) && id.contains(COMMA)){
String[] idArr = id.split(COMMA);
query.in(SysUser::getId, Arrays.asList(idArr));
}else {
query.eq(SysUser::getId, id);
}
//update-end---author:wangshuai ---date:2024-06-25 for【TV360X-1482】写信选择用户后第一次回显没翻译------------
}
//update-end---author:wangshuai ---date:20220608 for[VUEN-1238]邮箱回复时发送到显示的为用户id------------
//update-begin---author:wangshuai ---date:20220902 for[VUEN-2121]临时用户不能直接显示------------

View File

@ -55,11 +55,9 @@ import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
@ -105,13 +103,13 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
@Autowired
private SysThirdAccountMapper sysThirdAccountMapper;
@Autowired
ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
@Autowired
ThirdAppDingtalkServiceImpl dingtalkService;
ThirdAppDingtalkServiceImpl dingtalkService;
@Autowired
ISysRoleIndexService sysRoleIndexService;
ISysRoleIndexService sysRoleIndexService;
@Autowired
SysTenantMapper sysTenantMapper;
SysTenantMapper sysTenantMapper;
@Autowired
private SysUserTenantMapper relationMapper;
@Autowired
@ -122,10 +120,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
private SysPositionMapper sysPositionMapper;
@Autowired
private SystemSendMsgHandle systemSendMsgHandle;
@Autowired
private ISysThirdAccountService sysThirdAccountService;
@Autowired
private RedisUtil redisUtil;
@ -206,7 +202,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
List<String> positionList = sysUserPositionMapper.getPositionIdByUserTenantId(item.getId(),posTenantId);
//update-end---author:wangshuai---date:2023-11-15---for:【QQYUN-7028】用户职务保存后未回显---
//update-end---author:wangshuai ---date:20230228 for[QQYUN-4354]加入更多字段:当前加入时间应该取当前租户的/职位也是当前租户下的------------
item.setPost(CommonUtils.getSplitText(positionList, SymbolConstant.COMMA));
item.setPost(CommonUtils.getSplitText(positionList,SymbolConstant.COMMA));
//update-begin---author:wangshuai---date:2023-10-08---for:【QQYUN-6668】钉钉部门和用户同步我怎么知道哪些用户是双向绑定成功的---
//是否根据租户隔离(敲敲云用户列表专用,用于展示是否同步钉钉)
@ -269,13 +265,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
@CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
@Transactional(rollbackFor = Exception.class)
public boolean deleteUser(String userId) {
//update-begin---author:wangshuai---date:2024-01-16---for:【QQYUN-7974】admin用户禁止删除---
//1.验证当前用户是管理员账号 admin
//验证用户是否为管理员
this.checkUserAdminRejectDel(userId);
//update-end---author:wangshuai---date:2024-01-16---for:【QQYUN-7974】admin用户禁止删除---
//2.删除用户
//1.删除用户
this.removeById(userId);
return false;
}
@ -284,9 +274,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
@CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
@Transactional(rollbackFor = Exception.class)
public boolean deleteBatchUsers(String userIds) {
//1.验证当前用户是管理员账号 admin
this.checkUserAdminRejectDel(userIds);
//2.删除用户
//1.删除用户
this.removeByIds(Arrays.asList(userIds.split(",")));
return false;
}
@ -490,7 +478,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
* @return
*/
@Override
public IPage<SysUser> getUserByDepId(Page<SysUser> page, String departId, String username) {
public IPage<SysUser> getUserByDepId(Page<SysUser> page, String departId,String username) {
return userMapper.getUserByDepId(page, departId,username);
}
@ -533,7 +521,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
//根据部门orgCode查询部门需要将职位id进行传递
for (SysUserSysDepartModel model:list) {
List<String> positionList = sysUserPositionMapper.getPositionIdByUserId(model.getId());
model.setPost(CommonUtils.getSplitText(positionList, SymbolConstant.COMMA));
model.setPost(CommonUtils.getSplitText(positionList,SymbolConstant.COMMA));
}
Integer total = baseMapper.getUserByOrgCodeTotal(orgCode, userParams);
@ -779,19 +767,21 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
public void editUser(SysUser user, String roles, String departs, String relTenantIds) {
public void editUser(SysUser user, String roles, String departs, String relTenantIds, String updateFromPage) {
//获取用户编辑前台传过来的租户id
this.editUserTenants(user.getId(),relTenantIds);
//step.1 修改用户基础信息
this.updateById(user);
//step.2 修改角色
//处理用户角色 先删后加
sysUserRoleMapper.delete(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, user.getId()));
if(oConvertUtils.isNotEmpty(roles)) {
String[] arr = roles.split(",");
for (String roleId : arr) {
SysUserRole userRole = new SysUserRole(user.getId(), roleId);
sysUserRoleMapper.insert(userRole);
if (oConvertUtils.isEmpty(updateFromPage) || !"deptUsers".equalsIgnoreCase(updateFromPage)) {
// 处理用户角色 先删后加 , 如果是在部门用户页面修改用户,不处理用户角色,因为该页面无法编辑用户角色.
sysUserRoleMapper.delete(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, user.getId()));
if (oConvertUtils.isNotEmpty(roles)) {
String[] arr = roles.split(",");
for (String roleId : arr) {
SysUserRole userRole = new SysUserRole(user.getId(), roleId);
sysUserRoleMapper.insert(userRole);
}
}
}
@ -842,7 +832,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
}
@Override
@Cacheable(cacheNames= CacheConstant.SYS_USERS_CACHE, key="#username")
@Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username")
@SensitiveEncode
public LoginUser getEncodeUserInfo(String username){
if(oConvertUtils.isEmpty(username)) {
@ -885,6 +875,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
SysUserTenant userTenant = new SysUserTenant();
userTenant.setStatus(CommonConstant.USER_TENANT_QUIT);
userTenantMapper.update(userTenant,query);
//update-end---author:wangshuai ---date:20230111 for[QQYUN-3951]租户用户离职重构------------
}
@Override
@ -903,7 +894,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
* @return
*/
@Override
public Result<JSONObject> setLoginTenant(SysUser sysUser, JSONObject obj, String username, Result<JSONObject> result){
public Result<JSONObject> setLoginTenant(SysUser sysUser, JSONObject obj, String username, Result<JSONObject> result){
// update-begin--Author:sunjianlei Date:20210802 for获取用户租户信息
//用户有哪些租户
// List<SysTenant> tenantList = null;
@ -1343,7 +1334,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
* @param orgName
* @param orgId
*/
private void getParentDepart(SysDepart depart, List<String> orgName, List<String> orgId){
private void getParentDepart(SysDepart depart,List<String> orgName,List<String> orgId){
String pid = depart.getParentId();
orgName.add(0, depart.getDepartName());
orgId.add(0, depart.getId());
@ -1471,7 +1462,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
private void userPositionId(SysUser sysUser) {
if(null != sysUser){
List<String> positionList = sysUserPositionMapper.getPositionIdByUserId(sysUser.getId());
sysUser.setPost(CommonUtils.getSplitText(positionList, SymbolConstant.COMMA));
sysUser.setPost(CommonUtils.getSplitText(positionList,SymbolConstant.COMMA));
}
}
@ -1522,7 +1513,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
* @param departChargeUsers
* @param departId
*/
private void removeDepartmentManager(List<String> departChargeUserIdList, List<SysUser> departChargeUsers, String departId){
private void removeDepartmentManager(List<String> departChargeUserIdList,List<SysUser> departChargeUsers,String departId){
//移除部门负责人
for(String chargeUserId: departChargeUserIdList){
for(SysUser chargeUser: departChargeUsers){
@ -1910,6 +1901,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
}
}
@Override
public void changePhone(JSONObject json, String username) {
String smscode = json.getString("smscode");
@ -1943,7 +1935,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
userMapper.updateById(sysUser);
}
}
/**
* 验证手机号
*
@ -1963,7 +1955,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
//验证完成之后清空手机验证码
redisUtil.removeAll(phoneKey);
}
@Override
public void sendChangePhoneSms(JSONObject jsonObject, String username, String ipAddress) {
String type = jsonObject.getString("type");
@ -2006,7 +1998,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
log.warn("--------[警告] IP地址:{}, 短信接口请求太多-------", clientIp);
throw new JeecgBootException("短信接口请求太多,请稍后再试!", CommonConstant.PHONE_SMS_FAIL_CODE);
}
//随机数
String captcha = RandomUtil.randomNumbers(6);
JSONObject obj = new JSONObject();

View File

@ -28,6 +28,7 @@ import org.jeecg.common.config.TenantContext;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.constant.enums.MessageTypeEnum;
import org.jeecg.common.exception.JeecgBootBizTipException;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.*;
@ -1147,6 +1148,11 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
}
// 获取【钉钉】所有的部门
List<Department> departments = JdtDepartmentAPI.listAll(accessToken);
//update-begin---author:wangshuai---date:2024-06-25---for:【TV360X-1316】钉钉同步提示消息不正确---
if(departments.isEmpty()){
throw new JeecgBootBizTipException("请查看配置参数和白名单是否配置!");
}
//update-end---author:wangshuai---date:2024-06-25---for:【TV360X-1316】钉钉同步提示消息不正确---
String username = JwtUtil.getUserNameByToken(SpringContextUtils.getHttpServletRequest());
List<JdtDepartmentTreeVo> departmentTreeList = JdtDepartmentTreeVo.listToTree(departments);
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
@ -1182,7 +1188,11 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
try {
userMapper.updateById(updateSysUser);
String str = String.format("用户 %s(%s) 更新成功!", updateSysUser.getRealname(), updateSysUser.getUsername());
syncInfo.addSuccessInfo(str);
//update-begin---author:wangshuai---date:2024-06-24---for:【TV360X-1317】钉钉同步 同步成功之后 重复提示---
if(!syncInfo.getSuccessInfo().contains(str)){
syncInfo.addSuccessInfo(str);
}
//update-end---author:wangshuai---date:2024-06-24---for:【TV360X-1317】钉钉同步 同步成功之后 重复提示---
} catch (Exception e) {
this.syncUserCollectErrInfo(e, user, syncInfo);
}

View File

@ -26,6 +26,38 @@
}
return "";
}
<#elseif po.classType=='switch'>
<#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>
@Excel(name = "${po.filedComment}", width = 15,replace = {"是_${switch_extend_arr1}","否_${switch_extend_arr2}"} )
@ApiModelProperty(value = "${po.filedComment}")
private ${po.fieldType} ${po.fieldName};
<#elseif po.classType=='pca'>
@Excel(name = "${po.filedComment}", width = 15,exportConvert=true,importConvert = true )
@ApiModelProperty(value = "${po.filedComment}")
private ${po.fieldType} ${po.fieldName};
public String convertis${po.fieldName?cap_first}() {
return SpringContextUtils.getBean(ProvinceCityArea.class).getText(${po.fieldName});
}
public void convertset${po.fieldName?cap_first}(String text) {
this.${po.fieldName} = SpringContextUtils.getBean(ProvinceCityArea.class).getCode(text);
}
<#elseif po.classType=='cat_tree'>
<#assign list_field_dictCode=', dictTable = "sys_category", dicText = "name", dicCode = "id"'>
@Excel(name = "${po.filedComment}", width = 15${list_field_dictCode})
@ApiModelProperty(value = "${po.filedComment}")
private ${po.fieldType} ${po.fieldName};
<#else>
@Schema(description = "${po.filedComment}")
<#if po.fieldDbName == 'del_flag'>

View File

@ -13,6 +13,9 @@
<#if need_popup>
JPopup,
</#if>
<#if need_popup_dict>
JPopupDict,
</#if>
<#if need_category>
JCategorySelect,
</#if>

View File

@ -9,7 +9,7 @@
<#assign form_field_dictCode="${po.dictField}">
</#if>
<a-col :span="${form_span}">
<a-form-item label="${po.filedComment}" v-bind="validateInfos.${autoStringSuffixForModel(po)}">
<a-form-item label="${po.filedComment}" v-bind="validateInfos.${autoStringSuffixForModel(po)}" id="${formEntityName}-${autoStringSuffixForModel(po)}" name="${autoStringSuffixForModel(po)}">
<#if po.classType =='date'>
<a-date-picker placeholder="请选择${po.filedComment}" <#if po.extendParams?exists && po.extendParams.picker?exists>picker="${po.extendParams.picker}"</#if> v-model:value="formData.${po.fieldName}" value-format="YYYY-MM-DD" style="width: 100%" <#if po.readonly=='Y'>disabled</#if> allow-clear />
<#elseif po.classType =='datetime'>
@ -33,9 +33,18 @@
:multi="${po.extendParams.popupMulti?c}"
:setFieldsValue="setFieldsValue"
<#if po.readonly=='Y'>disabled</#if><#rt> allow-clear />
<#elseif po.classType =='popup_dict'>
<#assign need_popup_dict = true>
<#assign sourceFields = po.dictField?default("")?trim?split(",")/>
<#assign targetFields = po.dictText?default("")?trim?split(",")/>
<j-popup-dict
placeholder="请选择${po.filedComment}"
v-model:value="formData.${po.fieldName}"
dictCode="${po.dictTable},${po.dictText},${po.dictField}"
:multi="${po.extendParams.popupMulti?c}" <#if po.readonly=='Y'>disabled</#if> />
<#elseif po.classType =='sel_depart'>
<#assign need_dept = true>
<j-select-dept v-model:value="formData.${po.fieldName}" :multiple="${po.extendParams.multi?default('true')}" checkStrictly <#if po.readonly=='Y'>disabled</#if> allow-clear />
<j-select-dept v-model:value="formData.${po.fieldName}" <#if po.extendParams?exists && po.extendParams.text?exists>labelKey="${po.extendParams.text}"</#if> <#if po.extendParams?exists && po.extendParams.store?exists>rowKey="${po.extendParams.store}"</#if> <#if po.readonly=='Y'>disabled</#if> :multiple="${po.extendParams.multi?default('true')}" checkStrictly <#if po.readonly=='Y'>disabled</#if> allow-clear />
<#elseif po.classType =='switch'>
<#assign need_switch = true>
<j-switch v-model:value="formData.${po.fieldName}" <#if po.dictField != 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch>
@ -50,7 +59,7 @@
<#elseif po.classType =='sel_user'>
<#assign need_dept_user = true>
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
<j-select-user v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if> allow-clear />
<j-select-user v-model:value="formData.${po.fieldName}" <#if po.extendParams?exists && po.extendParams.text?exists>labelKey="${po.extendParams.text}"</#if> <#if po.extendParams?exists && po.extendParams.store?exists>rowKey="${po.extendParams.store}"</#if> <#if po.readonly=='Y'>disabled</#if> allow-clear />
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
<#elseif po.classType =='textarea'>
<a-textarea v-model:value="formData.${autoStringSuffixForModel(po)}" :rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>
@ -82,7 +91,7 @@
<j-image-upload <#if po.uploadnum??>:fileMax=${po.uploadnum}<#else>:fileMax="0"</#if> v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>></j-image-upload>
<#elseif po.classType=='umeditor'>
<#assign need_editor = true>
<j-editor v-model:value="formData.${autoStringSuffixForModel(po)}" <#if po.readonly=='Y'>disabled</#if>/>
<j-editor v-model:value="formData.${autoStringSuffixForModel(po)}" <#if po.readonly=='Y'>disabled</#if> :autoFocus="false"/>
<#elseif po.fieldDbType=='Blob'>
<a-input v-model:value="formData.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if> allow-clear ></a-input>
<#elseif po.classType == 'sel_tree'>

View File

@ -13,6 +13,9 @@
<#if need_popup>
import JPopup from '/@/components/Form/src/jeecg/components/JPopup.vue';
</#if>
<#if need_popup_dict>
import JPopupDict from '/@/components/Form/src/jeecg/components/JPopupDict.vue';
</#if>
<#if need_category>
import JCategorySelect from '/@/components/Form/src/jeecg/components/JCategorySelect.vue';
</#if>
@ -47,4 +50,7 @@
</#if>
<#if need_checkbox>
import JCheckbox from "/@/components/Form/src/jeecg/components/JCheckbox.vue";
</#if>
<#if need_range_number>
import JRangeNumber from "/@/components/Form/src/jeecg/components/JRangeNumber.vue";
</#if>

View File

@ -9,9 +9,11 @@
<#assign query_field_dictCode="">
<#if po.dictTable?default("")?trim?length gt 1>
<#assign need_select_tag = true>
<#assign need_multi = true>
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
<#elseif po.dictField?default("")?trim?length gt 1>
<#assign need_select_tag = true>
<#assign need_multi = true>
<#assign query_field_dictCode="${po.dictField}">
</#if>
<#if po.queryMode=='single'>
@ -56,66 +58,41 @@
<#if query_field_no gt 1> </#if>]"
<#if query_field_no gt 1> </#if>:multi="${po.extendParams.popupMulti?c}"
<#if query_field_no gt 1> </#if>:setFieldsValue="setFieldsValue" allow-clear />
<#elseif po.classType=='popup_dict'>
<#if query_field_no gt 1> </#if><j-popup-dict
<#if query_field_no gt 1> </#if>placeholder="请选择${po.filedComment}"
<#if query_field_no gt 1> </#if>v-model:value="queryParam.${po.fieldName}"
<#if query_field_no gt 1> </#if>dictCode="${po.dictTable},${po.dictText},${po.dictField}"
<#if query_field_no gt 1> </#if>:multi="${po.extendParams.popupMulti?c}"
<#if query_field_no gt 1> </#if><#if po.readonly=='Y'>disabled</#if> />
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
<#if po.dictTable?default("")?trim?length gt 1>
<#if query_field_no gt 1> </#if><j-dict-select-tag placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" dictCode="${po.dictTable},${po.dictText},${po.dictField}" allow-clear />
<#elseif po.dictField?default("")?trim?length gt 1>
<#if query_field_no gt 1> </#if><j-dict-select-tag placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" dictCode="${po.dictField}" allow-clear />
<#else>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
<#if po.dictTable?default("")?trim?length gt 1>
<#if query_field_no gt 1> </#if><j-select-multiple placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" dictCode="${po.dictTable},${po.dictText},${po.dictField}" allow-clear />
<#elseif po.dictField?default("")?trim?length gt 1>
<#if query_field_no gt 1> </#if><j-select-multiple placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" dictCode="${po.dictField}" allow-clear />
<#else>
<#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${po.fieldName}" allow-clear ></a-input>
</#if>
</#if>
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
<#if query_field_no gt 1> </#if><a-input-number placeholder="请输入${po.filedComment}" v-model:value="queryParam.${po.fieldName}"></a-input-number>
<#else>
<#else>
<#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${autoStringSuffixForModel(po)}" allow-clear ></a-input>
</#if>
</#if>
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if></a-col>
<#else>
<#if query_field_no gt 1> </#if><a-col :lg="6">
<#if query_field_no gt 1> </#if><a-form-item>
<#if query_field_no gt 1> </#if><template #label><span title="${po.filedComment}"><#if po.filedComment?default("")?trim?length gt 4>${po.filedComment?substring(0,4)}<#else>${po.filedComment}</#if></span></template>
<#if query_field_no gt 1> </#if><a-form-item name="${autoStringSuffixForModel(po)}">
<#if query_field_no gt 1> </#if><template #label><span title="${po.filedComment}"><#if po.filedComment?default("")?trim?length gt 4>${po.filedComment?substring(0,4)}<#else>${po.filedComment}</#if></span></template>
<#if po.classType=='date'>
<#if query_field_no gt 1> </#if><div style="display: flex">
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_begin" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><a-date-picker value-format="YYYY-MM-DD" placeholder="请选择开始日期" <#if po.extendParams?exists && po.extendParams.picker?exists>picker="${po.extendParams.picker}"</#if> v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust" allow-clear />
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if><span class="query-group-split-cust">~</span>
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_end" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><a-date-picker value-format="YYYY-MM-DD" placeholder="请选择结束日期" <#if po.extendParams?exists && po.extendParams.picker?exists>picker="${po.extendParams.picker}"</#if> v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust" allow-clear />
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if></div>
<#if query_field_no gt 1> </#if><a-range-picker value-format="YYYY-MM-DD" <#if po.extendParams?exists && po.extendParams.picker?exists>picker="${po.extendParams.picker}"</#if> v-model:value="queryParam.${po.fieldName}" class="query-group-cust"/>
<#elseif po.classType=='time'>
<#if query_field_no gt 1> </#if><div style="display: flex">
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_begin" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><time-picker value-format="HH:mm:ss" placeholder="请选择开始时间" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust" allow-clear />
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if><span class="query-group-split-cust">~</span>
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_end" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><time-picker value-format="HH:mm:ss" placeholder="请选择结束日期" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust" allow-clear />
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if></div>
<#if query_field_no gt 1> </#if><a-time-range-picker value-format="HH:mm:ss" v-model:value="queryParam.${po.fieldName}" class="query-group-cust" />
<#elseif po.classType=='datetime'>
<#if query_field_no gt 1> </#if><div style="display: flex">
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_begin" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><a-date-picker showTime value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust" allow-clear />
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if><span class="query-group-split-cust">~</span>
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_end" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><a-date-picker showTime value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust" allow-clear />
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if></div>
<#if query_field_no gt 1> </#if><a-range-picker showTime value-format="YYYY-MM-DD HH:mm:ss" v-model:value="queryParam.${po.fieldName}" class="query-group-cust"/>
<#else>
<#if query_field_no gt 1> </#if><div style="display: flex">
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_begin" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><a-input placeholder="请输入最小值" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust" allow-clear ></a-input>
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if><span class="query-group-left query-group-split-cust">~</span>
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_end" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><a-input placeholder="请输入最大值" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust" allow-clear ></a-input>
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if></div>
<#if query_field_no gt 1> </#if><JRangeNumber v-model:value="queryParam.${po.fieldName}" class="query-group-cust"></JRangeNumber>
</#if>
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if></a-col>

View File

@ -1,10 +1,10 @@
-- 注意该页面对应的前台目录为views/${entityPackage}文件夹下
-- 注意该页面对应的前台目录为views/${entityPackagePath}文件夹下
-- 如果你想更改到其他目录请修改sql中component字段对应的值
<#assign id = '${.now?string["yyyyMMddhhmmSSsss"]}0'>
INSERT INTO sys_permission(id, parent_id, name, url, component, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_route, is_leaf, keep_alive, hidden, hide_tab, description, status, del_flag, rule_flag, create_by, create_time, update_by, update_time, internal_or_external)
VALUES ('${id}', NULL, '${tableVo.ftlDescription}', '/${entityPackage}/${entityName?uncap_first}List', '${entityPackage}/${entityName}List', NULL, NULL, 0, NULL, '1', 0.00, 0, NULL, 1, 0, 0, 0, 0, NULL, '1', 0, 0, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0);
VALUES ('${id}', NULL, '${tableVo.ftlDescription}', '/${entityPackagePath}/${entityName?uncap_first}List', '${entityPackagePath}/${entityName}List', NULL, NULL, 0, NULL, '1', 0.00, 0, NULL, 1, 0, 0, 0, 0, NULL, '1', 0, 0, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0);
-- 权限控制sql
-- 新增

View File

@ -149,6 +149,8 @@
<#-- update-begin---author:chenrui ---date:20231228 for:fix 带条件字典存在单引号导致js编译错误---------- -->
<#elseif po.dictField?default("")?trim?length gt 1>
<#assign dictCode="dictCode: '${po.dictField}'">
<#else>
<#assign dictCode="dictCode: ''">
</#if>
<#if po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='checkbox' || po.classType=='radio'>
@ -229,4 +231,19 @@
</#if>
</#if>
<#return flag>
</#function>
<#-- vue3 native 获取范围字段 -->
<#function getRangeField(columns) >
<#assign rangeField = "">
<#list columns as po>
<#if po.isQuery=='Y'>
<#if po.queryMode!='single'>
<#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal' || po.classType=='time' || po.classType=='date' || po.classType=='datetime'>
<#assign rangeField = rangeField + "${po.fieldName},">
</#if>
</#if>
</#if>
</#list>
<#return rangeField>
</#function>

View File

@ -1,6 +1,7 @@
package ${bussiPackage}.${entityPackage}.controller;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@ -11,6 +12,7 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.query.QueryRuleEnum;
import org.jeecg.common.util.oConvertUtils;
import ${bussiPackage}.${entityPackage}.entity.${entityName};
import ${bussiPackage}.${entityPackage}.service.I${entityName}Service;
@ -37,10 +39,14 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;
<#assign bpm_flag=false>
<#assign has_multi_query_field=false>
<#list originalColumns as po>
<#if po.fieldDbName=='bpm_status'>
<#assign bpm_flag=true>
</#if>
<#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')>
<#assign has_multi_query_field=true>
</#if>
</#list>
/**
@ -51,7 +57,7 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
*/
@Tag(name="${tableVo.ftlDescription}")
@RestController
@RequestMapping("/${entityPackage}/${entityName?uncap_first}")
@RequestMapping("/${entityPackagePath}/${entityName?uncap_first}")
@Slf4j
public class ${entityName}Controller extends JeecgController<${entityName}, I${entityName}Service> {
@Autowired
@ -73,7 +79,19 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap());
<#if has_multi_query_field>
// 自定义查询规则
Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
// 自定义多选的查询规则为LIKE_WITH_OR
<#list originalColumns as po>
<#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')>
customeRuleMap.put("${po.fieldName}", QueryRuleEnum.LIKE_WITH_OR);
</#if>
</#list>
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap(),customeRuleMap);
<#else>
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap());
</#if>
Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize);
IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper);
return Result.OK(pageList);

View File

@ -9,6 +9,8 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableLogic;
import org.jeecg.common.constant.ProvinceCityArea;
import org.jeecg.common.util.SpringContextUtils;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
@ -33,6 +35,7 @@ public class ${entityName} implements Serializable {
private static final long serialVersionUID = 1L;
<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']>
<#assign excel_ignore_classType_arr=['pca','switch','cat_tree']>
<#list originalColumns as po>
<#-- 生成字典Code -->
<#assign list_field_dictCode="">
@ -68,7 +71,7 @@ public class ${entityName} implements Serializable {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
</#if>
<#else>
<#if !excel_ignore_arr?seq_contains("${po.fieldName}")>
<#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")>
@Excel(name = "${po.filedComment}", width = 15${list_field_dictCode})
</#if>
</#if>

View File

@ -55,9 +55,9 @@
model: {},
backRouteName:'index',
url: {
queryById: "/${entityPackage}/${entityName?uncap_first}/queryById",
add: "/${entityPackage}/${entityName?uncap_first}/add",
edit: "/${entityPackage}/${entityName?uncap_first}/edit",
queryById: "/${entityPackagePath}/${entityName?uncap_first}/queryById",
add: "/${entityPackagePath}/${entityName?uncap_first}/add",
edit: "/${entityPackagePath}/${entityName?uncap_first}/edit",
},
}
},

View File

@ -31,7 +31,7 @@
return {
CustomBar:this.CustomBar,
NavBarColor:this.NavBarColor,
url: "/${entityPackage}/${entityName?uncap_first}/list",
url: "/${entityPackagePath}/${entityName?uncap_first}/list",
};
},
methods: {

View File

@ -318,11 +318,11 @@
}
],
url: {
list: "/${entityPackage}/${entityName?uncap_first}/list",
delete: "/${entityPackage}/${entityName?uncap_first}/delete",
deleteBatch: "/${entityPackage}/${entityName?uncap_first}/deleteBatch",
exportXlsUrl: "/${entityPackage}/${entityName?uncap_first}/exportXls",
importExcelUrl: "${entityPackage}/${entityName?uncap_first}/importExcel",
list: "/${entityPackagePath}/${entityName?uncap_first}/list",
delete: "/${entityPackagePath}/${entityName?uncap_first}/delete",
deleteBatch: "/${entityPackagePath}/${entityName?uncap_first}/deleteBatch",
exportXlsUrl: "/${entityPackagePath}/${entityName?uncap_first}/exportXls",
importExcelUrl: "${entityPackagePath}/${entityName?uncap_first}/importExcel",
<#if bpm_flag>startProcess: '/act/process/extActProcess/startMutilProcess'</#if>
},
<#if bpm_flag>
@ -380,7 +380,7 @@
let params = {
flowCode: this.flowCode,
id: record.id,
formUrl: '${entityPackage}/modules/${entityName}Form',
formUrl: '${entityPackagePath}/modules/${entityName}Form',
formUrlMobile: ''
}
postAction(this.url.startProcess, params).then(res=>{

View File

@ -165,9 +165,9 @@
confirmLoading: false,
<#include "/common/validatorRulesTemplate/main.ftl">
url: {
add: "/${entityPackage}/${entityName?uncap_first}/add",
edit: "/${entityPackage}/${entityName?uncap_first}/edit",
queryById: "/${entityPackage}/${entityName?uncap_first}/queryById"
add: "/${entityPackagePath}/${entityName?uncap_first}/add",
edit: "/${entityPackagePath}/${entityName?uncap_first}/edit",
queryById: "/${entityPackagePath}/${entityName?uncap_first}/queryById"
}
}
},

View File

@ -21,9 +21,9 @@
<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-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<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>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -33,7 +33,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button>批量操作
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'">批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
@ -229,6 +229,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
}
]
}
@ -247,7 +248,8 @@
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
},
auth: '${entityPackage}:${tableName}:delete'
}
];
if(record.bpmStatus == '1'){
@ -272,7 +274,8 @@
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
},
auth: '${entityPackage}:${tableName}:delete'
}
]
</#if>
@ -286,7 +289,7 @@
let params = {
flowCode: 'dev_${tableName}_001',
id: record.id,
formUrl: '${entityPackage}/components/${entityName}Form',
formUrl: '${entityPackagePath}/components/${entityName}Form',
formUrlMobile: ''
}
await startProcess(params);
@ -318,6 +321,6 @@
</#if>
</script>
<style scoped>
<style lang="less" scoped>
<#include "/common/form/vue3SearchStyle.ftl">
</style>

View File

@ -4,13 +4,13 @@ import { useMessage } from "/@/hooks/web/useMessage";
const { createConfirm } = useMessage();
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 = '/${entityPackagePath}/${entityName?uncap_first}/list',
save='/${entityPackagePath}/${entityName?uncap_first}/add',
edit='/${entityPackagePath}/${entityName?uncap_first}/edit',
deleteOne = '/${entityPackagePath}/${entityName?uncap_first}/delete',
deleteBatch = '/${entityPackagePath}/${entityName?uncap_first}/deleteBatch',
importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel',
exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls',
}
/**
* 导出api

View File

@ -57,7 +57,7 @@ export const columns: BasicColumn[] = [
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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -104,6 +104,14 @@ export const searchFormSchema: FormSchema[] = [
<#elseif po.classType=='sel_user'>
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
component: 'JSelectUser',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
<#elseif po.classType=='switch'>
component: 'JSwitch',
@ -115,6 +123,14 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='list_multi'>
component: 'JSelectMultiple',
componentProps:{
@ -156,9 +172,16 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
component: 'JDictSelectTag',
component: 'JSelectMultiple',
componentProps:{
<#if po.dictTable?default("")?trim?length gt 1>
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
@ -276,8 +299,23 @@ export const formSchema: FormSchema[] = [
},
<#elseif po.classType =='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType =='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='switch'>
component: 'JSwitch',
componentProps:{
@ -299,8 +337,13 @@ export const formSchema: FormSchema[] = [
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
labelKey:'realname',
},
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='textarea'>
component: 'InputTextArea',
<#elseif po.classType=='list'>

View File

@ -41,7 +41,7 @@
});
let formData = {};
const queryByIdUrl = '/${entityPackage}/${entityName?uncap_first}/queryById';
const queryByIdUrl = '/${entityPackagePath}/${entityName?uncap_first}/queryById';
async function initFormData(){
let params = {id: props.formData.dataId};
const data = await defHttp.get({url: queryByIdUrl, params});

View File

@ -1,7 +1,7 @@
<#include "/common/utils.ftl">
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
<BasicForm @register="registerForm"/>
<BasicForm @register="registerForm" name="${entityName}Form" />
</BasicModal>
</template>
@ -16,8 +16,10 @@
const isUpdate = ref(true);
const isDetail = ref(false);
//表单配置
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
//labelWidth: 150,
const [registerForm, { setProps,resetFields, setFieldsValue, validate, scrollToField }] = useForm({
<#if tableVo.fieldRowNum == 1>
labelWidth: 150,
</#if>
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}
@ -51,6 +53,14 @@
closeModal();
//刷新列表
emit('success');
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
} finally {
setModalProps({confirmLoading: false});
}

View File

@ -1,3 +1,4 @@
<#include "/common/utils.ftl">
<template>
<div class="p-2">
<#assign query_field_no=0>
@ -9,6 +10,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -18,6 +20,8 @@
<#assign need_image_upload = false>
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign need_range_number = false>
<#assign is_range = false>
<#assign query_flag = false>
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
@ -52,11 +56,20 @@
<#if po.classType=='popup'>
<#assign need_popup = true>
</#if>
<#if po.classType=='popup_dict'>
<#assign need_popup_dict = true>
</#if>
<#if po.classType=='sel_tree'>
<#assign need_select_tree = true>
</#if>
<#if po.classType=='time'>
<#assign need_time = true>
</#if>
<#if po.queryMode!='single' && (po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal')>
<#assign need_range_number = true>
</#if>
<#if po.queryMode!='single'>
<#assign is_range = true>
</#if>
<#include "/common/form/native/vue3NativeSearch.ftl">
</#list>
@ -85,9 +98,9 @@
<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-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<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>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -97,7 +110,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button>批量操作
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'">批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
@ -158,6 +171,9 @@
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
</#if>
<#if is_range>
import { cloneDeep } from "lodash-es";
</#if>
const formRef = ref();
const queryParam = reactive<any>({});
@ -176,8 +192,13 @@
width: 120,
fixed: 'right',
},
beforeFetch: (params) => {
beforeFetch: async (params) => {
<#if is_range>
let rangerQuery = await setRangeQuery();
return Object.assign(params, rangerQuery);
<#else>
return Object.assign(params, queryParam);
</#if>
},
},
exportConfig: {
@ -270,6 +291,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
},
];
}
@ -289,7 +311,8 @@
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
},
auth: '${entityPackage}:${tableName}:delete'
}
];
if(record.bpmStatus == '1'){
@ -314,7 +337,8 @@
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
},
auth: '${entityPackage}:${tableName}:delete'
}
]
</#if>
@ -369,7 +393,7 @@
let params = {
flowCode: 'dev_${tableName}_001',
id: record.id,
formUrl: '${entityPackage}/components/${entityName}Form',
formUrl: '${entityPackagePath}/components/${entityName}Form',
formUrlMobile: ''
}
await startProcess(params);
@ -407,6 +431,32 @@
}
initDictConfig();
</#if>
<#if is_range>
let rangeField = '${getRangeField(columns)}'
/**
* 设置范围查询条件
*/
async function setRangeQuery(){
let queryParamClone = cloneDeep(queryParam);
if (rangeField) {
let fieldsValue = rangeField.split(',');
fieldsValue.forEach(item => {
if (queryParamClone[item]) {
let range = queryParamClone[item];
queryParamClone[item+'_begin'] = range[0];
queryParamClone[item+'_end'] = range[1];
delete queryParamClone[item];
} else {
queryParamClone[item+'_begin'] = '';
queryParamClone[item+'_end'] = '';
}
})
}
return queryParamClone;
}
</#if>
</script>
<style lang="less" scoped>

View File

@ -4,13 +4,13 @@ import { useMessage } from "/@/hooks/web/useMessage";
const { createConfirm } = useMessage();
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 = '/${entityPackagePath}/${entityName?uncap_first}/list',
save='/${entityPackagePath}/${entityName?uncap_first}/add',
edit='/${entityPackagePath}/${entityName?uncap_first}/edit',
deleteOne = '/${entityPackagePath}/${entityName?uncap_first}/delete',
deleteBatch = '/${entityPackagePath}/${entityName?uncap_first}/deleteBatch',
importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel',
exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls',
}
/**

View File

@ -57,7 +57,7 @@ export const columns: BasicColumn[] = [
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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',

View File

@ -3,7 +3,7 @@
<a-spin :spinning="confirmLoading">
<JFormContainer :disabled="disabled">
<template #detail>
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol" name="${entityName}Form">
<a-row>
<#assign need_category = false>
<#assign bpm_flag=false>
@ -14,6 +14,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -23,6 +24,7 @@
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign hasOnlyValidate = false>
<#assign need_range_number = false>
<#assign form_span = 24>
<#if tableVo.fieldRowNum==2>
<#assign form_span = 12>
@ -38,6 +40,7 @@
<#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'>
<#assign hasOnlyValidate = true>
</#if>
<#assign formEntityName>${entityName}Form</#assign>
<#include "/common/form/native/vue3NativeForm.ftl">
</#list>
<#if bpm_flag>
@ -64,7 +67,10 @@
<#if hasOnlyValidate == true>
import { duplicateValidate } from '/@/utils/helper/validator'
</#if>
<#if bpm_flag>
import { usePermission } from '/@/hooks/web/usePermission';
const { isDisabledAuth, hasPermission, initBpmFormData } = usePermission();
</#if>
const props = defineProps({
formDisabled: { type: Boolean, default: false },
formData: { type: Object, default: () => ({})},
@ -101,10 +107,11 @@
<#if bpm_flag>
onMounted(()=>{
initBpmFormData(props.formData);
initFormData();
});
//渲染流程表单数据
const queryByIdUrl = '/${entityPackage}/${entityName?uncap_first}/queryById';
const queryByIdUrl = '/${entityPackagePath}/${entityName?uncap_first}/queryById';
async function initFormData(){
if(props.formBpm === true){
let params = {id: props.formData.dataId};
@ -152,8 +159,18 @@
* 提交数据
*/
async function submitForm() {
// 触发表单验证
await validate();
try {
// 触发表单验证
await validate();
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
}
confirmLoading.value = true;
const isUpdate = ref<boolean>(false);
//时间格式化

View File

@ -61,7 +61,7 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
*/
@Tag(name="${tableVo.ftlDescription}")
@RestController
@RequestMapping("/${entityPackage}/${entityName?uncap_first}")
@RequestMapping("/${entityPackagePath}/${entityName?uncap_first}")
@Slf4j
public class ${entityName}Controller {
@Autowired

View File

@ -310,11 +310,11 @@
}
],
url: {
list: "/${entityPackage}/${entityName?uncap_first}/list",
delete: "/${entityPackage}/${entityName?uncap_first}/delete",
deleteBatch: "/${entityPackage}/${entityName?uncap_first}/deleteBatch",
exportXlsUrl: "/${entityPackage}/${entityName?uncap_first}/exportXls",
importExcelUrl: "${entityPackage}/${entityName?uncap_first}/importExcel",
list: "/${entityPackagePath}/${entityName?uncap_first}/list",
delete: "/${entityPackagePath}/${entityName?uncap_first}/delete",
deleteBatch: "/${entityPackagePath}/${entityName?uncap_first}/deleteBatch",
exportXlsUrl: "/${entityPackagePath}/${entityName?uncap_first}/exportXls",
importExcelUrl: "${entityPackagePath}/${entityName?uncap_first}/importExcel",
<#if bpm_flag>startProcess: '/act/process/extActProcess/startMutilProcess'</#if>
},
<#if bpm_flag>
@ -363,7 +363,7 @@
let params = {
flowCode: this.flowCode,
id: record.id,
formUrl: '${entityPackage}/modules/${entityName}Form',
formUrl: '${entityPackagePath}/modules/${entityName}Form',
formUrlMobile: ''
}
postAction(this.url.startProcess, params).then(res=>{

View File

@ -389,12 +389,12 @@
},
</#list>
url: {
add: "/${entityPackage}/${entityName?uncap_first}/add",
edit: "/${entityPackage}/${entityName?uncap_first}/edit",
queryById: "/${entityPackage}/${entityName?uncap_first}/queryById",
add: "/${entityPackagePath}/${entityName?uncap_first}/add",
edit: "/${entityPackagePath}/${entityName?uncap_first}/edit",
queryById: "/${entityPackagePath}/${entityName?uncap_first}/queryById",
<#list subTables as sub><#rt/>
${sub.entityName?uncap_first}: {
list: '/${entityPackage}/${entityName?uncap_first}/query${sub.entityName}ByMainId'
list: '/${entityPackagePath}/${entityName?uncap_first}/query${sub.entityName}ByMainId'
},
</#list>
}

View File

@ -52,7 +52,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
</#list>
@Tag(name="${tableVo.ftlDescription}")
@RestController
@RequestMapping("/${entityPackage}/${entityName?uncap_first}")
@RequestMapping("/${entityPackagePath}/${entityName?uncap_first}")
@Slf4j
public class ${entityName}Controller extends JeecgController<${entityName}, I${entityName}Service>{
@Autowired

View File

@ -8,6 +8,8 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableLogic;
import org.jeecg.common.constant.ProvinceCityArea;
import org.jeecg.common.util.SpringContextUtils;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
@ -29,6 +31,7 @@ public class ${entityName} implements Serializable {
private static final long serialVersionUID = 1L;
<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']>
<#assign excel_ignore_classType_arr=['pca','switch','cat_tree']>
<#list originalColumns as po>
<#-- 生成字典Code -->
<#assign list_field_dictCode="">
@ -64,7 +67,7 @@ public class ${entityName} implements Serializable {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
</#if>
<#else>
<#if !excel_ignore_arr?seq_contains("${po.fieldName}")>
<#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")>
@Excel(name = "${po.filedComment}", width = 15${list_field_dictCode})
</#if>
</#if>

View File

@ -299,13 +299,13 @@
}
],
url: {
list: "/${entityPackage}/${entityName?uncap_first}/rootList",
childList: "/${entityPackage}/${entityName?uncap_first}/childList",
getChildListBatch: "/${entityPackage}/${entityName?uncap_first}/getChildListBatch",
delete: "/${entityPackage}/${entityName?uncap_first}/delete",
deleteBatch: "/${entityPackage}/${entityName?uncap_first}/deleteBatch",
exportXlsUrl: "/${entityPackage}/${entityName?uncap_first}/exportXls",
importExcelUrl: "${entityPackage}/${entityName?uncap_first}/importExcel",
list: "/${entityPackagePath}/${entityName?uncap_first}/rootList",
childList: "/${entityPackagePath}/${entityName?uncap_first}/childList",
getChildListBatch: "/${entityPackagePath}/${entityName?uncap_first}/getChildListBatch",
delete: "/${entityPackagePath}/${entityName?uncap_first}/delete",
deleteBatch: "/${entityPackagePath}/${entityName?uncap_first}/deleteBatch",
exportXlsUrl: "/${entityPackagePath}/${entityName?uncap_first}/exportXls",
importExcelUrl: "${entityPackagePath}/${entityName?uncap_first}/importExcel",
},
expandedRowKeys:[],
hasChildrenField:"${hasChildrenField}",

View File

@ -142,8 +142,8 @@
confirmLoading: false,
<#include "/common/validatorRulesTemplate/main.ftl">
url: {
add: "/${entityPackage}/${entityName?uncap_first}/add",
edit: "/${entityPackage}/${entityName?uncap_first}/edit",
add: "/${entityPackagePath}/${entityName?uncap_first}/add",
edit: "/${entityPackagePath}/${entityName?uncap_first}/edit",
},
expandedRowKeys:[],
pidField:"${pidFieldName}"

View File

@ -26,9 +26,9 @@
<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-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleCreate" preIcon="ant-design:plus-outlined"> 新增</a-button>
<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>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
@ -39,7 +39,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button>批量操作
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'">批量操作
<Icon icon="ant-design:down-outlined"></Icon>
</a-button>
</a-dropdown>
@ -371,6 +371,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
},
{
label: '添加下级',
@ -392,9 +393,9 @@
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
];
if(record.bpmStatus == '1' || !record.bpmStatus){
dropDownAction.push({
@ -417,8 +418,9 @@
popConfirm: {
title: '确定删除吗?',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
]
</#if>
@ -432,7 +434,7 @@
let params = {
flowCode: 'dev_${tableName}_001',
id: record.id,
formUrl: '${entityPackage}/components/${entityName}Form',
formUrl: '${entityPackagePath}/components/${entityName}Form',
formUrlMobile: ''
}
await startProcess(params);
@ -442,6 +444,6 @@
</script>
<style scoped>
<style lang="less" scoped>
<#include "/common/form/vue3SearchStyle.ftl">
</style>

View File

@ -4,15 +4,15 @@ import { useMessage } from "/@/hooks/web/useMessage";
const { createConfirm } = useMessage();
enum Api {
list = '/${entityPackage}/${entityName?uncap_first}/rootList',
save='/${entityPackage}/${entityName?uncap_first}/add',
edit='/${entityPackage}/${entityName?uncap_first}/edit',
delete${entityName} = '/${entityPackage}/${entityName?uncap_first}/delete',
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',
list = '/${entityPackagePath}/${entityName?uncap_first}/rootList',
save='/${entityPackagePath}/${entityName?uncap_first}/add',
edit='/${entityPackagePath}/${entityName?uncap_first}/edit',
delete${entityName} = '/${entityPackagePath}/${entityName?uncap_first}/delete',
importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel',
exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls',
loadTreeData = '/${entityPackagePath}/${entityName?uncap_first}/loadTreeRoot',
getChildList = '/${entityPackagePath}/${entityName?uncap_first}/childList',
getChildListBatch = '/${entityPackagePath}/${entityName?uncap_first}/getChildListBatch',
}
/**

View File

@ -61,7 +61,7 @@ export const columns: BasicColumn[] = [
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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -109,6 +109,14 @@ export const searchFormSchema: FormSchema[] = [
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='switch'>
component: 'JSwitch',
componentProps:{
@ -118,6 +126,14 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='list_multi'>
component: 'JSelectMultiple',
componentProps:{
@ -159,6 +175,13 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType == 'sel_tree'>
component: 'JTreeSelect',
componentProps:{
@ -177,7 +200,7 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
component: 'JDictSelectTag',
component: 'JSelectMultiple',
componentProps:{
<#if po.dictTable?default("")?trim?length gt 1>
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
@ -294,8 +317,23 @@ export const formSchema: FormSchema[] = [
},
<#elseif po.classType =='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType =='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='switch'>
component: 'JSwitch',
componentProps:{
@ -317,8 +355,13 @@ export const formSchema: FormSchema[] = [
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
labelKey:'realname',
},
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='textarea'>
component: 'InputTextArea',
<#elseif po.classType=='list'>

View File

@ -41,7 +41,7 @@
});
let formData = {};
const queryByIdUrl = '/${entityPackage}/${entityName?uncap_first}/queryById';
const queryByIdUrl = '/${entityPackagePath}/${entityName?uncap_first}/queryById';
async function initFormData(){
let params = {id: props.formData.dataId};
const data = await defHttp.get({url: queryByIdUrl, params});

View File

@ -11,7 +11,7 @@
</#list>
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" :title="getTitle" @ok="handleSubmit">
<BasicForm @register="registerForm"/>
<BasicForm @register="registerForm" name="${entityName}Form" />
</BasicModal>
</template>
<script lang="ts" setup>
@ -29,7 +29,7 @@
// 当前编辑的数据
let model:Nullable<Recordable> = null;
//表单配置
const [registerForm, {setProps,resetFields, setFieldsValue, validate, updateSchema}] = useForm({
const [registerForm, { setProps,resetFields, setFieldsValue, validate, updateSchema, scrollToField }] = useForm({
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}},
@ -103,6 +103,14 @@
// 是否更改了父级节点
changeParent: model != null && (model['${pidFieldName}'] != values['${pidFieldName}']),
});
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
} finally {
setModalProps({confirmLoading: false});
}

View File

@ -20,6 +20,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -29,6 +30,8 @@
<#assign need_image_upload = false>
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign need_range_number = false>
<#assign is_range = false>
<#assign query_flag = false>
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
@ -63,11 +66,20 @@
<#if po.classType=='popup'>
<#assign need_popup = true>
</#if>
<#if po.classType=='popup_dict'>
<#assign need_popup_dict = true>
</#if>
<#if po.classType=='sel_tree'>
<#assign need_select_tree = true>
</#if>
<#if po.classType=='time'>
<#assign need_time = true>
</#if>
<#if po.queryMode!='single' && (po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal')>
<#assign need_range_number = true>
</#if>
<#if po.queryMode!='single'>
<#assign is_range = true>
</#if>
<#include "/common/form/native/vue3NativeSearch.ftl">
</#list>
@ -96,7 +108,7 @@
<BasicTable @register="registerTable" :rowSelection="rowSelection" :expandedRowKeys="expandedRowKeys" @expand="handleExpand" @fetch-success="onFetchSuccess">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -106,7 +118,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'"
>批量操作
<Icon icon="ant-design:down-outlined"></Icon>
</a-button>
@ -164,6 +176,9 @@
</#if>
<#if need_pca>
import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
</#if>
<#if is_range>
import { cloneDeep } from "lodash-es";
</#if>
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
@ -186,8 +201,13 @@
width: 120,
fixed: 'right',
},
beforeFetch: (params) => {
beforeFetch: async (params) => {
<#if is_range>
let rangerQuery = await setRangeQuery();
return Object.assign(params, rangerQuery);
<#else>
return Object.assign(params, queryParam.value);
</#if>
},
},
exportConfig: {
@ -419,6 +439,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
}
];
}
@ -443,8 +464,9 @@
popConfirm: {
title: '确定删除吗?',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
},
];
if(record.bpmStatus == '1' || !record.bpmStatus){
@ -475,6 +497,7 @@
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
},
auth: '${entityPackage}:${tableName}:delete'
},
];
</#if>
@ -488,7 +511,7 @@
let params = {
flowCode: 'dev_${tableName}_001',
id: record.id,
formUrl: '${entityPackage}/components/${entityName}Form',
formUrl: '${entityPackagePath}/components/${entityName}Form',
formUrlMobile: ''
}
await startProcess(params);
@ -569,6 +592,32 @@
}
initDictConfig();
</#if>
<#if is_range>
let rangeField = '${getRangeField(columns)}'
/**
* 设置范围查询条件
*/
async function setRangeQuery(){
let queryParamClone = cloneDeep(queryParam.value);
if (rangeField) {
let fieldsValue = rangeField.split(',');
fieldsValue.forEach(item => {
if (queryParamClone[item]) {
let range = queryParamClone[item];
queryParamClone[item+'_begin'] = range[0];
queryParamClone[item+'_end'] = range[1];
delete queryParamClone[item];
} else {
queryParamClone[item+'_begin'] = '';
queryParamClone[item+'_end'] = '';
}
})
}
return queryParamClone;
}
</#if>
</script>
<style lang="less" scoped>

View File

@ -4,15 +4,15 @@ import { useMessage } from "/@/hooks/web/useMessage";
const { createConfirm } = useMessage();
enum Api {
list = '/${entityPackage}/${entityName?uncap_first}/rootList',
save='/${entityPackage}/${entityName?uncap_first}/add',
edit='/${entityPackage}/${entityName?uncap_first}/edit',
delete${entityName} = '/${entityPackage}/${entityName?uncap_first}/delete',
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',
list = '/${entityPackagePath}/${entityName?uncap_first}/rootList',
save='/${entityPackagePath}/${entityName?uncap_first}/add',
edit='/${entityPackagePath}/${entityName?uncap_first}/edit',
delete${entityName} = '/${entityPackagePath}/${entityName?uncap_first}/delete',
importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel',
exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls',
loadTreeData = '/${entityPackagePath}/${entityName?uncap_first}/loadTreeRoot',
getChildList = '/${entityPackagePath}/${entityName?uncap_first}/childList',
getChildListBatch = '/${entityPackagePath}/${entityName?uncap_first}/getChildListBatch',
}
/**

View File

@ -61,7 +61,7 @@ export const columns: BasicColumn[] = [
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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',

View File

@ -3,7 +3,7 @@
<a-spin :spinning="confirmLoading">
<JFormContainer :disabled="disabled">
<template #detail>
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol" name="${entityName}Form">
<a-row>
<#assign need_category = false>
<#assign bpm_flag=false>
@ -14,6 +14,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -22,6 +23,7 @@
<#assign need_image_upload = false>
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign need_range_number = false>
<#assign pidFieldName = "">
<#assign hasOnlyValidate = false>
<#assign form_span = 24>
@ -56,6 +58,7 @@
</a-form-item>
</a-col>
</#if>
<#assign formEntityName>${entityName}Form</#assign>
<#include "/common/form/native/vue3NativeForm.ftl">
</#list>
<#if bpm_flag>
@ -82,7 +85,10 @@
<#if hasOnlyValidate == true>
import { duplicateValidate } from '/@/utils/helper/validator'
</#if>
<#if bpm_flag>
import { usePermission } from '/@/hooks/web/usePermission';
const { isDisabledAuth, hasPermission, initBpmFormData } = usePermission();
</#if>
const useForm = Form.useForm;
const formRef = ref();
const isUpdate = ref(true);
@ -124,10 +130,11 @@
<#if bpm_flag>
onMounted(()=>{
initBpmFormData(props.formData);
initFormData();
});
//渲染流程表单数据
const queryByIdUrl = '/${entityPackage}/${entityName?uncap_first}/queryById';
const queryByIdUrl = '/${entityPackagePath}/${entityName?uncap_first}/queryById';
async function initFormData(){
if(props.formBpm === true){
let params = {id: props.formData.dataId};
@ -196,8 +203,18 @@
* 提交数据
*/
async function submitForm() {
// 触发表单验证
await validate();
try {
// 触发表单验证
await validate();
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
}
confirmLoading.value = true;
const isUpdate = ref<boolean>(false);
//时间格式化

View File

@ -2,6 +2,7 @@ package ${bussiPackage}.${entityPackage}.controller;
import org.jeecg.common.system.query.QueryGenerator;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.jeecg.common.system.query.QueryRuleEnum;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
@ -13,6 +14,7 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
import java.util.HashMap;
import org.jeecg.common.util.oConvertUtils;
<#list subTables as sub>
import ${bussiPackage}.${entityPackage}.entity.${sub.entityName};
@ -39,7 +41,12 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.shiro.authz.annotation.RequiresPermissions;
<#assign has_multi_query_field=false>
<#list originalColumns as po>
<#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')>
<#assign has_multi_query_field=true>
</#if>
</#list>
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
@ -48,7 +55,7 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
*/
@Tag(name="${tableVo.ftlDescription}")
@RestController
@RequestMapping("/${entityPackage}/${entityName?uncap_first}")
@RequestMapping("/${entityPackagePath}/${entityName?uncap_first}")
@Slf4j
public class ${entityName}Controller extends JeecgController<${entityName}, I${entityName}Service> {
@ -78,7 +85,19 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap());
<#if has_multi_query_field>
// 自定义查询规则
Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
// 自定义多选的查询规则为LIKE_WITH_OR
<#list originalColumns as po>
<#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')>
customeRuleMap.put("${po.fieldName}", QueryRuleEnum.LIKE_WITH_OR);
</#if>
</#list>
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap(),customeRuleMap);
<#else>
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap());
</#if>
Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize);
IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper);
return Result.OK(pageList);

View File

@ -9,6 +9,8 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableLogic;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecg.common.constant.ProvinceCityArea;
import org.jeecg.common.util.SpringContextUtils;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
@ -28,6 +30,7 @@ public class ${entityName} implements Serializable {
private static final long serialVersionUID = 1L;
<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']>
<#assign excel_ignore_classType_arr=['pca','switch','cat_tree']>
<#list originalColumns as po>
<#-- 生成字典Code -->
<#assign list_field_dictCode="">
@ -63,7 +66,7 @@ public class ${entityName} implements Serializable {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
</#if>
<#else>
<#if !excel_ignore_arr?seq_contains("${po.fieldName}")>
<#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")>
@Excel(name = "${po.filedComment}", width = 15${list_field_dictCode})
</#if>
</#if>

View File

@ -9,6 +9,8 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableLogic;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.constant.ProvinceCityArea;
import org.jeecg.common.util.SpringContextUtils;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
@ -30,6 +32,7 @@ public class ${subTab.entityName} implements Serializable {
private static final long serialVersionUID = 1L;
<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']>
<#assign excel_ignore_classType_arr=['pca','switch','cat_tree']>
<#list subTab.originalColumns as po>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>
@ -50,7 +53,7 @@ public class ${subTab.entityName} implements Serializable {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
</#if>
<#elseif !subTab.foreignKeys?seq_contains(po.fieldName?cap_first)>
<#if !excel_ignore_arr?seq_contains("${po.fieldName}")>
<#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")>
@Excel(name = "${po.filedComment}", width = 15)
</#if>
</#if>
@ -63,7 +66,7 @@ public class ${subTab.entityName} implements Serializable {
</#if>
</#if>
<#if po.classType =='cat_tree'>
@Dict(dicCode = "id",dicText = "name",dictTable = "sys_category")
//@Dict(dicCode = "id",dicText = "name",dictTable = "sys_category")
</#if>
<#if po.classType =='sel_depart'>
<#assign list_field_dictCode='dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dictTable = "sys_depart"'>

View File

@ -310,11 +310,11 @@
}
],
url: {
list: "/${entityPackage}/${entityName?uncap_first}/list",
delete: "/${entityPackage}/${entityName?uncap_first}/delete",
deleteBatch: "/${entityPackage}/${entityName?uncap_first}/deleteBatch",
exportXlsUrl: "/${entityPackage}/${entityName?uncap_first}/exportXls",
importExcelUrl: "${entityPackage}/${entityName?uncap_first}/importExcel",
list: "/${entityPackagePath}/${entityName?uncap_first}/list",
delete: "/${entityPackagePath}/${entityName?uncap_first}/delete",
deleteBatch: "/${entityPackagePath}/${entityName?uncap_first}/deleteBatch",
exportXlsUrl: "/${entityPackagePath}/${entityName?uncap_first}/exportXls",
importExcelUrl: "${entityPackagePath}/${entityName?uncap_first}/importExcel",
},
dictOptions:{
<#list columns as po>

View File

@ -287,11 +287,11 @@
}
],
url: {
list: "/${entityPackage}/${entityName?uncap_first}/list${sub.entityName}ByMainId",
delete: "/${entityPackage}/${entityName?uncap_first}/delete${sub.entityName}",
deleteBatch: "/${entityPackage}/${entityName?uncap_first}/deleteBatch${sub.entityName}",
exportXlsUrl: "/${entityPackage}/${entityName?uncap_first}/export${sub.entityName}",
importUrl: "/${entityPackage}/${entityName?uncap_first}/import${sub.entityName}",
list: "/${entityPackagePath}/${entityName?uncap_first}/list${sub.entityName}ByMainId",
delete: "/${entityPackagePath}/${entityName?uncap_first}/delete${sub.entityName}",
deleteBatch: "/${entityPackagePath}/${entityName?uncap_first}/deleteBatch${sub.entityName}",
exportXlsUrl: "/${entityPackagePath}/${entityName?uncap_first}/export${sub.entityName}",
importUrl: "/${entityPackagePath}/${entityName?uncap_first}/import${sub.entityName}",
},
dictOptions:{
<#list columns as po>

Some files were not shown because too many files have changed in this diff Show More