【合并升级v3.8.1】

Merge remote-tracking branch 'origin/master' into springboot3

# Conflicts:
#	jeecg-boot/README.md
#	jeecg-boot/db/tables_nacos.sql
#	jeecg-boot/jeecg-boot-base-core/pom.xml
#	jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java
#	jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/encryption/AesEncryptUtil.java
#	jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/WebMvcConfiguration.java
#	jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/pom.xml
#	jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/app/controller/AiragAppController.java
#	jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/monitor/actuator/httptrace/CustomInMemoryHttpTraceRepository.java
#	jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiPermissionServiceImpl.java
#	jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleIndexController.java
#	jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserService.java
#	jeecg-boot/jeecg-module-system/jeecg-system-start/pom.xml
#	jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml
#	jeecg-boot/jeecg-server-cloud/jeecg-system-cloud-start/src/main/java/org/jeecg/JeecgSystemCloudApplication.java
#	jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-sentinel/pom.xml
#	jeecg-boot/pom.xml
#	jeecgboot-vue3/pnpm-lock.yaml
This commit is contained in:
JEECG
2025-07-08 16:33:51 +08:00
370 changed files with 12841 additions and 5591 deletions

View File

@ -24,6 +24,12 @@
<artifactId>hibernate-re</artifactId>
</dependency>
<!-- AI大模型管理 -->
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-module-airag</artifactId>
<version>${jeecgboot.version}</version>
</dependency>
<!-- 企业微信/钉钉 api -->
<dependency>
<groupId>org.jeecgframework</groupId>
@ -40,10 +46,16 @@
</exclusion>
</exclusions>
</dependency>
<!-- mongo、redis和文件数据集支持包按需引入 -->
<dependency>
<groupId>org.jeecgframework.jimureport</groupId>
<artifactId>jimureport-nosql-starter</artifactId>
</dependency>
<!-- 后台导出接口Echart图表支持包按需引入
<dependency>
<groupId>org.jeecgframework.jimureport</groupId>
<artifactId>jimureport-echarts-starter</artifactId>
</dependency> -->
<!-- 积木BI -->
<dependency>
<groupId>org.jeecgframework.jimureport</groupId>

View File

@ -27,6 +27,10 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @Description: 邮箱发送信息
@ -54,32 +58,37 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
* 真实姓名变量
*/
private static final String realNameExp = "{REALNAME}";
/**
* 线程池用于异步发送消息
*/
public static ExecutorService cachedThreadPool = new ThreadPoolExecutor(0, 1024, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
@Override
public void sendMsg(String esReceiver, String esTitle, String esContent) {
JavaMailSender mailSender = (JavaMailSender) SpringContextUtils.getBean("mailSender");
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = null;
//update-begin-authortaoyan date:20200811 for:配置类数据获取
if(oConvertUtils.isEmpty(emailFrom)){
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
setEmailFrom(staticConfig.getEmailFrom());
}
//update-end-authortaoyan date:20200811 for:配置类数据获取
try {
helper = new MimeMessageHelper(message, true);
// 设置发送方邮箱地址
helper.setFrom(emailFrom);
helper.setTo(esReceiver);
helper.setSubject(esTitle);
helper.setText(esContent, true);
mailSender.send(message);
} catch (MessagingException e) {
e.printStackTrace();
}
cachedThreadPool.execute(()->{
try {
log.info("============> 开始邮件发送,接收人:"+esReceiver);
MimeMessageHelper helper = new MimeMessageHelper(message, true);
// 设置发送方邮箱地址
helper.setFrom(emailFrom);
helper.setTo(esReceiver);
helper.setSubject(esTitle);
helper.setText(esContent, true);
mailSender.send(message);
log.info("============> 邮件发送成功,接收人:"+esReceiver);
} catch (MessagingException e) {
log.error("============> 邮件发送失败,接收人:"+esReceiver, e.getMessage());
}
});
}
@Override
@ -180,24 +189,26 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
private void sendEmail(String email, String content, String title){
JavaMailSender mailSender = (JavaMailSender) SpringContextUtils.getBean("mailSender");
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = null;
if (oConvertUtils.isEmpty(emailFrom)) {
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
setEmailFrom(staticConfig.getEmailFrom());
}
try {
helper = new MimeMessageHelper(message, true);
// 设置发送方邮箱地址
helper.setFrom(emailFrom);
helper.setTo(email);
//设置抄送人
helper.setCc(email);
helper.setSubject(title);
helper.setText(content, true);
mailSender.send(message);
} catch (MessagingException e) {
e.printStackTrace();
}
cachedThreadPool.execute(()->{
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
// 设置发送方邮箱地址
helper.setFrom(emailFrom);
helper.setTo(email);
//设置抄送人
helper.setCc(email);
helper.setSubject(title);
helper.setText(content, true);
mailSender.send(message);
log.info("============> 邮件发送成功,接收人:"+email);
} catch (MessagingException e) {
log.warn("============> 邮件发送失败,接收人:"+email, e.getMessage());
}
});
}
//update-end-author:taoyan date:2023-6-20 for: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱

View File

@ -19,6 +19,21 @@ public class CustomInMemoryHttpTraceRepository extends InMemoryHttpExchangeRepos
return super.findAll();
}
/**
* for [issues/8309]系统监控>请求追踪,列表每刷新一下,总数据就减一#8309
* @param trace
* @author chenrui
* @date 2025/6/4 19:38
*/
@Override
public void add(HttpExchange trace) {
// 只有当请求不是OPTIONS方法并且URI不包含httptrace时才记录数据
if (!"OPTIONS".equals(trace.getRequest().getMethod()) &&
!trace.getRequest().getUri().toString().contains("httptrace")) {
super.add(trace);
}
}
public List<HttpExchange> findAll(String query) {
List<HttpExchange> allTrace = super.findAll();
if (null != allTrace && !allTrace.isEmpty()) {

View File

@ -162,7 +162,7 @@ public class OpenApiController extends JeecgController<OpenApi, OpenApiService>
String method = openApi.getRequestMethod();
String appkey = request.getHeader("appkey");
OpenApiAuth openApiAuth = openApiAuthService.getByAppkey(appkey);
SysUser systemUser = sysUserService.getById(openApiAuth.getSystemUserId());
SysUser systemUser = sysUserService.getUserByName(openApiAuth.getCreateBy());
String token = this.getToken(systemUser.getUsername(), systemUser.getPassword());
httpHeaders.put("X-Access-Token", Lists.newArrayList(token));
httpHeaders.put("Content-Type",Lists.newArrayList("application/json"));
@ -382,7 +382,7 @@ public class OpenApiController extends JeecgController<OpenApi, OpenApiService>
SwaggerInfo info = new SwaggerInfo();
info.setDescription("OpenAPI 接口列表");
info.setVersion("3.8.0");
info.setVersion("3.8.1");
info.setTitle("OpenAPI 接口列表");
info.setTermsOfService("https://jeecg.com");

View File

@ -1,35 +1,22 @@
package org.jeecg.modules.openapi.controller;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.openapi.entity.OpenApiPermission;
import org.jeecg.modules.openapi.service.OpenApiPermissionService;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
@RestController
@RequestMapping("/openapi/permission")
public class OpenApiPermissionController extends JeecgController<OpenApiPermission, OpenApiPermissionService> {
@PostMapping("add")
public Result add(@RequestBody OpenApiPermission openApiPermission) {
List<String> list = Arrays.asList(openApiPermission.getApiId().split(","));
if (CollectionUtil.isNotEmpty(list)) {
list.forEach(l->{
OpenApiPermission saveApiPermission = new OpenApiPermission();
saveApiPermission.setApiId(l);
saveApiPermission.setApiAuthId(openApiPermission.getApiAuthId());
service.save(saveApiPermission);
});
}
service.add(openApiPermission);
return Result.ok("保存成功");
}
@GetMapping("/list")
public Result list( String apiAuthId) {
return Result.ok(service.list(Wrappers.<OpenApiPermission>lambdaQuery().eq(OpenApiPermission::getApiAuthId,apiAuthId)));
@GetMapping("/getOpenApi")
public Result<?> getOpenApi( String apiAuthId) {
return service.getOpenApi(apiAuthId);
}
}

View File

@ -1,6 +1,7 @@
package org.jeecg.modules.openapi.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;
@ -95,4 +96,9 @@ public class OpenApi implements Serializable {
* 更新时间
*/
private Date updateTime;
/**
* 历史已选接口
*/
@TableField(exist = false)
private String ifCheckBox = "0";
}

View File

@ -1,6 +1,8 @@
package org.jeecg.modules.openapi.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.openapi.entity.OpenApi;
import org.jeecg.modules.openapi.entity.OpenApiPermission;
import java.util.List;
@ -10,4 +12,8 @@ import java.util.List;
*/
public interface OpenApiPermissionService extends IService<OpenApiPermission> {
List<OpenApiPermission> findByAuthId(String authId);
Result<?> getOpenApi(String apiAuthId);
void add(OpenApiPermission openApiPermission);
}

View File

@ -1,21 +1,67 @@
package org.jeecg.modules.openapi.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.openapi.entity.OpenApi;
import org.jeecg.modules.openapi.entity.OpenApiPermission;
import org.jeecg.modules.openapi.mapper.OpenApiPermissionMapper;
import org.jeecg.modules.openapi.service.OpenApiPermissionService;
import org.jeecg.modules.openapi.service.OpenApiService;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @date 2024/12/19 17:44
*/
@Service
public class OpenApiPermissionServiceImpl extends ServiceImpl<OpenApiPermissionMapper, OpenApiPermission> implements OpenApiPermissionService {
@Resource
private OpenApiService openApiService;
@Override
public List<OpenApiPermission> findByAuthId(String authId) {
return baseMapper.selectList(Wrappers.lambdaQuery(OpenApiPermission.class).eq(OpenApiPermission::getApiAuthId, authId));
}
@Override
public Result<?> getOpenApi(String apiAuthId) {
List<OpenApi> openApis = openApiService.list();
if (CollectionUtil.isEmpty(openApis)) {
return Result.error("接口不存在");
}
List<OpenApiPermission> openApiPermissions = baseMapper.selectList(Wrappers.<OpenApiPermission>lambdaQuery().eq(OpenApiPermission::getApiAuthId, apiAuthId));
if (CollectionUtil.isNotEmpty(openApiPermissions)) {
Map<String, OpenApi> openApiMap = openApis.stream().collect(Collectors.toMap(OpenApi::getId, o -> o));
for (OpenApiPermission openApiPermission : openApiPermissions) {
OpenApi openApi = openApiMap.get(openApiPermission.getApiId());
if (openApi!=null) {
openApi.setIfCheckBox("1");
}
}
}
return Result.ok(openApis);
}
@Override
public void add(OpenApiPermission openApiPermission) {
this.remove(Wrappers.<OpenApiPermission>lambdaQuery().eq(OpenApiPermission::getApiAuthId, openApiPermission.getApiAuthId()));
List<String> list = Arrays.asList(openApiPermission.getApiId().split(","));
if (CollectionUtil.isNotEmpty(list)) {
list.forEach(l->{
if (StrUtil.isNotEmpty(l)){
OpenApiPermission saveApiPermission = new OpenApiPermission();
saveApiPermission.setApiId(l);
saveApiPermission.setApiAuthId(openApiPermission.getApiAuthId());
this.save(saveApiPermission);
}
});
}
}
}

View File

@ -3,8 +3,8 @@ package org.jeecg.modules.quartz.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;

View File

@ -229,7 +229,7 @@ public class CommonController {
File file = new File(filePath);
if(!file.exists()){
response.setStatus(404);
log.error("文件["+imgPath+"]不存在..");
log.warn("文件["+imgPath+"]不存在..");
return;
//throw new RuntimeException();
}

View File

@ -1,7 +1,7 @@
package org.jeecg.modules.system.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
@ -36,7 +36,7 @@ public class DuplicateCheckController {
* @return
*/
@RequestMapping(value = "/check", method = RequestMethod.GET)
@Operation(summary ="重复校验接口")
@Operation(summary="重复校验接口")
public Result<String> doDuplicateCheck(DuplicateCheckVo duplicateCheckVo, HttpServletRequest request) {
log.debug("----duplicate check------"+ duplicateCheckVo.toString());

View File

@ -5,8 +5,8 @@ import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
@ -70,7 +70,7 @@ public class LoginController {
private final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
@Operation(summary = "登录接口")
@Operation(summary="登录接口")
@RequestMapping(value = "/login", method = RequestMethod.POST)
public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel, HttpServletRequest request){
Result<JSONObject> result = new Result<JSONObject>();
@ -404,7 +404,7 @@ public class LoginController {
* @param jsonObject
* @return
*/
@Operation(summary = "手机号登录接口")
@Operation(summary="手机号登录接口")
@PostMapping("/phoneLogin")
public Result<JSONObject> phoneLogin(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
Result<JSONObject> result = new Result<JSONObject>();
@ -523,7 +523,7 @@ public class LoginController {
* @param response
* @param key
*/
@Operation(summary = "获取验证码")
@Operation(summary="获取验证码")
@GetMapping(value = "/randomImage/{key}")
public Result<String> randomImage(HttpServletResponse response,@PathVariable("key") String key){
Result<String> res = new Result<String>();

View File

@ -534,6 +534,7 @@ public class SysAnnouncementController {
*/
@RequestMapping(value = "/vue3List", method = RequestMethod.GET)
public Result<List<SysAnnouncement>> vue3List(@RequestParam(name="fromUser", required = false) String fromUser,
@RequestParam(name="busType", required = false) String busType,
@RequestParam(name="starFlag", required = false) String starFlag,
@RequestParam(name="rangeDateKey", required = false) String rangeDateKey,
@RequestParam(name="beginDate", required = false) String beginDate,
@ -562,7 +563,7 @@ public class SysAnnouncementController {
}
// 2、根据条件查询用户的通知消息
List<SysAnnouncement> ls = this.sysAnnouncementService.querySysMessageList(pageSize, pageNo, fromUser, starFlag, beginTime, endTime);
List<SysAnnouncement> ls = this.sysAnnouncementService.querySysMessageList(pageSize, pageNo, fromUser, starFlag,busType, beginTime, endTime);
// 3、设置当前页的消息为已读
if (!CollectionUtils.isEmpty(ls)) {

View File

@ -4,8 +4,8 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;

View File

@ -3,8 +3,8 @@ package org.jeecg.modules.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.dto.DataLogDTO;

View File

@ -7,8 +7,8 @@ import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;

View File

@ -7,8 +7,6 @@ import jakarta.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
@ -35,6 +33,8 @@ import org.jeecg.modules.system.service.ISysPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
/**
* @Description: 部门权限表
@ -71,7 +71,7 @@ public class SysDepartPermissionController extends JeecgController<SysDepartPerm
* @param req
* @return
*/
@Operation(summary ="部门权限表-分页列表查询")
@Operation(summary="部门权限表-分页列表查询")
@GetMapping(value = "/list")
public Result<?> queryPageList(SysDepartPermission sysDepartPermission,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@ -89,7 +89,7 @@ public class SysDepartPermissionController extends JeecgController<SysDepartPerm
* @param sysDepartPermission
* @return
*/
@Operation(summary ="部门权限表-添加")
@Operation(summary="部门权限表-添加")
@PostMapping(value = "/add")
public Result<?> add(@RequestBody SysDepartPermission sysDepartPermission) {
sysDepartPermissionService.save(sysDepartPermission);
@ -102,7 +102,7 @@ public class SysDepartPermissionController extends JeecgController<SysDepartPerm
* @param sysDepartPermission
* @return
*/
@Operation(summary ="部门权限表-编辑")
@Operation(summary="部门权限表-编辑")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<?> edit(@RequestBody SysDepartPermission sysDepartPermission) {
sysDepartPermissionService.updateById(sysDepartPermission);
@ -115,7 +115,7 @@ public class SysDepartPermissionController extends JeecgController<SysDepartPerm
* @param id
* @return
*/
@Operation(summary ="部门权限表-通过id删除")
@Operation(summary="部门权限表-通过id删除")
@DeleteMapping(value = "/delete")
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
sysDepartPermissionService.removeById(id);
@ -128,7 +128,7 @@ public class SysDepartPermissionController extends JeecgController<SysDepartPerm
* @param ids
* @return
*/
@Operation(summary ="部门权限表-批量删除")
@Operation(summary="部门权限表-批量删除")
@DeleteMapping(value = "/deleteBatch")
public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.sysDepartPermissionService.removeByIds(Arrays.asList(ids.split(",")));
@ -141,7 +141,7 @@ public class SysDepartPermissionController extends JeecgController<SysDepartPerm
* @param id
* @return
*/
@Operation(summary ="部门权限表-通过id查询")
@Operation(summary="部门权限表-通过id查询")
@GetMapping(value = "/queryById")
public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
SysDepartPermission sysDepartPermission = sysDepartPermissionService.getById(id);

View File

@ -7,8 +7,6 @@ import jakarta.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
@ -30,6 +28,8 @@ import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
/**
* @Description: 部门角色
@ -69,7 +69,7 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
* @param req
* @return
*/
@Operation(summary = "部门角色-分页列表查询")
@Operation(summary="部门角色-分页列表查询")
@GetMapping(value = "/list")
public Result<?> queryPageList(SysDepartRole sysDepartRole,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@ -110,7 +110,7 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
* @return
*/
@RequiresPermissions("system:depart:role:add")
@Operation(summary ="部门角色-添加")
@Operation(summary="部门角色-添加")
@PostMapping(value = "/add")
public Result<?> add(@RequestBody SysDepartRole sysDepartRole) {
sysDepartRoleService.save(sysDepartRole);
@ -123,7 +123,7 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
* @param sysDepartRole
* @return
*/
@Operation(summary ="部门角色-编辑")
@Operation(summary="部门角色-编辑")
@RequiresPermissions("system:depart:role:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<?> edit(@RequestBody SysDepartRole sysDepartRole) {
@ -138,7 +138,7 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
* @return
*/
@AutoLog(value = "部门角色-通过id删除")
@Operation(summary ="部门角色-通过id删除")
@Operation(summary="部门角色-通过id删除")
@RequiresPermissions("system:depart:role:delete")
@DeleteMapping(value = "/delete")
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
@ -153,7 +153,7 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
* @return
*/
@AutoLog(value = "部门角色-批量删除")
@Operation(summary ="部门角色-批量删除")
@Operation(summary="部门角色-批量删除")
@RequiresPermissions("system:depart:role:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
@ -168,7 +168,7 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
* @param id
* @return
*/
@Operation(summary ="部门角色-通过id查询")
@Operation(summary="部门角色-通过id查询")
@GetMapping(value = "/queryById")
public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
SysDepartRole sysDepartRole = sysDepartRoleService.getById(id);

View File

@ -7,8 +7,8 @@ import java.util.Date;
import jakarta.servlet.http.HttpServletRequest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
@ -162,7 +162,7 @@ public class SysDictItemController {
* @return
*/
@RequestMapping(value = "/dictItemCheck", method = RequestMethod.GET)
@Operation(summary ="字典重复校验接口")
@Operation(summary="字典重复校验接口")
public Result<Object> doDictItemCheck(SysDictItem sysDictItem, HttpServletRequest request) {
Long num = Long.valueOf(0);
LambdaQueryWrapper<SysDictItem> queryWrapper = new LambdaQueryWrapper<SysDictItem>();

View File

@ -5,8 +5,8 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;

View File

@ -3,8 +3,8 @@ package org.jeecg.modules.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;

View File

@ -5,8 +5,8 @@ import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;

View File

@ -4,8 +4,8 @@ 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 io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

View File

@ -3,8 +3,8 @@ package org.jeecg.modules.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;

View File

@ -986,4 +986,16 @@ public class SysTenantController {
}
return result;
}
/**
* 目前只给敲敲云人员与部门下的用户删除使用
*
* 删除用户
*/
@DeleteMapping("/deleteUser")
public Result<String> deleteUser(@RequestBody SysUser sysUser,HttpServletRequest request){
Integer tenantId = oConvertUtils.getInteger(TokenUtils.getTenantIdByRequest(request), null);
sysTenantService.deleteUser(sysUser, tenantId);
return Result.ok("删除用户成功");
}
}

View File

@ -1727,7 +1727,7 @@ public class SysUserController {
}
return result;
}
/**
* 根据关键词搜索部门和用户【low-app】
* @param keyword
@ -1847,7 +1847,7 @@ public class SysUserController {
public Result<?> importAppUser(HttpServletRequest request, HttpServletResponse response)throws IOException {
return sysUserService.importAppUser(request);
}
/**
* 更改手机号(敲敲云个人设置专用)
*

View File

@ -45,7 +45,6 @@ public class SysUserOnlineController {
public ISysUserService userService;
@Autowired
private SysBaseApiImpl sysBaseApi;
@Resource
private BaseCommonService baseCommonService;

View File

@ -283,7 +283,7 @@ public class ThirdLoginController {
* @param jsonObject
* @return
*/
@Operation(summary ="手机号登录接口")
@Operation(summary="手机号登录接口")
@PostMapping("/bindingThirdPhone")
@ResponseBody
public Result<String> bindingThirdPhone(@RequestBody JSONObject jsonObject) {

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -23,7 +24,7 @@ import java.util.Date;
@TableName("sys_check_rule")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Schema(description = "编码校验规则")
@Schema(description="编码校验规则")
public class SysCheckRule {
/**

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -22,7 +23,7 @@ import org.springframework.format.annotation.DateTimeFormat;
@TableName("sys_data_source")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Schema(description = "多数据源管理")
@Schema(description="多数据源管理")
public class SysDataSource {
/**

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -24,7 +25,7 @@ import org.jeecgframework.poi.excel.annotation.Excel;
@TableName("sys_depart_role_permission")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Schema( description="部门角色权限")
@Schema(description="部门角色权限")
public class SysDepartRolePermission {
/**id*/

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -21,7 +22,7 @@ import org.springframework.format.annotation.DateTimeFormat;
@TableName("sys_fill_rule")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Schema(description = "填值规则")
@Schema(description="填值规则")
public class SysFillRule {
/**

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -5,6 +5,7 @@ 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;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -5,11 +5,12 @@ import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -22,7 +23,7 @@ import org.springframework.format.annotation.DateTimeFormat;
@TableName("sys_position")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Schema(description = "职务表")
@Schema(description="职务表")
public class SysPosition {
/**

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -21,7 +22,7 @@ import org.springframework.format.annotation.DateTimeFormat;
@TableName("sys_table_white_list")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Schema(description = "系统表白名单")
@Schema(description="系统表白名单")
public class SysTableWhiteList {
/**

View File

@ -4,11 +4,12 @@ import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -31,8 +31,8 @@ public class SysUserDepart implements Serializable {
this.depId = depId;
}
public SysUserDepart(String id, String departId) {
this.userId = id;
public SysUserDepart(String userId, String departId) {
this.userId = userId;
this.depId = departId;
}
}

View File

@ -4,13 +4,14 @@ import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* @Description: 用户职位关系表
* @Author: jeecg-boot

View File

@ -5,11 +5,12 @@ import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

View File

@ -46,7 +46,7 @@ public interface SysAnnouncementMapper extends BaseMapper<SysAnnouncement> {
* @param endDate
* @return
*/
List<SysAnnouncement> queryAllMessageList(Page<SysAnnouncement> page, @Param("userId")String userId, @Param("fromUser")String fromUser, @Param("starFlag")String starFlag, @Param("beginDate")Date beginDate, @Param("endDate")Date endDate);
List<SysAnnouncement> queryAllMessageList(Page<SysAnnouncement> page, @Param("userId")String userId, @Param("fromUser")String fromUser, @Param("starFlag")String starFlag, @Param("busType")String busType, @Param("beginDate")Date beginDate, @Param("endDate")Date endDate);
/**
* 查询用户未阅读的通知公告

View File

@ -178,4 +178,21 @@ public interface SysDepartMapper extends BaseMapper<SysDepart> {
* @return
*/
List<SysDepartExportVo> getSysDepartList(@Param("parentId") String parentId,@Param("tenantId") Integer tenantId, List<String> idList);
/**
* 根据多个部门id获取部门数据
*
* @param departIds
* @return
*/
List<SysUserDepVo> getDepartByIds(List<String> departIds);
/**
* 根据用户id获取部门数据
*
* @param userList
* @return
*/
@InterceptorIgnore(tenantLine = "true")
List<SysUserDepVo> getUserDepartByUserId(@Param("userList")List<SysUser> userList);
}

View File

@ -8,6 +8,8 @@ import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.system.entity.SysRole;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.vo.SysUserPositionVo;
import java.util.List;
@ -73,4 +75,12 @@ public interface SysRoleMapper extends BaseMapper<SysRole> {
*/
@Select("select count(*) from sys_role where id=#{id} and tenant_id=#{tenantId}")
Long getRoleCountByTenantId(@Param("id") String id, @Param("tenantId") Integer tenantId);
/**
* 根据用户id获取角色信息
*
* @param userList
* @return
*/
List<SysUserPositionVo> getUserRoleByUserId(@Param("userList") List<SysUser> userList);
}

View File

@ -92,6 +92,9 @@
<if test="starFlag!=null and starFlag!=''">
and b.star_flag = #{starFlag}
</if>
<if test="busType!=null and busType!=''">
and a.bus_type = #{busType}
</if>
order by b.read_flag ASC, a.create_time DESC
</select>

View File

@ -193,4 +193,29 @@
</if>
ORDER BY depart_order DESC
</select>
<!--根据多个部门id获取部门数据-->
<select id="getDepartByIds" resultType="org.jeecg.modules.system.vo.SysUserDepVo">
SELECT id,depart_name,org_code,parent_id FROM sys_depart
where
1=1
<if test="departIds != null and !departIds.isEmpty()">
and id in
<foreach item="id" index="index" collection="departIds" open="(" separator="," close=")">
#{id}
</foreach>
</if>
</select>
<!--根据用户id获取部门信息-->
<select id="getUserDepartByUserId" resultType="org.jeecg.modules.system.vo.SysUserDepVo">
SELECT sd.depart_name, sud.user_id, sd.id as deptId, sd.parent_id
FROM sys_depart sd
RIGHT JOIN sys_user_depart sud on sd.id = sud.dep_id and sd.del_flag = 0
WHERE sud.user_id IN
<foreach collection="userList" index="index" item="item" open="(" separator="," close=")">
#{item.id}
</foreach>
order by sd.org_code;
</select>
</mapper>

View File

@ -54,5 +54,14 @@
AND tenant_id = #{tenantId}
</if>
</select>
<!--根据用户id获取角色信息-->
<select id="getUserRoleByUserId" resultType="org.jeecg.modules.system.vo.SysUserPositionVo">
SELECT sr.role_name as name,sur.user_id FROM sys_role sr
RIGHT JOIN sys_user_role sur on sur.role_id = sr.id
WHERE sur.user_id IN
<foreach collection="userList" index="index" item="user" open="(" separator="," close=")">
#{user.id}
</foreach>
</select>
</mapper>

View File

@ -29,6 +29,7 @@
<if test="tenantId != null and tenantId != 0">
AND sp.tenant_id = #{tenantId}
</if>
order by sup.create_time desc
</select>
<!--职位列表移除成员-->

View File

@ -72,7 +72,7 @@ public interface ISysAnnouncementService extends IService<SysAnnouncement> {
/**
* 分页查询当前登录用户的消息, 并且标记哪些是未读消息
*/
List<SysAnnouncement> querySysMessageList(int pageSize, int pageNo, String fromUser, String starFlag, Date beginDate, Date endDate);
List<SysAnnouncement> querySysMessageList(int pageSize, int pageNo, String fromUser, String starFlag, String busType, Date beginDate, Date endDate);
/**
* 修改为已读消息

View File

@ -232,4 +232,11 @@ public interface ISysTenantService extends IService<SysTenant> {
* @return
*/
List<SysTenant> getTenantListByUserId(String userId);
/**
* 删除用户
* @param sysUser
* @param tenantId
*/
void deleteUser(SysUser sysUser, Integer tenantId);
}

View File

@ -1,6 +1,7 @@
package org.jeecg.modules.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.entity.SysThirdAppConfig;
import java.util.List;

View File

@ -12,6 +12,7 @@ import org.jeecg.common.system.vo.SysUserCacheInfo;
import org.jeecg.modules.system.entity.SysRoleIndex;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.model.SysUserSysDepartModel;
import org.jeecg.modules.system.vo.SysUserExportVo;
import org.jeecg.modules.system.vo.lowapp.DepartAndUserInfo;
import org.jeecg.modules.system.vo.lowapp.UpdateDepartInfo;
import org.springframework.transaction.annotation.Transactional;
@ -458,4 +459,26 @@ public interface ISysUserService extends IService<SysUser> {
* @param username
*/
void userLogOff(JSONObject jsonObject, String username);
/**
* 获取部门和用户关系的导出信息
* @param pageList
*/
List<SysUserExportVo> getDepartAndRoleExportMsg(List<SysUser> pageList);
/**
* 导入用户
*
* @param request
*/
Result<?> importSysUser(HttpServletRequest request);
/**
* 没有绑定手机号 直接修改密码
*
* @param oldPassword
* @param password
* @param username
*/
void updatePasswordNotBindPhone(String oldPassword, String password, String username);
}

View File

@ -199,7 +199,7 @@ public class SysAnnouncementServiceImpl extends ServiceImpl<SysAnnouncementMappe
}
@Override
public List<SysAnnouncement> querySysMessageList(int pageSize, int pageNo, String fromUser, String starFlag, Date beginDate, Date endDate) {
public List<SysAnnouncement> querySysMessageList(int pageSize, int pageNo, String fromUser, String starFlag, String busType, Date beginDate, Date endDate) {
// //1. 补全send表的数据
// completeNoteThreadPool.execute(()->{
// completeAnnouncementSendInfo();
@ -208,7 +208,7 @@ public class SysAnnouncementServiceImpl extends ServiceImpl<SysAnnouncementMappe
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
log.info(" 获取登录人 LoginUser id: {}", sysUser.getId());
Page<SysAnnouncement> page = new Page<SysAnnouncement>(pageNo,pageSize);
List<SysAnnouncement> list = baseMapper.queryAllMessageList(page, sysUser.getId(), fromUser, starFlag, beginDate, endDate);
List<SysAnnouncement> list = baseMapper.queryAllMessageList(page, sysUser.getId(), fromUser, starFlag, busType, beginDate, endDate);
return list;
}

View File

@ -1199,6 +1199,23 @@ public class SysBaseApiImpl implements ISysBaseAPI {
int count = sysPermissionMapper.queryCountByUsername(username, p);
has = has || (count>0);
}
if (!has) {
//没有配置菜单 找online表单菜单地址
SysPermission sysPermission = new SysPermission();
sysPermission.setUrl(onlineFormUrl);
int count = sysPermissionMapper.queryCountByUsername(username, sysPermission);
if (count <= 0) {
//update-begin---author:chenrui ---date:20240123 for[QQYUN-7992]【online】工单申请下的online表单未配置online表单开发菜单操作报错无权限------------
sysPermission.setUrl(onlineAuthDTO.getOnlineWorkOrderUrl());
count = sysPermissionMapper.queryCountByUsername(username, sysPermission);
if (count > 0) {
has = true;
}
//update-end---author:chenrui ---date:20240123 for[QQYUN-7992]【online】工单申请下的online表单未配置online表单开发菜单操作报错无权限------------
} else {
has = true;
}
}
return has;
}
return true;
@ -1408,7 +1425,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
e.printStackTrace();
}
log.info("Email Html Text{}", htmlText);
log.debug("Email Html Text{}", htmlText);
emailHandle.sendMsg(email, title, htmlText);
}

View File

@ -889,25 +889,76 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
if(!sysUserData.getCreateBy().equals(user.getUsername())){
throw new JeecgBootException("您不是该用户的创建人,无法删除!");
}
Date createTime = sysUserData.getCreateTime();
boolean sameDay = DateUtils.isSameDay(createTime, new Date());
if(!sameDay){
throw new JeecgBootException("用户不是今天创建的,无法删除!");
}
//step4 验证密码
String passwordEncode = PasswordUtil.encrypt(sysUserData.getUsername(), password, sysUserData.getSalt());
if(!passwordEncode.equals(sysUserData.getPassword())){
throw new JeecgBootException("您输入的密码不正确,无法删除该用户!");
}
//update-begin---author:wangshuai---date:2025-04-11---for:【QQYUN-11839】删除用户需要输入被删除用户的密码这逻辑对吗不应该是管理员的密码吗---
this.verifyCreateTimeAndPassword(sysUserData,password);
//update-end---author:wangshuai---date:2025-04-11---for:【QQYUN-11839】删除用户需要输入被删除用户的密码这逻辑对吗不应该是管理员的密码吗---
//step5 逻辑删除用户
userService.deleteUser(userId);
//step6 真实删除用户
userService.removeLogicDeleted(Collections.singletonList(userId));
}
/**
* 验证创建时间和密码
*
* @param sysUser
* @param password
*/
private void verifyCreateTimeAndPassword(SysUser sysUser,String password) {
if(null == sysUser){
throw new JeecgBootException("该用户不存在,无法删除!");
}
//step1 验证创建时间
//当前登录用户
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
Date createTime = sysUser.getCreateTime();
boolean sameDay = DateUtils.isSameDay(createTime, new Date());
if(!sameDay){
throw new JeecgBootException("用户不是今天创建的,无法删除!");
}
//step2 验证密码
//获取admin的用户
SysUser adminUser = userService.getById(user.getId());
String passwordEncode = PasswordUtil.encrypt(adminUser.getUsername(), password, adminUser.getSalt());
if(!passwordEncode.equals(adminUser.getPassword())){
throw new JeecgBootException("您输入的密码不正确,无法删除该用户!");
}
}
@Override
public List<SysTenant> getTenantListByUserId(String userId) {
return tenantMapper.getTenantListByUserId(userId);
}
@Override
public void deleteUser(SysUser sysUser, Integer tenantId) {
//被删除人的用户id
String userId = sysUser.getId();
//被删除人的密码
String password = sysUser.getPassword();
//当前登录用户
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//step1 判断当前用户是否为当前租户的创建者才可以删除
SysTenant sysTenant = this.getById(tenantId);
if(null == sysTenant || !user.getUsername().equals(sysTenant.getCreateBy())){
throw new JeecgBootException("您不是当前组织的创建者,无法删除用户!");
}
//step2 判断除了当前组织之外是否还有加入了其他组织
LambdaQueryWrapper<SysUserTenant> query = new LambdaQueryWrapper<>();
query.eq(SysUserTenant::getUserId,userId);
query.ne(SysUserTenant::getTenantId,tenantId);
List<SysUserTenant> sysUserTenants = userTenantMapper.selectList(query);
if(CollectionUtils.isNotEmpty(sysUserTenants)){
throw new JeecgBootException("该用户还存在于其它组织中,无法删除用户!");
}
//step3 验证创建时间和密码
SysUser sysUserData = userService.getById(userId);
this.verifyCreateTimeAndPassword(sysUserData,password);
//step4 真实删除用户
userService.deleteUser(userId);
userService.removeLogicDeleted(Collections.singletonList(userId));
}
}

View File

@ -28,12 +28,14 @@ import org.jeecg.common.constant.enums.MessageTypeEnum;
import org.jeecg.common.constant.enums.RoleIndexConfigEnum;
import org.jeecg.common.constant.enums.SysAnnmentTypeEnum;
import org.jeecg.common.desensitization.annotation.SensitiveEncode;
import org.jeecg.common.exception.JeecgBootBizTipException;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.SysUserCacheInfo;
import org.jeecg.common.util.*;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.jmreport.common.util.OkConvertUtils;
import org.jeecg.modules.message.handle.impl.SystemSendMsgHandle;
import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.mapper.*;
@ -42,6 +44,7 @@ import org.jeecg.modules.system.service.ISysRoleIndexService;
import org.jeecg.modules.system.service.ISysThirdAccountService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.vo.SysUserDepVo;
import org.jeecg.modules.system.vo.SysUserExportVo;
import org.jeecg.modules.system.vo.SysUserPositionVo;
import org.jeecg.modules.system.vo.UserAvatar;
import org.jeecg.modules.system.vo.lowapp.AppExportUserVo;
@ -59,6 +62,7 @@ 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;
@ -121,6 +125,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
private SysPositionMapper sysPositionMapper;
@Autowired
private SystemSendMsgHandle systemSendMsgHandle;
@Autowired
private ISysThirdAccountService sysThirdAccountService;
@Autowired
@ -1550,8 +1555,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
}
//查询用户数据
List<SysUser> userList = userMapper.getUserByDepartsTenantId(list, tenantId);
//获取部门名称
List<SysUserDepVo> userDepVos = sysDepartMapper.getUserDepartByTenantUserId(userList, tenantId);
//获取部门名称
List<SysUserDepVo> userDepVos = new ArrayList<>();
if(CollectionUtil.isNotEmpty(userList)){
userDepVos = sysDepartMapper.getUserDepartByTenantUserId(userList, tenantId);
}
//获取职位
List<SysUserPositionVo> positionVos = sysUserPositionMapper.getPositionIdByUsersTenantId(userList, tenantId);
// step2 根据用户id进行分类
@ -1560,9 +1568,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
for (SysUser sysUser : userList) {
AppExportUserVo exportUserVo = new AppExportUserVo();
BeanUtils.copyProperties(sysUser, exportUserVo);
String departNames = userDepVos.stream().filter(item -> item.getUserId().equals(sysUser.getId()))
.map(SysUserDepVo::getDepartName).collect(Collectors.joining(SymbolConstant.SEMICOLON));
exportUserVo.setDepart(departNames);
//update-begin---author:wangshuai---date:2025-01-17---for:【QQYUN-10926】组织管理——用户导出时部门没有导出上下级关系---
StringBuilder departNames = this.getDepartNames(userDepVos,sysUser);
exportUserVo.setDepart(departNames.toString());
//update-end---author:wangshuai---date:2025-01-17---for:【QQYUN-10926】组织管理——用户导出时部门没有导出上下级关系---
String posNames = positionVos.stream().filter(item -> item.getUserId().equals(sysUser.getId())).map(SysUserPositionVo::getName).collect(Collectors.joining(SymbolConstant.SEMICOLON));
exportUserVo.setPosition(posNames);
exportUserVoList.add(exportUserVo);
@ -1582,7 +1591,65 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
return mv;
}
//======================================= end 用户与部门 用户列表导出 =========================================
/**
* 获取部门名称
* for【QQYUN-10926】组织管理——用户导出时部门没有导出上下级关系
*
* @param userDepVos
* @param sysUser
* @return
*/
private StringBuilder getDepartNames(List<SysUserDepVo> userDepVos, SysUser sysUser) {
List<SysUserDepVo> SysUserDepVoList = userDepVos.stream().filter(item -> item.getUserId().equals(sysUser.getId()))
.map(item -> {
SysUserDepVo userDepVo = new SysUserDepVo();
userDepVo.setUserId(item.getUserId());
userDepVo.setDeptId(item.getDeptId());
userDepVo.setDepartName(item.getDepartName());
userDepVo.setParentId(item.getParentId());
return userDepVo;
}).collect(Collectors.toList());
//循环SysUserDepVoList,如果存在父级id的情况下需要将父级id的部门名称查询出来
StringBuilder departNames = new StringBuilder();
for (SysUserDepVo sysUserDepVo : SysUserDepVoList) {
if(oConvertUtils.isEmpty(sysUserDepVo.getDepartName())){
continue;
}
//用于查询父级的部门名称
List<String> departNameList = new LinkedList<>();
departNameList.add(sysUserDepVo.getDepartName());
if (StringUtils.isNotEmpty(sysUserDepVo.getParentId())) {
//递归查询部门名称
this.getDepartNameByParentId(sysUserDepVo.getParentId(), departNameList);
}
Collections.reverse(departNameList);
String departName = departNameList.stream().collect(Collectors.joining(SymbolConstant.SINGLE_SLASH));
if (StringUtils.isNotEmpty(departNames.toString())) {
departNames.append(SymbolConstant.SEMICOLON);
}
departNames.append(departName);
}
return departNames;
}
/**
* 根据父级id查询父级的部门名称
* for【QQYUN-10926】组织管理——用户导出时部门没有导出上下级关系
*
* @param parentId
* @param departNameList
*/
private void getDepartNameByParentId(String parentId, List<String> departNameList) {
SysDepart parentDepartId = sysDepartMapper.getDepartById(parentId);
if (null != parentDepartId) {
departNameList.add(parentDepartId.getDepartName());
if (StringUtils.isNotEmpty(parentDepartId.getParentId())) {
this.getDepartNameByParentId(parentDepartId.getParentId(), departNameList);
}
}
}
//======================================= end 用户与部门 用户列表导出 =========================================
//======================================= begin 用户与部门 用户列表导入 =========================================
@Override
@ -1804,9 +1871,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
String[] departNames = depart.split(SymbolConstant.SEMICOLON);
List<String> departNameList = Arrays.asList(departNames);
departNameList = departNameList.stream().distinct().collect(Collectors.toList());
//部门id
String parentId = "";
for (String departName : departNameList) {
//部门id
String parentId = "";
String[] names = departName.split(SymbolConstant.SINGLE_SLASH);
//部门名称拼接
String nameStr = "";
@ -1886,7 +1953,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
messageDTO.setTitle(title);
Map<String, Object> data = new HashMap<>();
//update-begin---author:wangshuai---date:2024-03-11---for:【QQYUN-8425】用户导入成功后 消息提醒 跳转至同意页面---
data.put(CommonConstant.NOTICE_MSG_BUS_TYPE, SysAnnmentTypeEnum.TENANT_INVITE.getType());
data.put(CommonConstant.NOTICE_MSG_BUS_TYPE,SysAnnmentTypeEnum.TENANT_INVITE.getType());
//update-end---author:wangshuai---date:2024-03-11---for:【QQYUN-8425】用户导入成功后 消息提醒 跳转至同意页面---
messageDTO.setData(data);
messageDTO.setContent(title);
@ -2040,7 +2107,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();
@ -2057,4 +2124,236 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
throw new JeecgBootException("短信接口未配置,请联系管理员!");
}
}
//================================================= begin 低代码部门导入导出 ================================================================
@Override
public List<SysUserExportVo> getDepartAndRoleExportMsg(List<SysUser> userList) {
List<SysUserExportVo> list = new ArrayList<>();
if (CollectionUtil.isNotEmpty(userList)) {
//获取部门
List<SysUserDepVo> userDepVos = sysDepartMapper.getUserDepartByUserId(userList);
//获取职位
List<SysUserPositionVo> sysRoles = sysRoleMapper.getUserRoleByUserId(userList);
//组装数据并返回
for (SysUser sysUser : userList) {
SysUserExportVo userExportVo = new SysUserExportVo();
BeanUtils.copyProperties(sysUser, userExportVo);
StringBuilder departNames = this.getDepartNames(userDepVos, sysUser);
userExportVo.setDepartNames(departNames.toString());
String departIds = sysUser.getDepartIds();
if (oConvertUtils.isNotEmpty(departIds)) {
List<SysUserDepVo> depVoList = sysDepartMapper.getDepartByIds(Arrays.asList(departIds.split(",")));
StringBuilder names = this.getDepartNames(userDepVos, sysUser);
userExportVo.setDepartIds(names.toString());
}
String posNames = sysRoles.stream().filter(item -> item.getUserId().equals(sysUser.getId())).map(SysUserPositionVo::getName).collect(Collectors.joining(SymbolConstant.SEMICOLON));
userExportVo.setRoleNames(posNames);
list.add(userExportVo);
}
}
return list;
}
@Override
public Result<?> importSysUser(HttpServletRequest request) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
// 错误信息
List<String> errorMessage = new ArrayList<>();
int successLines = 0, errorLines = 0;
//存放部门的map;key为名称 value为SysDepart对象。避免多次导入和查询
Map<String, SysDepart> departMap = new HashMap<>();
Map<String, String> positionMap = new HashMap<>();
String tenantId = TokenUtils.getTenantIdByRequest(request);
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();// 获取上传文件对象
ImportParams params = new ImportParams();
params.setTitleRows(2);
params.setHeadRows(1);
params.setNeedSave(true);
try {
List<SysUserExportVo> listSysUsers = ExcelImportUtil.importExcel(file.getInputStream(), SysUserExportVo.class, params);
for (int i = 0; i < listSysUsers.size(); i++) {
SysUserExportVo sysUserExcel = listSysUsers.get(i);
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(sysUserExcel, sysUser);
if (OkConvertUtils.isEmpty(sysUser.getUsername())) {
errorLines += 1;
int lineNumber = i + 1;
errorMessage.add("" + lineNumber + " 行:用户账号为空,忽略导入。");
continue;
}
try {
String username = sysUser.getUsername();
//根据用户名程序,为空则添加用户
SysUser userByName = userMapper.getUserByName(username);
if (null != userByName) {
errorLines += 1;
int lineNumber = i + 1;
errorMessage.add("" + lineNumber + " 行:用户名已经存在,忽略导入。");
continue;
} else {
// 密码默认为 “123456”
sysUser.setPassword("123456");
// 密码加密加盐
String salt = oConvertUtils.randomGen(8);
sysUser.setSalt(salt);
String passwordEncode = PasswordUtil.encrypt(sysUserExcel.getUsername(), sysUser.getPassword(), salt);
sysUser.setPassword(passwordEncode);
this.save(sysUser);
}
//添加部门
String departNames = sysUserExcel.getDepartNames();
//新增或编辑部门
Integer tenantIdInt = null;
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
tenantIdInt = OkConvertUtils.getInt(tenantId, 0);
}
this.addOrEditDepart(sysUser.getId(), departNames, tenantIdInt, departMap);
//新增或编辑角色
String roleNames = sysUserExcel.getRoleNames();
this.saveOrEditRole(sysUser.getId(), roleNames, tenantIdInt);
//新增或编辑职位
String position = sysUserExcel.getPost();
if (oConvertUtils.isNotEmpty(position)) {
this.addOrEditPosition(sysUser.getId(), position, false, tenantIdInt, positionMap);
}
//添加负责部门
this.saveChargeDepart(sysUser, sysUserExcel.getDepartIds(), departMap);
successLines++;
} catch (Exception e) {
errorLines++;
String message = e.getMessage().toLowerCase();
int lineNumber = i + 1;
// 通过索引名判断出错信息
if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_USERNAME)) {
errorMessage.add("" + lineNumber + " 行:用户名已经存在,忽略导入。");
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_WORK_NO)) {
errorMessage.add("" + lineNumber + " 行:工号已经存在,忽略导入。");
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_PHONE)) {
errorMessage.add("" + lineNumber + " 行:手机号已经存在,忽略导入。");
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_EMAIL)) {
errorMessage.add("" + lineNumber + " 行:电子邮件已经存在,忽略导入。");
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER)) {
errorMessage.add("" + lineNumber + " 行:违反表唯一性约束。");
} else {
errorMessage.add("" + lineNumber + " 行:未知错误,忽略导入");
log.error(e.getMessage(), e);
}
}
}
} catch (Exception e) {
errorMessage.add("发生异常:" + e.getMessage());
log.error(e.getMessage(), e);
} finally {
try {
file.getInputStream().close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
try {
departMap.clear();
departMap = null;
return ImportExcelUtil.imporReturnRes(errorLines, successLines, errorMessage);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void saveChargeDepart(SysUser sysUser, String departIds, Map<String, SysDepart> departMap) {
//判断那些部门没有,即没有加入到部门,则不能成为负责部门人员
if (OkConvertUtils.isEmpty(departIds)) {
return;
}
//多个部门用;分隔开
String[] split = departIds.split(SymbolConstant.SEMICOLON);
//负责部门id
StringBuilder departIdBulider = new StringBuilder();
for (String name : split) {
if (departMap.containsKey(name)) {
SysDepart sysDepart = departMap.get(name);
departIdBulider.append(sysDepart.getId()).append(",");
}
}
// 检查并删除最后一个逗号
if (departIdBulider.length() > 0 && departIdBulider.charAt(departIdBulider.length() - 1) == ',') {
departIdBulider.deleteCharAt(departIdBulider.length() - 1);
}
sysUser.setDepartIds(departIdBulider.toString());
this.updateById(sysUser);
}
/**
* 保存或编辑角色
*
* @param userId
* @param roleNames
* @param tenantIdInt
*/
private void saveOrEditRole(String userId, String roleNames, Integer tenantIdInt) {
if (oConvertUtils.isEmpty(roleNames)) {
return;
}
String[] roleNameArray = roleNames.split(SymbolConstant.SEMICOLON);
//删除用户下的角色
LambdaQueryWrapper<SysUserRole> deleteQuery = new LambdaQueryWrapper<>();
deleteQuery.eq(SysUserRole::getUserId, userId);
sysUserRoleMapper.delete(deleteQuery);
//通过名字获取角色
LambdaQueryWrapper<SysRole> roleQuery = new LambdaQueryWrapper<>();
roleQuery.orderByDesc(SysRole::getCreateTime);
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
roleQuery.eq(SysRole::getTenantId, tenantIdInt);
}
for (String roleName : roleNameArray) {
roleQuery.eq(SysRole::getRoleName, roleName);
List<SysRole> sysRoles = sysRoleMapper.selectList(roleQuery);
String roleId = "";
if (CollectionUtil.isNotEmpty(sysRoles)) {
roleId = sysRoles.get(0).getId();
} else {
SysRole sysRole = new SysRole();
sysRole.setRoleName(roleName);
sysRole.setRoleCode(RandomUtil.randomString(10));
sysRoleMapper.insert(sysRole);
roleId = sysRole.getId();
}
SysUserRole sysUserRole = new SysUserRole();
sysUserRole.setUserId(userId);
sysUserRole.setRoleId(roleId);
sysUserRoleMapper.insert(sysUserRole);
}
}
//================================================= end 低代码部门导入导出 ================================================================
@Override
public void updatePasswordNotBindPhone(String oldPassword, String password, String username) {
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
//step1 只能修改自己的密码
if(!sysUser.getUsername().equals(username)){
throw new JeecgBootBizTipException("只允许修改自己的密码!");
}
//step2 用户不存在禁止修改密码
SysUser user = this.getUserByName(username);
if(null == user){
throw new JeecgBootBizTipException("用户不存在,无法修改密码!");
}
//setp3 如果手机号存在需要用手机号修改密码的方式
if(oConvertUtils.isNotEmpty(user.getPhone())){
throw new JeecgBootBizTipException("手机号不为空,请根据手机号进行修改密码操作!");
}
//step4 判断旧密码是否正确
String passwordEncode = PasswordUtil.encrypt(username, oldPassword, user.getSalt());
if (!user.getPassword().equals(passwordEncode)) {
throw new JeecgBootBizTipException("旧密码输入错误!");
}
if (oConvertUtils.isEmpty(password)) {
throw new JeecgBootBizTipException("新密码不允许为空!");
}
//step5 修改密码
String newPassWord = PasswordUtil.encrypt(username, password, user.getSalt());
this.userMapper.update(new SysUser().setPassword(newPassWord), new LambdaQueryWrapper<SysUser>().eq(SysUser::getId, user.getId()));
}
}

View File

@ -32,10 +32,7 @@ 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.PasswordUtil;
import org.jeecg.common.util.RestUtil;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.common.util.*;
import org.jeecg.config.JeecgBaseConfig;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
import org.jeecg.modules.system.entity.*;

View File

@ -0,0 +1,112 @@
package org.jeecg.modules.system.util;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.ImportExcelUtil;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDepart;
import org.jeecg.modules.system.service.ISysUserDepartService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.service.impl.SysUserDepartServiceImpl;
import org.jeecg.modules.system.service.impl.SysUserServiceImpl;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @Description: 旧版导入
* @author: wangshuai
* @date: 2025/4/2 10:19
*/
@Slf4j
public class ImportOldUserUtil {
public static Result<?> importOldSysUser(HttpServletRequest request) throws IOException {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
// 错误信息
List<String> errorMessage = new ArrayList<>();
int successLines = 0, errorLines = 0;
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();// 获取上传文件对象
ImportParams params = new ImportParams();
params.setTitleRows(2);
params.setHeadRows(1);
params.setNeedSave(true);
try {
List<SysUser> listSysUsers = ExcelImportUtil.importExcel(file.getInputStream(), SysUser.class, params);
for (int i = 0; i < listSysUsers.size(); i++) {
SysUser sysUserExcel = listSysUsers.get(i);
if (StringUtils.isBlank(sysUserExcel.getPassword())) {
// 密码默认为 “123456”
sysUserExcel.setPassword("123456");
}
// 密码加密加盐
String salt = oConvertUtils.randomGen(8);
sysUserExcel.setSalt(salt);
String passwordEncode = PasswordUtil.encrypt(sysUserExcel.getUsername(), sysUserExcel.getPassword(), salt);
sysUserExcel.setPassword(passwordEncode);
try {
ISysUserService service = SpringContextUtils.getBean(SysUserServiceImpl.class);
service.save(sysUserExcel);
successLines++;
} catch (Exception e) {
errorLines++;
String message = e.getMessage().toLowerCase();
int lineNumber = i + 1;
// 通过索引名判断出错信息
if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_USERNAME)) {
errorMessage.add("" + lineNumber + " 行:用户名已经存在,忽略导入。");
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_WORK_NO)) {
errorMessage.add("" + lineNumber + " 行:工号已经存在,忽略导入。");
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_PHONE)) {
errorMessage.add("" + lineNumber + " 行:手机号已经存在,忽略导入。");
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_EMAIL)) {
errorMessage.add("" + lineNumber + " 行:电子邮件已经存在,忽略导入。");
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER)) {
errorMessage.add("" + lineNumber + " 行:违反表唯一性约束。");
} else {
errorMessage.add("" + lineNumber + " 行:未知错误,忽略导入");
log.error(e.getMessage(), e);
}
}
// 批量将部门和用户信息建立关联关系
String departIds = sysUserExcel.getDepartIds();
if (StringUtils.isNotBlank(departIds)) {
String userId = sysUserExcel.getId();
String[] departIdArray = departIds.split(",");
List<SysUserDepart> userDepartList = new ArrayList<>(departIdArray.length);
for (String departId : departIdArray) {
userDepartList.add(new SysUserDepart(userId, departId));
}
ISysUserDepartService service = SpringContextUtils.getBean(SysUserDepartServiceImpl.class);
service.saveBatch(userDepartList);
}
}
} catch (Exception e) {
errorMessage.add("发生异常:" + e.getMessage());
log.error(e.getMessage(), e);
} finally {
try {
file.getInputStream().close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
return ImportExcelUtil.imporReturnRes(errorLines, successLines, errorMessage);
}
}

View File

@ -0,0 +1,119 @@
package org.jeecg.modules.system.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @Description: 低代码用户导出
* @author: wangshuai
* @date: 2025/3/28 12:01
*/
@Data
public class SysUserExportVo {
/**
* 登录账号
*/
@Excel(name = "登录账号", width = 15)
private String username;
/**
* 真实姓名
*/
@Excel(name = "真实姓名", width = 15)
private String realname;
/**
* 头像
*/
@Excel(name = "头像", width = 15, type = 2)
private String avatar;
/**
* 生日
*/
@Excel(name = "生日", width = 15, format = "yyyy-MM-dd")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
/**
* 性别1男 2
*/
@Excel(name = "性别", width = 15, dicCode = "sex")
private Integer sex;
/**
* 电子邮件
*/
@Excel(name = "电子邮件", width = 15)
private String email;
/**
* 电话
*/
@Excel(name = "电话", width = 15)
private String phone;
/**
* 状态(1正常 2冻结
*/
@Excel(name = "状态", width = 15, dicCode = "user_status")
private Integer status;
/**
* 删除状态0正常1已删除
*/
@Excel(name = "删除状态", width = 15, dicCode = "del_flag")
private Integer delFlag;
/**
* 工号,唯一键
*/
@Excel(name = "工号", width = 15)
private String workNo;
/**
* 职务,关联职务表
*/
@Excel(name = "职务", width = 15)
@TableField(exist = false)
private String post;
/**
* 座机号
*/
@Excel(name = "座机号", width = 15)
private String telephone;
/**
* 身份0 普通成员 1 上级)
*/
@Excel(name = "1普通成员 2上级", width = 15)
private Integer userIdentity;
/**
* 角色名称
*/
@Excel(name = "角色", width = 15)
private String roleNames;
/**
* 部门名称
*/
@Excel(name = "所属部门", width = 15)
private String departNames;
/**
* 负责部门
*/
@Excel(name = "负责部门", width = 15)
private String departIds;
}

View File

@ -48,7 +48,10 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
<#assign has_multi_query_field=true>
</#if>
</#list>
<#assign enhanceJavaList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.enhanceJavaList??>
<#assign enhanceJavaList = tableVo.extendParams.enhanceJavaList?filter(enhance -> enhance??)>
</#if>
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
@ -79,6 +82,16 @@ 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) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='query' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 查询前触发的方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeQuery()
</#if>
</#list>
</#if>
<#if has_multi_query_field>
// 自定义查询规则
Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
@ -94,6 +107,14 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
</#if>
Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize);
IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper);
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='query' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
//TODO 查询后触发的方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.afterQuery()
</#if>
</#list>
</#if>
return Result.OK(pageList);
}
@ -108,10 +129,27 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequiresPermissions("${entityPackage}:${tableName}:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody ${entityName} ${entityName?uncap_first}) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='add' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 新增前的处理方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeAdd()
</#if>
</#list>
</#if>
<#if bpm_flag>
${entityName?uncap_first}.setBpmStatus("1");
</#if>
${entityName?uncap_first}Service.save(${entityName?uncap_first});
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='add' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
//TODO 新增后的处理方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.afterAdd()
</#if>
</#list>
</#if>
return Result.OK("添加成功!");
}
@ -126,7 +164,23 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequiresPermissions("${entityPackage}:${tableName}:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 编辑前,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeEdit()
</#if>
</#list>
</#if>
${entityName?uncap_first}Service.updateById(${entityName?uncap_first});
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
//TODO 编辑后,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.afterEdit()
</#if>
</#list>
</#if>
return Result.OK("编辑成功!");
}
@ -186,6 +240,14 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequiresPermissions("${entityPackage}:${tableName}:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='export' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 导出前,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeExport()
</#if>
</#list>
</#if>
return super.exportXls(request, ${entityName?uncap_first}, ${entityName}.class, "${tableVo.ftlDescription}");
}
@ -199,6 +261,14 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequiresPermissions("${entityPackage}:${tableName}:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='import' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 导入前,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeImport()
</#if>
</#list>
</#if>
return super.importExcel(request, response, ${entityName}.class);
}

View File

@ -51,6 +51,8 @@ public class ${entityName} implements Serializable {
</#if>
<#elseif po.classType=='sel_tree'>
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'>
<#elseif po.classType=='link_table'>
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'>
</#if>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>

View File

@ -8,8 +8,8 @@ navigationBarTitleText: '${tableVo.ftlDescription}',
},
}
</route>
<template>
<#assign onlyFields = []>
<PageLayout :navTitle="navTitle" :backRouteName="backRouteName">
<scroll-view class="scrollArea" scroll-y>
<view class="form-container">
@ -49,19 +49,11 @@ navigationBarTitleText: '${tableVo.ftlDescription}',
:required="true"
</#if>
>
<!-- #ifndef APP-PLUS -->
<online-file
v-model:value="myFormData[${autoStringSuffix(po)}]"
name=${autoStringSuffix(po)}
></online-file>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<online-file-custom
v-model:value="myFormData[${autoStringSuffix(po)}]"
name=${autoStringSuffix(po)}
></online-file-custom>
<!-- #endif -->
</wd-cell>
<#elseif po.classType =='datetime' || po.classType =='time'>
<DateTime
@ -166,6 +158,15 @@ navigationBarTitleText: '${tableVo.ftlDescription}',
clearable
v-model="myFormData[${autoStringSuffix(po)}]"
></wd-input>
<#elseif po.classType =='pca'>
<online-pca
:label="get4Label('${po.filedComment}')"
labelWidth="100px"
name=${autoStringSuffix(po)}
prop=${autoStringSuffix(po)}
clearable
v-model:value="myFormData[${autoStringSuffix(po)}]"
></online-pca>
<#elseif po.classType =='popup_dict'>
<PopupDict
labelWidth="100px"
@ -291,9 +292,12 @@ navigationBarTitleText: '${tableVo.ftlDescription}',
<#-- 金额 -->
<#elseif fieldValidType == 'money'>
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
<#-- 唯一校验 -->
<#elseif fieldValidType != '' && fieldValidType == 'only'>
<#assign onlyFields = onlyFields + [autoStringSuffix(po)]>
<#-- 正则校验 -->
<#elseif fieldValidType != '' && fieldValidType != '*'>
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
{ pattern: /${fieldValidType}/, message: '不符合校验规则!'},
<#-- 无校验 -->
<#else>
<#t>
@ -352,9 +356,12 @@ navigationBarTitleText: '${tableVo.ftlDescription}',
<#-- 金额 -->
<#elseif fieldValidType == 'money'>
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
<#-- 唯一校验 -->
<#elseif fieldValidType != '' && fieldValidType == 'only'>
<#assign onlyFields = onlyFields + [autoStringSuffix(po)]>
<#-- 正则校验 -->
<#elseif fieldValidType != '' && fieldValidType != '*'>
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
{ pattern: /${fieldValidType}/, message: '不符合校验规则!'},
<#-- 无校验 -->
<#else>
<#t>
@ -393,8 +400,10 @@ import OnlineRadio from '@/components/online/view/online-radio.vue'
import OnlineCheckbox from '@/components/online/view/online-checkbox.vue'
import OnlineMulti from '@/components/online/view/online-multi.vue'
import OnlinePopupLinkRecord from '@/components/online/view/online-popup-link-record.vue'
import OnlinePca from '@/components/online/view/online-pca.vue'
import SelectDept from '@/components/SelectDept/SelectDept.vue'
import SelectUser from '@/components/SelectUser/SelectUser.vue'
import {duplicateCheck} from "@/service/api";
defineOptions({
name: '${entityName}Form',
options: {
@ -434,8 +443,40 @@ const handleSuccess = () => {
uni.$emit('refreshList');
router.back()
}
/**
* 校验唯一
* @param values
* @returns {boolean}
*/
async function fieldCheck(values: any) {
const onlyField = [
<#list onlyFields as field>
${field}<#sep>, </#sep>
</#list>
];
for (const field of onlyField) {
if (values[field]) {
// 仅校验有值的字段
const res: any = await duplicateCheck({
tableName: '${tableName}',
fieldName: field, // 使用处理后的字段名
fieldVal: values[field],
dataId: values.id,
});
if (!res.success) {
toast.warning(res.message);
return true; // 校验失败
}
}
}
return false; // 校验通过
}
// 提交表单
const handleSubmit = () => {
const handleSubmit = async () => {
// 判断字段必填和正则
if (await fieldCheck(myFormData)) {
return
}
let url = dataId.value?'/${entityPackagePath}/${entityName?uncap_first}/edit':'/${entityPackagePath}/${entityName?uncap_first}/add';
form.value
.validate()
@ -509,4 +550,11 @@ onLoad((option) => {
padding-bottom: calc(constant(safe-area-inset-bottom) + 10px);
padding-bottom: calc(env(safe-area-inset-bottom) + 10px);
}
:deep(.wd-cell__label) {
font-size: 14px;
color: #444;
}
:deep(.wd-cell__value) {
text-align: left;
}
</style>

View File

@ -20,6 +20,10 @@
<#assign list_need_pca=true>
</#if>
</#list>
<#assign buttonList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
</#if>
<#-- 结束循环 -->
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
@ -28,6 +32,14 @@
<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>
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'button'>
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
</#if>
</#list>
</#if>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -75,6 +87,10 @@
</BasicTable>
<!-- 表单区域 -->
<${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
<#if bpm_flag==true>
<!-- 审批记录 -->
<BpmPictureModal @register="registerBpmModal" />
</#if>
</div>
</template>
@ -88,6 +104,7 @@
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import { useUserStore } from '/@/store/modules/user';
import { useMessage } from '/@/hooks/web/useMessage';
<#if list_need_pca>
import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
</#if>
@ -100,12 +117,23 @@
import {getPopDictByCode} from "@/utils/dict";
import {filterMultiDictText} from "@/utils/dict/JDictSelectUtil";
</#if>
import { getDateByPicker } from '/@/utils';
//日期个性化选择
const fieldPickers = reactive({
<#list columns as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
const [registerBpmModal, { openModal: bpmPicModal }] = useModal();
</#if>
const queryParam = reactive<any>({});
const checkedKeys = ref<Array<string | number>>([]);
const userStore = useUserStore();
const { createMessage } = useMessage();
//注册model
const [registerModal, {openModal}] = useModal();
//注册table数据
@ -114,7 +142,7 @@
title: '${tableVo.ftlDescription}',
api: list,
columns,
canResize:false,
canResize:true,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
@ -152,6 +180,13 @@
fixed:'right'
},
beforeFetch: (params) => {
if (params && fieldPickers) {
for (let key in fieldPickers) {
if (params[key]) {
params[key] = getDateByPicker(params[key], fieldPickers[key]);
}
}
}
return Object.assign(params, queryParam);
},
<#if list_has_popup_dict>
@ -261,7 +296,22 @@
placement: 'topLeft',
},
auth: '${entityPackage}:${tableName}:delete'
},
{
label: '审批进度',
onClick: handlePreviewPic.bind(null, record),
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
}
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'link'>
,{
label: '${btn.buttonName}',
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
}
</#if>
</#list>
</#if>
];
if(record.bpmStatus == '1'){
dropDownAction.push({
@ -288,6 +338,16 @@
},
auth: '${entityPackage}:${tableName}:delete'
}
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'link'>
,{
label: '${btn.buttonName}',
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
}
</#if>
</#list>
</#if>
]
</#if>
}
@ -306,8 +366,32 @@
await startProcess(params);
handleSuccess();
}
/**
* 审批进度
*/
async function handlePreviewPic(record) {
bpmPicModal(true, {
flowCode: 'dev_${tableName}_001',
dataId: record.id,
});
}
</#if>
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle=='button'>
function handle${btn.buttonCode?cap_first}(){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
<#if btn.buttonStyle=='link'>
function handle${btn.buttonCode?cap_first}(record){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
</#list>
</#if>
<#if list_need_category>
/**
* 初始化字典配置

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' || po.classType=='popup_dict'>
<#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' || po.classType=='link_table'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -423,6 +423,14 @@ export const formSchema: FormSchema[] = [
</#if>
pidValue:"${po.dictField}",
},
<#elseif po.classType=='link_table'>
component: 'JLinkTableCard',
componentProps: {
valueField: '${po.dictField}',
textField: '${po.dictText}',
tableName: '${po.dictTable}',
multi: <#if (po.queryMode!"") == "multi">true<#else>false</#if>
},
<#else>
component: 'Input',
</#if>

View File

@ -1,16 +1,32 @@
<#include "/common/utils.ftl">
<#assign buttonList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
</#if>
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
<BasicForm @register="registerForm" name="${entityName}Form" />
<#if buttonList?? && buttonList?size gt 0>
<template #insertFooter>
<#list buttonList as btn>
<#if btn.buttonStyle=='form'>
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
</#if>
</#list>
</template>
</#if>
</BasicModal>
</template>
<script lang="ts" setup>
import {ref, computed, unref} from 'vue';
import {ref, computed, unref, reactive} from 'vue';
import {BasicModal, useModalInner} from '/@/components/Modal';
import {BasicForm, useForm} from '/@/components/Form/index';
import {formSchema} from '../${entityName}.data';
import {saveOrUpdate} from '../${entityName}.api';
import { useMessage } from '/@/hooks/web/useMessage';
import { getDateByPicker } from '/@/utils';
const { createMessage } = useMessage();
// Emits声明
const emit = defineEmits(['register','success']);
const isUpdate = ref(true);
@ -40,12 +56,22 @@
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter })
});
//日期个性化选择
const fieldPickers = reactive({
<#list columns as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
//设置标题
const title = computed(() => (!unref(isUpdate) ? '新增' : !unref(isDetail) ? '详情' : '编辑'));
//表单提交事件
async function handleSubmit(v) {
try {
let values = await validate();
// 预处理日期数据
changeDateValue(values);
setModalProps({confirmLoading: true});
//提交表单
await saveOrUpdate(values, isUpdate.value);
@ -65,6 +91,30 @@
setModalProps({confirmLoading: false});
}
}
/**
* 处理日期值
* @param formData 表单数据
*/
const changeDateValue = (formData) => {
if (formData && fieldPickers) {
for (let key in fieldPickers) {
if (formData[key]) {
formData[key] = getDateByPicker(formData[key], fieldPickers[key]);
}
}
}
};
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle=='form'>
function handle${btn.buttonCode?cap_first}(){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
</#list>
</#if>
</script>
<style lang="less" scoped>

View File

@ -23,6 +23,10 @@
<#assign need_range_number = false>
<#assign is_range = false>
<#assign query_flag = false>
<#assign buttonList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
</#if>
<#assign is_like = false>
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
@ -105,6 +109,13 @@
<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>
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'button'>
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
</#if>
</#list>
</#if>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -151,6 +162,10 @@
</BasicTable>
<!-- 表单区域 -->
<${entityName}Modal ref="registerModal" @success="handleSuccess"></${entityName}Modal>
<#if bpm_flag==true>
<!-- 审批记录 -->
<BpmPictureModal @register="registerBpmModal" />
</#if>
</div>
</template>
@ -163,6 +178,8 @@
import { downloadFile } from '/@/utils/common/renderUtils';
import ${entityName}Modal from './components/${entityName}Modal.vue'
import { useUserStore } from '/@/store/modules/user';
import { useMessage } from '/@/hooks/web/useMessage';
import {useModal} from '/@/components/Modal';
<#include "/common/form/native/vue3NativeImport.ftl">
<#if need_category>
import { loadCategoryData } from '/@/api/common/api';
@ -172,29 +189,40 @@
<#if need_pca>
import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
</#if>
import { getDateByPicker } from '/@/utils';
<#if need_popup_dict>
import {getPopDictByCode} from "@/utils/dict";
import {filterMultiDictText} from "@/utils/dict/JDictSelectUtil";
</#if>
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
const [registerBpmModal, { openModal: bpmPicModal }] = useModal();
</#if>
<#if is_range>
import { cloneDeep } from "lodash-es";
</#if>
const fieldPickers = reactive({
<#list columns as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
const formRef = ref();
const queryParam = reactive<any>({});
const toggleSearchStatus = ref<boolean>(false);
const registerModal = ref();
const userStore = useUserStore();
const { createMessage } = useMessage();
//注册table数据
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
title: '${tableVo.ftlDescription}',
api: list,
columns,
canResize:false,
canResize:true,
useSearchForm: false,
actionColumn: {
width: 120,
@ -205,6 +233,11 @@
let rangerQuery = await setRangeQuery();
return Object.assign(params, rangerQuery);
<#else>
for (let key in fieldPickers) {
if (queryParam[key] && fieldPickers[key]) {
queryParam[key] = getDateByPicker(queryParam[key], fieldPickers[key]);
}
}
return Object.assign(params, queryParam);
</#if>
},
@ -328,7 +361,22 @@
placement: 'topLeft',
},
auth: '${entityPackage}:${tableName}:delete'
}
},
{
label: '审批进度',
onClick: handlePreviewPic.bind(null, record),
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
}
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'link'>
,{
label: '${btn.buttonName}',
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
}
</#if>
</#list>
</#if>
];
if(record.bpmStatus == '1'){
dropDownAction.push({
@ -355,6 +403,16 @@
},
auth: '${entityPackage}:${tableName}:delete'
}
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'link'>
,{
label: '${btn.buttonName}',
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
}
</#if>
</#list>
</#if>
]
</#if>
}
@ -413,9 +471,33 @@
}
await startProcess(params);
handleSuccess();
}
/**
* 审批进度
*/
async function handlePreviewPic(record) {
bpmPicModal(true, {
flowCode: 'dev_${tableName}_001',
dataId: record.id,
});
}
</#if>
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle=='button'>
function handle${btn.buttonCode?cap_first}(){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
<#if btn.buttonStyle=='link'>
function handle${btn.buttonCode?cap_first}(record){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
</#list>
</#if>
<#if need_category>
/**
* form点击事件

View File

@ -61,7 +61,7 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
<#include "/common/form/native/vue3NativeImport.ftl">
import { getValueType } from '/@/utils';
import { getDateByPicker, getValueType } from '/@/utils';
import { saveOrUpdate } from '../${entityName}.api';
import { Form } from 'ant-design-vue';
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
@ -93,6 +93,14 @@
<#include "/common/validatorRulesTemplate/native/vue3MainNative.ftl">
});
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: false });
//日期个性化选择
const fieldPickers = reactive({
<#list columns as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
// 表单禁用
const disabled = computed(()=>{
@ -181,6 +189,8 @@
}
//循环数据
for (let data in model) {
// 更新个性化日期选择器的值
model[data] = getDateByPicker(model[data], fieldPickers[data]);
//如果该数据是数组并且是字符串类型
if (model[data] instanceof Array) {
let valueType = getValueType(formRef.value.getProps, data);

View File

@ -1,6 +1,21 @@
<template>
<#assign buttonList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
</#if>
<j-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
<${entityName}Form ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></${entityName}Form>
<template #footer>
<#if buttonList?? && buttonList?size gt 0>
<#list buttonList as btn>
<#if btn.buttonStyle=='form'>
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
</#if>
</#list>
</#if>
<a-button @click="handleCancel">取消</a-button>
<a-button :class="{ 'jee-hidden': disableSubmit }" type="primary" @click="handleOk">确认</a-button>
</template>
</j-modal>
</template>
@ -8,7 +23,8 @@
import { ref, nextTick, defineExpose } from 'vue';
import ${entityName}Form from './${entityName}Form.vue'
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
import { useMessage } from '/@/hooks/web/useMessage';
const { createMessage } = useMessage();
const title = ref<string>('');
const width = ref<number>(800);
const visible = ref<boolean>(false);
@ -60,7 +76,15 @@
function handleCancel() {
visible.value = false;
}
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle=='form'>
function handle${btn.buttonCode?cap_first}(){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
</#list>
</#if>
defineExpose({
add,
edit,

View File

@ -50,6 +50,10 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
<#assign pidFieldName = po.fieldName>
</#if>
</#list>
<#assign enhanceJavaList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.enhanceJavaList??>
<#assign enhanceJavaList = tableVo.extendParams.enhanceJavaList?filter(enhance -> enhance??)>
</#if>
@Tag(name="${tableVo.ftlDescription}")
@RestController
@RequestMapping("/${entityPackagePath}/${entityName?uncap_first}")
@ -74,6 +78,14 @@ 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) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='query' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 查询前触发的方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeQuery()
</#if>
</#list>
</#if>
String hasQuery = req.getParameter("hasQuery");
if(hasQuery != null && "true".equals(hasQuery)){
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap());
@ -92,6 +104,14 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
queryWrapper.eq("${Format.humpToUnderline(pidFieldName)}", parentId);
Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize);
IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper);
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='query' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
//TODO 查询后触发的方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.afterQuery()
</#if>
</#list>
</#if>
return Result.OK(pageList);
}
}
@ -210,7 +230,23 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequiresPermissions("${entityPackage}:${tableName}:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody ${entityName} ${entityName?uncap_first}) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='add' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 新增前的处理方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeAdd()
</#if>
</#list>
</#if>
${entityName?uncap_first}Service.add${entityName}(${entityName?uncap_first});
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='add' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
//TODO 新增后的处理方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.afterAdd()
</#if>
</#list>
</#if>
return Result.OK("添加成功!");
}
@ -225,7 +261,23 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequiresPermissions("${entityPackage}:${tableName}:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 编辑前,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeEdit()
</#if>
</#list>
</#if>
${entityName?uncap_first}Service.update${entityName}(${entityName?uncap_first});
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
//TODO 编辑后,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.afterEdit()
</#if>
</#list>
</#if>
return Result.OK("编辑成功!");
}
@ -285,6 +337,14 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequiresPermissions("${entityPackage}:${tableName}:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='export' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 导出前,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeExport()
</#if>
</#list>
</#if>
return super.exportXls(request, ${entityName?uncap_first}, ${entityName}.class, "${tableVo.ftlDescription}");
}
@ -298,6 +358,14 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequiresPermissions("${entityPackage}:${tableName}:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='import' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 导入前,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeImport()
</#if>
</#list>
</#if>
return super.importExcel(request, response, ${entityName}.class);
}

View File

@ -48,6 +48,8 @@ public class ${entityName} implements Serializable {
</#if>
<#elseif po.classType=='sel_tree'>
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'>
<#elseif po.classType=='link_table'>
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'>
</#if>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>

View File

@ -12,6 +12,10 @@
</#if>
</#list>
<#assign list_need_pca=false>
<#assign buttonList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
</#if>
<#-- 开始循环 -->
<#list columns as po>
<#if po.fieldDbName=='bpm_status'>
@ -33,7 +37,13 @@
<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>
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'button'>
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
</#if>
</#list>
</#if>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -81,6 +91,10 @@
</BasicTable>
<!--字典弹窗-->
<${entityName}Modal @register="registerModal" @success="handleSuccess"/>
<#if bpm_flag==true>
<!-- 审批记录 -->
<BpmPictureModal @register="registerBpmModal" />
</#if>
</div>
</template>
@ -93,6 +107,7 @@
import ${entityName}Modal from './components/${entityName}Modal.vue';
import {columns, searchFormSchema, superQuerySchema} from './${entityName}.data';
import { downloadFile } from '/@/utils/common/renderUtils';
import { useMessage } from '/@/hooks/web/useMessage';
import {list, delete${entityName}, batchDelete${entityName}, getExportUrl,getImportUrl, getChildList,getChildListBatch} from './${entityName}.api';
<#if list_need_pca>
import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
@ -101,9 +116,20 @@
import {getPopDictByCode} from "@/utils/dict";
import {filterMultiDictText} from "@/utils/dict/JDictSelectUtil";
</#if>
import { getDateByPicker } from '/@/utils';
//日期个性化选择
const fieldPickers = reactive({
<#list columns as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
const [registerBpmModal, { openModal: bpmPicModal }] = useModal();
</#if>
const { createMessage } = useMessage();
const queryParam = reactive<any>({});
const expandedRowKeys = ref([]);
//字典model
@ -114,7 +140,7 @@
api: list,
title: '${tableVo.ftlDescription}',
columns,
canResize:false,
canResize:true,
<#-- update-begin---author:chenrui ---date:20231228 for[issue/#5658] 树表复选框与展开按钮重叠问题---------- -->
isTreeTable: true,
<#-- update-end---author:chenrui ---date:20231228 for[issue/#5658] 树表复选框与展开按钮重叠问题---------- -->
@ -155,7 +181,14 @@
fixed:'right'
},
beforeFetch: (params) => {
params.hasQuery = "true";
if (params && fieldPickers) {
for (let key in fieldPickers) {
if (params[key]) {
params[key] = getDateByPicker(params[key], fieldPickers[key]);
}
}
}
params.hasQuery = "true";
return Object.assign(params, queryParam);
},
<#if list_has_popup_dict>
@ -408,6 +441,21 @@
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
},{
label: '审批进度',
onClick: handlePreviewPic.bind(null, record),
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
}
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'link'>
,{
label: '${btn.buttonName}',
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
}
</#if>
</#list>
</#if>
];
if(record.bpmStatus == '1' || !record.bpmStatus){
dropDownAction.push({
@ -434,6 +482,16 @@
},
auth: '${entityPackage}:${tableName}:delete'
}
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'link'>
,{
label: '${btn.buttonName}',
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
}
</#if>
</#list>
</#if>
]
</#if>
}
@ -452,6 +510,16 @@
await startProcess(params);
await reload();
}
/**
* 审批进度
*/
async function handlePreviewPic(record) {
bpmPicModal(true, {
flowCode: 'dev_${tableName}_001',
dataId: record.id,
});
}
</#if>
<#if list_has_popup_dict>
/**
@ -474,6 +542,21 @@
return records;
}
</#if>
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle=='button'>
function handle${btn.buttonCode?cap_first}(){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
<#if btn.buttonStyle=='link'>
function handle${btn.buttonCode?cap_first}(record){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
</#list>
</#if>
</script>
<style lang="less" scoped>

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' || po.classType=='popup_dict'>
<#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' || po.classType=='link_table'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -198,6 +198,14 @@ export const searchFormSchema: FormSchema[] = [
</#if>
pidValue:"${po.dictField}",
},
<#elseif po.classType=='link_table'>
component: 'JLinkTableCard',
componentProps: {
valueField: '${po.dictField}',
textField: '${po.dictText}',
tableName: '${po.dictTable}',
multi: <#if (po.queryMode!"") == "multi">true<#else>false</#if>
},
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
component: 'JSelectMultiple',

View File

@ -9,17 +9,41 @@
<#assign hasChildrenField = po.fieldName>
</#if>
</#list>
<#assign buttonList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
</#if>
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" :title="getTitle" @ok="handleSubmit">
<BasicForm @register="registerForm" name="${entityName}Form" />
<#if buttonList?? && buttonList?size gt 0>
<template #insertFooter>
<#list buttonList as btn>
<#if btn.buttonStyle=='form'>
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
</#if>
</#list>
</template>
</#if>
</BasicModal>
</template>
<script lang="ts" setup>
import {ref, computed, unref} from 'vue';
import {ref, computed, unref, reactive} from 'vue';
import {BasicModal, useModalInner} from '/@/components/Modal';
import {BasicForm, useForm} from '/@/components/Form';
import {formSchema} from '../${entityName}.data';
import {loadTreeData, saveOrUpdateDict} from '../${entityName}.api';
import { useMessage } from '/@/hooks/web/useMessage';
import { getDateByPicker } from '/@/utils';
//日期个性化选择
const fieldPickers = reactive({
<#list columns as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
const { createMessage } = useMessage();
// 获取emit
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
@ -88,6 +112,8 @@
async function handleSubmit() {
try {
let values = await validate();
// 预处理日期数据
changeDateValue(values);
setModalProps({confirmLoading: true});
//提交表单
await saveOrUpdateDict(values, isUpdate.value);
@ -115,6 +141,30 @@
setModalProps({confirmLoading: false});
}
}
/**
* 处理日期值
* @param formData 表单数据
*/
const changeDateValue = (formData) => {
if (formData && fieldPickers) {
for (let key in fieldPickers) {
if (formData[key]) {
formData[key] = getDateByPicker(formData[key], fieldPickers[key]);
}
}
}
};
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle=='form'>
function handle${btn.buttonCode?cap_first}(){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
</#list>
</#if>
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */

View File

@ -33,6 +33,10 @@
<#assign need_range_number = false>
<#assign is_range = false>
<#assign is_like = false>
<#assign buttonList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
</#if>
<#assign query_flag = false>
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
@ -113,6 +117,13 @@
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'button'>
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
</#if>
</#list>
</#if>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -161,6 +172,10 @@
</BasicTable>
<!-- 表单区域 -->
<${entityName}Modal ref="registerModal" @success="handleSuccess"></${entityName}Modal>
<#if bpm_flag==true>
<!-- 审批记录 -->
<BpmPictureModal @register="registerBpmModal" />
</#if>
</div>
</template>
@ -172,6 +187,7 @@
import {list, delete${entityName}, batchDelete${entityName}, getExportUrl,getImportUrl, getChildList,getChildListBatch} from './${entityName}.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import ${entityName}Modal from './components/${entityName}Modal.vue'
import { useMessage } from '/@/hooks/web/useMessage';
<#include "/common/form/native/vue3NativeImport.ftl">
<#if need_category>
import { loadCategoryData } from '/@/api/common/api';
@ -181,6 +197,7 @@
<#if need_pca>
import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
</#if>
import { getDateByPicker } from '/@/utils';
<#if need_popup_dict>
import {getPopDictByCode} from "@/utils/dict";
import {filterMultiDictText} from "@/utils/dict/JDictSelectUtil";
@ -190,8 +207,16 @@
</#if>
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
const [registerBpmModal, { openModal: bpmPicModal }] = useModal();
</#if>
const fieldPickers = reactive({
<#list columns as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
const { createMessage } = useMessage();
const expandedRowKeys = ref([]);
const queryParam = ref<any>({});
const toggleSearchStatus = ref<boolean>(false);
@ -202,7 +227,7 @@
title: '${tableVo.ftlDescription}',
api: list,
columns,
canResize:false,
canResize:true,
useSearchForm: false,
isTreeTable: true,
actionColumn: {
@ -215,6 +240,11 @@
let rangerQuery = await setRangeQuery();
return Object.assign(params, rangerQuery);
<#else>
for (let key in fieldPickers) {
if (queryParam[key] && fieldPickers[key]) {
queryParam[key] = getDateByPicker(queryParam[key], fieldPickers[key]);
}
}
return Object.assign(params, queryParam.value);
</#if>
},
@ -480,6 +510,21 @@
},
auth: '${entityPackage}:${tableName}:delete'
},
{
label: '审批进度',
onClick: handlePreviewPic.bind(null, record),
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
}
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'link'>
,{
label: '${btn.buttonName}',
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
}
</#if>
</#list>
</#if>
];
if(record.bpmStatus == '1' || !record.bpmStatus){
dropDownAction.push({
@ -510,7 +555,17 @@
placement: 'topLeft',
},
auth: '${entityPackage}:${tableName}:delete'
},
}
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'link'>
,{
label: '${btn.buttonName}',
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
}
</#if>
</#list>
</#if>
];
</#if>
}
@ -528,9 +583,31 @@
}
await startProcess(params);
await reload();
}
/**
* 审批进度
*/
async function handlePreviewPic(record) {
bpmPicModal(true, {
flowCode: 'dev_${tableName}_001',
dataId: record.id,
});
}
</#if>
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle=='button'>
function handle${btn.buttonCode?cap_first}(){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
<#if btn.buttonStyle=='link'>
function handle${btn.buttonCode?cap_first}(record){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
</#list>
</#if>
/**
* 查询

View File

@ -79,7 +79,7 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
<#include "/common/form/native/vue3NativeImport.ftl">
import { getValueType } from '/@/utils';
import { getDateByPicker, getValueType } from '/@/utils';
import {loadTreeData, saveOrUpdateDict} from '../${entityName}.api';
import { Form } from 'ant-design-vue';
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
@ -111,6 +111,14 @@
<#include "/common/validatorRulesTemplate/native/vue3MainNative.ftl">
});
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: false });
//日期个性化选择
const fieldPickers = reactive({
<#list columns as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
const props = defineProps({
formDisabled: { type: Boolean, default: false },
formData: { type: Object, default: () => ({}) },
@ -224,6 +232,8 @@
}
//循环数据
for (let data in formData) {
// 更新个性化日期选择器的值
model[data] = getDateByPicker(model[data], fieldPickers[data]);
//如果该数据是数组并且是字符串类型
if (formData[data] instanceof Array) {
let valueType = getValueType(formRef.value.getProps, data);

View File

@ -1,6 +1,21 @@
<template>
<#assign buttonList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
</#if>
<j-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
<${entityName}Form ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></${entityName}Form>
<template #footer>
<#if buttonList?? && buttonList?size gt 0>
<#list buttonList as btn>
<#if btn.buttonStyle=='form'>
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
</#if>
</#list>
</#if>
<a-button @click="handleCancel">取消</a-button>
<a-button :class="{ 'jee-hidden': disableSubmit }" type="primary" @click="handleOk">确认</a-button>
</template>
</j-modal>
</template>
@ -8,7 +23,9 @@
import { ref, nextTick, defineExpose } from 'vue';
import ${entityName}Form from './${entityName}Form.vue'
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
import { useMessage } from '/@/hooks/web/useMessage';
const { createMessage } = useMessage();
const title = ref<string>('');
const width = ref<number>(800);
const visible = ref<boolean>(false);

View File

@ -47,6 +47,10 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
<#assign has_multi_query_field=true>
</#if>
</#list>
<#assign enhanceJavaList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.enhanceJavaList??>
<#assign enhanceJavaList = tableVo.extendParams.enhanceJavaList?filter(enhance -> enhance??)>
</#if>
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
@ -85,6 +89,14 @@ 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) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='query' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 查询前触发的方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeQuery()
</#if>
</#list>
</#if>
<#if has_multi_query_field>
// 自定义查询规则
Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
@ -100,6 +112,14 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
</#if>
Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize);
IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper);
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='query' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
//TODO 查询后触发的方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.afterQuery()
</#if>
</#list>
</#if>
return Result.OK(pageList);
}
@ -113,7 +133,23 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequiresPermissions("${entityPackage}:${tableName}:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody ${entityName} ${entityName?uncap_first}) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='add' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 新增前的处理方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeAdd()
</#if>
</#list>
</#if>
${entityName?uncap_first}Service.save(${entityName?uncap_first});
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='add' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
//TODO 新增后的处理方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.afterAdd()
</#if>
</#list>
</#if>
return Result.OK("添加成功!");
}
@ -127,7 +163,23 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequiresPermissions("${entityPackage}:${tableName}:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 编辑前,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeEdit()
</#if>
</#list>
</#if>
${entityName?uncap_first}Service.updateById(${entityName?uncap_first});
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
//TODO 编辑后,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.afterEdit()
</#if>
</#list>
</#if>
return Result.OK("编辑成功!");
}
@ -166,6 +218,14 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequiresPermissions("${entityPackage}:${tableName}:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='export' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 导出前,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeExport()
</#if>
</#list>
</#if>
return super.exportXls(request, ${entityName?uncap_first}, ${entityName}.class, "${tableVo.ftlDescription}");
}
@ -176,6 +236,14 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e
@RequiresPermissions("${entityPackage}:${tableName}:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='import' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 导入前,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeImport()
</#if>
</#list>
</#if>
return super.importExcel(request, response, ${entityName}.class);
}
/*---------------------------------主表处理-end-------------------------------------*/

View File

@ -47,6 +47,8 @@ public class ${entityName} implements Serializable {
</#if>
<#elseif po.classType=='sel_tree'>
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'>
<#elseif po.classType=='link_table'>
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'>
</#if>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>

View File

@ -72,6 +72,10 @@ public class ${subTab.entityName} implements Serializable {
<#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"'>
@Dict(${list_field_dictCode})
</#if>
<#if po.classType =='link_table'>
<#assign list_field_dictCode='dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dictTable = "sys_depart"'>
@Dict(${list_field_dictCode})
</#if>
<#-- 大字段转换 -->
<#include "/common/blob.ftl">

View File

@ -20,6 +20,10 @@
</#if>
</#list>
<#-- 结束循环 -->
<#assign buttonList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
</#if>
<div class="content">
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
@ -28,6 +32,13 @@
<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>
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'button'>
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
</#if>
</#list>
</#if>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -86,6 +97,10 @@
</div>
<!-- 表单区域 -->
<${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
<#if bpm_flag==true>
<!-- 审批记录 -->
<BpmPictureModal @register="registerBpmModal" />
</#if>
</div>
</template>
@ -96,6 +111,7 @@
import {useModal} from '/@/components/Modal';
import ${entityName}Modal from './components/${entityName}Modal.vue'
import { useUserStore } from '/@/store/modules/user';
import { useMessage } from '/@/hooks/web/useMessage';
<#list subTables as sub>
import ${sub.entityName}List from './${sub.entityName}List.vue'
</#list>
@ -114,10 +130,21 @@
import { getAuthCache, setAuthCache } from '/@/utils/auth';
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
</#if>
import { getDateByPicker } from '/@/utils';
//日期个性化选择
const fieldPickers = reactive({
<#list columns as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
const [registerBpmModal, { openModal: bpmPicModal }] = useModal();
</#if>
const queryParam = reactive<any>({});
const { createMessage } = useMessage();
//注册model
const [registerModal, {openModal}] = useModal();
//注册table数据
@ -126,7 +153,7 @@
title: '${tableVo.ftlDescription}',
api: list,
columns,
canResize: false,
canResize: true,
clickToRowSelect: true,
rowSelection: {type: 'radio'},
formConfig: {
@ -163,6 +190,13 @@
fixed:'right'
},
beforeFetch: (params) => {
if (params && fieldPickers) {
for (let key in fieldPickers) {
if (params[key]) {
params[key] = getDateByPicker(params[key], fieldPickers[key]);
}
}
}
return Object.assign(params, queryParam);
},
<#if list_has_popup_dict>
@ -280,6 +314,15 @@
await startProcess(params);
handleSuccess();
}
/**
* 审批进度
*/
async function handlePreviewPic(record) {
bpmPicModal(true, {
flowCode: 'dev_${tableName}_001',
dataId: record.id,
});
}
</#if>
/**
@ -299,7 +342,22 @@
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
},
{
label: '审批进度',
onClick: handlePreviewPic.bind(null, record),
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
}
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'link'>
,{
label: '${btn.buttonName}',
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
}
</#if>
</#list>
</#if>
];
if(record.bpmStatus == '1'){
dropDownAction.push({
@ -325,6 +383,16 @@
},
auth: '${entityPackage}:${tableName}:delete'
}
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'link'>
,{
label: '${btn.buttonName}',
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
}
</#if>
</#list>
</#if>
]
</#if>
}
@ -373,6 +441,21 @@
return records;
}
</#if>
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle=='button'>
function handle${btn.buttonCode?cap_first}(){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
<#if btn.buttonStyle=='link'>
function handle${btn.buttonCode?cap_first}(record){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
</#list>
</#if>
</script>
<style lang="less" scoped>
@ -381,7 +464,6 @@
height: 100%;
.content {
background-color: #fff;
height: 100%;
}
}
}

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' || po.classType=='popup_dict'>
<#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' || po.classType=='link_table'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -418,6 +418,14 @@ export const formSchema: FormSchema[] = [
</#if>
pidValue:"${po.dictField}",
},
<#elseif po.classType=='link_table'>
component: 'JLinkTableCard',
componentProps: {
valueField: '${po.dictField}',
textField: '${po.dictText}',
tableName: '${po.dictTable}',
multi: <#if (po.queryMode!"") == "multi">true<#else>false</#if>
},
<#else>
component: 'Input',
</#if>
@ -551,7 +559,7 @@ export const ${sub.entityName?uncap_first}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=='link_table'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -740,6 +748,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
</#if>
pidValue:"${po.dictField}",
},
<#elseif po.classType=='link_table'>
component: 'JLinkTableCard',
componentProps: {
valueField: '${po.dictField}',
textField: '${po.dictText}',
tableName: '${po.dictTable}',
multi: <#if (po.queryMode!"") == "multi">true<#else>false</#if>
},
<#else>
component: 'Input',
</#if>

View File

@ -75,7 +75,7 @@
tableProps: {
api: ${sub.entityName?uncap_first}List,
columns: ${sub.entityName?uncap_first}Columns,
canResize: false,
canResize: true,
useSearchForm: false,
actionColumn: {
width: 180,

View File

@ -1,16 +1,40 @@
<#include "/common/utils.ftl">
<template>
<#assign buttonList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
</#if>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
<BasicForm @register="registerForm" name="${entityName}Form" />
<#if buttonList?? && buttonList?size gt 0>
<template #insertFooter>
<#list buttonList as btn>
<#if btn.buttonStyle=='form'>
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
</#if>
</#list>
</template>
</#if>
</BasicModal>
</template>
<script lang="ts" setup>
import {ref, computed, unref} from 'vue';
import {ref, computed, unref, reactive} from 'vue';
import {BasicModal, useModalInner} from '/@/components/Modal';
import {BasicForm, useForm} from '/@/components/Form/index';
import {formSchema} from '../${entityName}.data';
import {saveOrUpdate} from '../${entityName}.api';
import { useMessage } from '/@/hooks/web/useMessage';
import { getDateByPicker } from '/@/utils';
//日期个性化选择
const fieldPickers = reactive({
<#list columns as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
const { createMessage } = useMessage();
// Emits声明
const emit = defineEmits(['register','success']);
const isUpdate = ref(true);
@ -46,6 +70,8 @@
async function handleSubmit(v) {
try {
let values = await validate();
// 预处理日期数据
changeDateValue(values);
setModalProps({confirmLoading: true});
//提交表单
await saveOrUpdate(values, isUpdate.value);
@ -65,6 +91,29 @@
setModalProps({confirmLoading: false});
}
}
/**
* 处理日期值
* @param formData 表单数据
*/
const changeDateValue = (formData) => {
if (formData && fieldPickers) {
for (let key in fieldPickers) {
if (formData[key]) {
formData[key] = getDateByPicker(formData[key], fieldPickers[key]);
}
}
}
};
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle=='form'>
function handle${btn.buttonCode?cap_first}(){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
</#list>
</#if>
</script>
<style lang="less" scoped>

View File

@ -8,11 +8,20 @@
</template>
<script lang="ts" setup>
import {ref, computed, unref,inject} from 'vue';
import {ref, computed, unref,inject, reactive} from 'vue';
import {BasicModal, useModalInner} from '/@/components/Modal';
import {BasicForm, useForm} from '/@/components/Form/index';
import {${sub.entityName?uncap_first}FormSchema} from '../${entityName}.data';
import {${sub.entityName?uncap_first}SaveOrUpdate} from '../${entityName}.api';
import { getDateByPicker } from '/@/utils';
//日期个性化选择
const fieldPickers = reactive({
<#list sub.colums as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
//接收主表id
const mainId = inject('mainId');
@ -51,6 +60,8 @@
async function handleSubmit(v) {
try {
let values = await validate();
// 预处理日期数据
changeDateValue(values);
setModalProps({confirmLoading: true});
if (unref(mainId)) {
<#list sub.foreignKeys as key>
@ -74,6 +85,20 @@
setModalProps({confirmLoading: false});
}
}
/**
* 处理日期值
* @param formData 表单数据
*/
const changeDateValue = (formData) => {
if (formData && fieldPickers) {
for (let key in fieldPickers) {
if (formData[key]) {
formData[key] = getDateByPicker(formData[key], fieldPickers[key]);
}
}
}
};
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */

View File

@ -24,6 +24,10 @@
<#assign need_range_number = false>
<#assign is_range = false>
<#assign is_like = false>
<#assign buttonList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
</#if>
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
<a-form ref="formRef" @keyup.enter.native="reload" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
@ -109,6 +113,13 @@
<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>
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'button'>
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
</#if>
</#list>
</#if>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -168,6 +179,10 @@
</div>
<!-- 表单区域 -->
<${entityName}Modal ref="registerModal" @success="handleSuccess" />
<#if bpm_flag==true>
<!-- 审批记录 -->
<BpmPictureModal @register="registerBpmModal" />
</#if>
</div>
</template>
@ -175,10 +190,12 @@
import { ref, reactive, computed, unref, provide } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage'
import {useModal} from '/@/components/Modal';
import ${entityName}Modal from './components/${entityName}Modal.vue'
import { columns, superQuerySchema } from './${entityName}.data';
import { list, deleteOne, batchDelete, getImportUrl,getExportUrl } from './${entityName}.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import { useMessage } from '/@/hooks/web/useMessage';
<#include "/common/form/native/vue3NativeImport.ftl">
<#if need_pca>
import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
@ -188,8 +205,11 @@
import { getAuthCache, setAuthCache } from '/@/utils/auth';
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
</#if>
import { getDateByPicker } from '/@/utils';
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
const [registerBpmModal, { openModal: bpmPicModal }] = useModal();
</#if>
<#list subTables as sub>
import ${sub.entityName}List from './${sub.entityName}List.vue'
@ -202,18 +222,27 @@
import {getPopDictByCode} from "@/utils/dict";
import {filterMultiDictText} from "@/utils/dict/JDictSelectUtil";
</#if>
const fieldPickers = reactive({
<#list columns as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
const formRef = ref();
const queryParam = reactive<any>({});
const checkedKeys = ref<Array<string | number>>([]);
const registerModal = ref();
const userStore = useUserStore();
const { createMessage } = useMessage();
//注册table数据
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
tableProps:{
title: '${tableVo.ftlDescription}',
api: list,
columns,
canResize:false,
canResize:true,
useSearchForm: false,
clickToRowSelect: true,
rowSelection: {type: 'radio'},
@ -226,6 +255,11 @@
let rangerQuery = await setRangeQuery();
return Object.assign(params, rangerQuery);
<#else>
for (let key in fieldPickers) {
if (queryParam[key] && fieldPickers[key]) {
queryParam[key] = getDateByPicker(queryParam[key], fieldPickers[key]);
}
}
return Object.assign(params, queryParam);
</#if>
},
@ -348,7 +382,22 @@
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
},
{
label: '审批进度',
onClick: handlePreviewPic.bind(null, record),
ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
},
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'link'>
,{
label: '${btn.buttonName}',
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
}
</#if>
</#list>
</#if>
];
if(record.bpmStatus == '1' || !record.bpmStatus){
dropDownAction.push({
@ -375,7 +424,17 @@
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
},
}
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle == 'link'>
,{
label: '${btn.buttonName}',
onClick: handle${btn.buttonCode?cap_first}.bind(null, record),
}
</#if>
</#list>
</#if>
];
</#if>
}
@ -394,8 +453,30 @@
await startProcess(params);
handleSuccess();
}
/**
* 审批进度
*/
async function handlePreviewPic(record) {
bpmPicModal(true, {
flowCode: 'dev_${tableName}_001',
dataId: record.id,
});
}
</#if>
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle=='button'>
function handle${btn.buttonCode?cap_first}(){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
<#if btn.buttonStyle=='link'>
function handle${btn.buttonCode?cap_first}(record){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
</#list>
</#if>
<#if need_category>
/**
* form点击事件
@ -526,7 +607,6 @@
height: 100%;
.content {
background-color: #fff;
height: 100%;
}
}
</style>

View File

@ -84,7 +84,7 @@
tableProps: {
api: ${sub.entityName?uncap_first}List,
columns: ${sub.entityName?uncap_first}Columns,
canResize: false,
canResize: true,
useSearchForm: false,
actionColumn: {
width: 180,

View File

@ -61,7 +61,7 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
<#include "/common/form/native/vue3NativeImport.ftl">
import { getValueType } from '/@/utils';
import { getDateByPicker, getValueType } from '/@/utils';
import { saveOrUpdate } from '../${entityName}.api';
import { Form } from 'ant-design-vue';
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
@ -89,6 +89,14 @@
<#include "/common/validatorRulesTemplate/native/vue3MainNative.ftl">
});
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: false });
//日期个性化选择
const fieldPickers = reactive({
<#list columns as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
const formRef = ref();
// 表单禁用
const disabled = computed(()=>{
@ -176,6 +184,8 @@
}
//循环数据
for (let data in model) {
// 更新个性化日期选择器的值
model[data] = getDateByPicker(model[data], fieldPickers[data]);
//如果该数据是数组并且是字符串类型
if (model[data] instanceof Array) {
let valueType = getValueType(formRef.value.getProps, data);

View File

@ -1,14 +1,31 @@
<template>
<#assign buttonList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??>
<#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)>
</#if>
<j-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
<${entityName}Form ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></${entityName}Form>
</j-modal>
<template #footer>
<#if buttonList?? && buttonList?size gt 0>
<#list buttonList as btn>
<#if btn.buttonStyle=='form'>
<a-button type="primary" @click="handle${btn.buttonCode?cap_first}" <#if btn.buttonIcon??> preIcon="ant-design:${btn.buttonIcon}" </#if>>${btn.buttonName}</a-button>
</#if>
</#list>
</#if>
<a-button @click="handleCancel">取消</a-button>
<a-button :class="{ 'jee-hidden': disableSubmit }" type="primary" @click="handleOk">确认</a-button>
</template>
</j-modal>
</template>
<script lang="ts" setup>
import { ref, nextTick, defineExpose } from 'vue';
import ${entityName}Form from './${entityName}Form.vue'
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
import { useMessage } from '/@/hooks/web/useMessage';
const { createMessage } = useMessage();
const title = ref<string>('');
const width = ref<number>(800);
const visible = ref<boolean>(false);
@ -61,6 +78,16 @@
visible.value = false;
}
<#if buttonList?size gt 0>
<#list buttonList?sort_by('orderNum') as btn>
<#if btn.buttonStyle=='form'>
function handle${btn.buttonCode?cap_first}(){
createMessage.info('点击了${btn.buttonName}按钮,对应的业务逻辑需自行实现!');
}
</#if>
</#list>
</#if>
defineExpose({
add,
edit,

View File

@ -58,7 +58,7 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
<#include "/common/form/native/vue3NativeImport.ftl">
import { getValueType } from '/@/utils';
import { getDateByPicker, getValueType } from '/@/utils';
import { ${sub.entityName?uncap_first}SaveOrUpdate } from '../${entityName}.api';
import { Form } from 'ant-design-vue';
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
@ -88,6 +88,14 @@
</#list>
};
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: false });
//日期个性化选择
const fieldPickers = reactive({
<#list sub.colums as po>
<#if po.extendParams?exists && po.extendParams.picker?exists>
${po.fieldName}: '${po.extendParams.picker}',
</#if>
</#list>
});
const props = defineProps({
disabled: { type: Boolean, default: false },
});
@ -147,6 +155,8 @@
//循环数据
for (let data in model) {
// 更新个性化日期选择器的值
model[data] = getDateByPicker(model[data], fieldPickers[data]);
//如果该数据是数组并且是字符串类型
if (model[data] instanceof Array) {
let valueType = getValueType(formRef.value.getProps, data);

View File

@ -54,6 +54,10 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
<#assign has_multi_query_field=true>
</#if>
</#list>
<#assign enhanceJavaList=[]>
<#if tableVo.extendParams?? && tableVo.extendParams.enhanceJavaList??>
<#assign enhanceJavaList = tableVo.extendParams.enhanceJavaList?filter(enhance -> enhance??)>
</#if>
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
@ -88,6 +92,14 @@ public class ${entityName}Controller {
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='query' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 查询前触发的方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeQuery()
</#if>
</#list>
</#if>
<#if has_multi_query_field>
// 自定义查询规则
Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
@ -103,6 +115,14 @@ public class ${entityName}Controller {
</#if>
Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize);
IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper);
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='query' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
//TODO 查询后触发的方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.afterQuery()
</#if>
</#list>
</#if>
return Result.OK(pageList);
}
@ -117,9 +137,25 @@ public class ${entityName}Controller {
@RequiresPermissions("${entityPackage}:${tableName}:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='add' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 新增前的处理方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeAdd()
</#if>
</#list>
</#if>
${entityName} ${entityName?uncap_first} = new ${entityName}();
BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first});
${entityName?uncap_first}Service.saveMain(${entityName?uncap_first}, <#list subTables as sub>${entityName?uncap_first}Page.get${sub.entityName}List()<#if sub_has_next>,</#if></#list>);
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='add' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
//TODO 新增后的处理方法,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.afterAdd()
</#if>
</#list>
</#if>
return Result.OK("添加成功!");
}
@ -134,6 +170,14 @@ public class ${entityName}Controller {
@RequiresPermissions("${entityPackage}:${tableName}:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 编辑前,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeEdit()
</#if>
</#list>
</#if>
${entityName} ${entityName?uncap_first} = new ${entityName}();
BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first});
${entityName} ${entityName?uncap_first}Entity = ${entityName?uncap_first}Service.getById(${entityName?uncap_first}.getId());
@ -141,6 +185,14 @@ public class ${entityName}Controller {
return Result.error("未找到对应数据");
}
${entityName?uncap_first}Service.updateMain(${entityName?uncap_first}, <#list subTables as sub>${entityName?uncap_first}Page.get${sub.entityName}List()<#if sub_has_next>,</#if></#list>);
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'>
//TODO 编辑后,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.afterEdit()
</#if>
</#list>
</#if>
return Result.OK("编辑成功!");
}
@ -221,6 +273,14 @@ public class ${entityName}Controller {
@RequiresPermissions("${entityPackage}:${tableName}:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='export' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 导出前,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeExport()
</#if>
</#list>
</#if>
// Step.1 组装查询条件查询数据
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap());
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
@ -265,6 +325,14 @@ public class ${entityName}Controller {
@RequiresPermissions("${entityPackage}:${tableName}:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
<#if enhanceJavaList?size gt 0>
<#list enhanceJavaList as enhanceJava>
<#if enhanceJava.buttonCode=='import' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'>
//TODO 导入前,代码生成后,请手工实现增强类逻辑;
//${entityName?uncap_first}Service.beforeImport()
</#if>
</#list>
</#if>
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {

View File

@ -47,6 +47,8 @@ public class ${entityName} implements Serializable {
</#if>
<#elseif po.classType=='sel_tree'>
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'>
<#elseif po.classType=='link_table'>
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'>
</#if>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>

View File

@ -49,6 +49,8 @@ public class ${subTab.entityName} implements Serializable {
<#elseif po.classType=='sel_tree'>
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'>
</#if>
<#elseif po.classType=='link_table'>
<#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'>
</#if>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>

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