Compare commits

..

10 Commits

12 changed files with 64 additions and 18 deletions

View File

@ -9,6 +9,8 @@ assignees: getActivity
##### 版本号: ##### 版本号:
##### 分支:
##### 问题描述: ##### 问题描述:

View File

@ -6,9 +6,10 @@ assignees: getActivity
--- ---
##### 版本号: ##### 版本号:
##### 分支:
##### 问题描述: ##### 问题描述:

View File

@ -4,6 +4,7 @@ JeecgBoot AI低代码平台
当前最新版本: 3.8.3发布日期2025-10-09 当前最新版本: 3.8.3发布日期2025-10-09
> 重要提醒: v3.8.3 是 SpringBoot2 的最终版本,后续将不再维护。建议大家尽快升级至基于 SpringBoot3版本以获得更好的性能和支持。
[![AUR](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/jeecgboot/JeecgBoot/blob/master/LICENSE) [![AUR](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/jeecgboot/JeecgBoot/blob/master/LICENSE)
[![](https://img.shields.io/badge/Author-北京国炬软件-orange.svg)](https://jeecg.com) [![](https://img.shields.io/badge/Author-北京国炬软件-orange.svg)](https://jeecg.com)
@ -81,6 +82,7 @@ JeecgBoot低代码平台可以应用在任何J2EE项目的开发中支持
- 官方网站: [http://www.jeecg.com](http://www.jeecg.com) - 官方网站: [http://www.jeecg.com](http://www.jeecg.com)
- 在线演示: [平台演示](https://boot3.jeecg.com) | [APP演示](https://jeecg.com/appIndex) - 在线演示: [平台演示](https://boot3.jeecg.com) | [APP演示](https://jeecg.com/appIndex)
- 入门指南: [快速入门](http://www.jeecg.com/doc/quickstart) | [代码生成使用](https://help.jeecg.com/java/codegen/online) | [开发文档](https://help.jeecg.com) | [AI应用手册](https://help.jeecg.com/aigc) | [视频教程](http://jeecg.com/doc/video) - 入门指南: [快速入门](http://www.jeecg.com/doc/quickstart) | [代码生成使用](https://help.jeecg.com/java/codegen/online) | [开发文档](https://help.jeecg.com) | [AI应用手册](https://help.jeecg.com/aigc) | [视频教程](http://jeecg.com/doc/video)
- AI编程 [JEECG低代码+AI编程Cursor+GitHub Copilot实现高效编程](https://www.bilibili.com/video/BV11XyaBVEoH)
- 技术支持: [反馈问题](https://github.com/jeecgboot/JeecgBoot/issues/new?template=bug_report.md) | [低代码体验一分钟](https://jeecg.blog.csdn.net/article/details/106079007) - 技术支持: [反馈问题](https://github.com/jeecgboot/JeecgBoot/issues/new?template=bug_report.md) | [低代码体验一分钟](https://jeecg.blog.csdn.net/article/details/106079007)
- QQ交流群 964611995、⑩716488839(满)、⑨808791225(满)、其他(满) - QQ交流群 964611995、⑩716488839(满)、⑨808791225(满)、其他(满)
@ -155,6 +157,9 @@ JeecgBoot平台提供了一套完善的AI应用管理系统模块是一套类
#### 前端 #### 前端
- 前端环境要求Node.js要求`Node 20+` 版本以上、pnpm 要求`9+` 版本以上 - 前端环境要求Node.js要求`Node 20+` 版本以上、pnpm 要求`9+` 版本以上
> Vite 不再支持已结束生命周期EOL的 Node.js 18。现在需要使用 Node.js 20.19+ 或 22.12+。
- 依赖管理node、npm、pnpm - 依赖管理node、npm、pnpm
- 前端IDE建议IDEA、WebStorm、Vscode - 前端IDE建议IDEA、WebStorm、Vscode
- 采用 Vue3.0+TypeScript+Vite6+Ant-Design-Vue4等新技术方案包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能 - 采用 Vue3.0+TypeScript+Vite6+Ant-Design-Vue4等新技术方案包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能
@ -508,4 +513,4 @@ AI写文章
如果觉得还不错,请作者喝杯咖啡吧 ☺ 如果觉得还不错,请作者喝杯咖啡吧 ☺
![](https://static.oschina.net/uploads/img/201903/08155608_0EFX.png) ![](https://static.oschina.net/uploads/img/201903/08155608_0EFX.png)

View File

@ -143,7 +143,7 @@ public class AutoLogAspect {
// https://my.oschina.net/mengzhang6/blog/2395893 // https://my.oschina.net/mengzhang6/blog/2395893
Object[] arguments = new Object[paramsArray.length]; Object[] arguments = new Object[paramsArray.length];
for (int i = 0; i < paramsArray.length; i++) { for (int i = 0; i < paramsArray.length; i++) {
if (paramsArray[i] instanceof BindingResult || paramsArray[i] instanceof ServletRequest || paramsArray[i] instanceof ServletResponse || paramsArray[i] instanceof MultipartFile) { if (paramsArray[i] instanceof BindingResult || paramsArray[i] instanceof ServletRequest || paramsArray[i] instanceof ServletResponse || paramsArray[i] instanceof MultipartFile || paramsArray[i] instanceof MultipartFile[]) {
//ServletRequest不能序列化从入参里排除否则报异常java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false) //ServletRequest不能序列化从入参里排除否则报异常java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
//ServletResponse不能序列化 从入参里排除否则报异常java.lang.IllegalStateException: getOutputStream() has already been called for this response //ServletResponse不能序列化 从入参里排除否则报异常java.lang.IllegalStateException: getOutputStream() has already been called for this response
continue; continue;

View File

@ -1686,6 +1686,42 @@ public class SysUserController {
return Result.ok(); return Result.ok();
} }
/**
* 添加用户【后台租户模式专用,敲敲云不要用这个】
*
* @param jsonObject
* @return
*/
@RequiresPermissions("system:user:addTenantUser")
@RequestMapping(value = "/addTenantUser", method = RequestMethod.POST)
public Result<SysUser> addTenantUser(@RequestBody JSONObject jsonObject) {
Result<SysUser> result = new Result<SysUser>();
String selectedRoles = jsonObject.getString("selectedroles");
String selectedDeparts = jsonObject.getString("selecteddeparts");
try {
SysUser user = JSON.parseObject(jsonObject.toJSONString(), SysUser.class);
user.setCreateTime(new Date());//设置创建时间
String salt = oConvertUtils.randomGen(8);
user.setSalt(salt);
String passwordEncode = PasswordUtil.encrypt(user.getUsername(), user.getPassword(), salt);
user.setPassword(passwordEncode);
user.setStatus(1);
user.setDelFlag(CommonConstant.DEL_FLAG_0);
//用户表字段org_code不能在这里设置他的值
user.setOrgCode(null);
// 保存用户走一个service 保证事务
//获取租户ids
String relTenantIds = jsonObject.getString("relTenantIds");
sysUserService.saveUser(user, selectedRoles, selectedDeparts, relTenantIds, true);
baseCommonService.addLog("添加用户username " + user.getUsername(), CommonConstant.LOG_TYPE_2, 2);
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
/** /**
* 修改租户下的用户【低代码应用专用接口】 * 修改租户下的用户【低代码应用专用接口】
* @param sysUser * @param sysUser

View File

@ -2055,7 +2055,10 @@ public class SysBaseApiImpl implements ISysBaseAPI {
if(oConvertUtils.isEmpty(code)) { if(oConvertUtils.isEmpty(code)) {
return null; return null;
} }
List<SysDepart> list = sysDepartList.stream().filter(sysDepart -> sysDepart.getOrgCode().equals(code)).toList(); List<SysDepart> list = sysDepartList.stream()
.filter(sysDepart -> sysDepart.getOrgCode().equals(code))
.collect(Collectors.toList());
//判断去上级的级别 //判断去上级的级别
if(!CollectionUtils.isEmpty(list) && nowLevel == level) { if(!CollectionUtils.isEmpty(list) && nowLevel == level) {
return list.get(0); return list.get(0);

View File

@ -785,7 +785,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
List<String> departIdList = new ArrayList<>(); List<String> departIdList = new ArrayList<>();
//如果前端传过来的部门id不为空的时候说明是系统用户根据所属部门选择主岗位或者兼职岗位 //如果前端传过来的部门id不为空的时候说明是系统用户根据所属部门选择主岗位或者兼职岗位
if(oConvertUtils.isNotEmpty(departIds) && oConvertUtils.isEmpty(parentId)){ if(oConvertUtils.isNotEmpty(departIds) && oConvertUtils.isEmpty(parentId)){
departIdList = list.stream().map(SysDepart::getId).toList(); departIdList = list.stream().map(SysDepart::getId).collect(Collectors.toList());
} }
List<SysDepartTreeModel> records = new ArrayList<>(); List<SysDepartTreeModel> records = new ArrayList<>();
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
@ -1859,7 +1859,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
List<SysDepart> sysDepartList = departMapper.selectList(query); List<SysDepart> sysDepartList = departMapper.selectList(query);
if(!CollectionUtils.isEmpty(sysDepartList)){ if(!CollectionUtils.isEmpty(sysDepartList)){
//获取部门名称拼接返回给前台 //获取部门名称拼接返回给前台
List<String> departNameList = sysDepartList.stream().map(SysDepart::getDepartName).toList(); List<String> departNameList = sysDepartList.stream().map(SysDepart::getDepartName).collect(Collectors.toList());
String departNames = String.join("/", departNameList); String departNames = String.join("/", departNameList);
redisUtil.set(CommonConstant.DEPART_NAME_REDIS_KEY_PRE + orgCode,departNames); redisUtil.set(CommonConstant.DEPART_NAME_REDIS_KEY_PRE + orgCode,departNames);
return departNames; return departNames;

View File

@ -100,11 +100,11 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
// 提取已存在的用户ID // 提取已存在的用户ID
List<String> existingUserIds = existingUsers.stream() List<String> existingUserIds = existingUsers.stream()
.map(SysTenantPackUser::getUserId) .map(SysTenantPackUser::getUserId)
.toList(); .collect(Collectors.toList());
// 过滤出需要新增的用户ID // 过滤出需要新增的用户ID
List<String> newUserIds = userIds.stream() List<String> newUserIds = userIds.stream()
.filter(userId -> !existingUserIds.contains(userId)) .filter(userId -> !existingUserIds.contains(userId))
.toList(); .collect(Collectors.toList());
for (String userId : newUserIds) { for (String userId : newUserIds) {
//update-end---author:wangshuai---date:2025-09-03---for: 编辑时需要查看有没有未分配的用户--- //update-end---author:wangshuai---date:2025-09-03---for: 编辑时需要查看有没有未分配的用户---
SysTenantPackUser tenantPackUser = new SysTenantPackUser(tenantId, packId, userId); SysTenantPackUser tenantPackUser = new SysTenantPackUser(tenantId, packId, userId);

View File

@ -2734,7 +2734,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
public IPage<SysUserSysDepPostModel> queryDepartPostUserByOrgCode(String orgCode, SysUser userParams, IPage page) { public IPage<SysUserSysDepPostModel> queryDepartPostUserByOrgCode(String orgCode, SysUser userParams, IPage page) {
List<SysUserSysDepPostModel> sysDepartModels = baseMapper.queryDepartPostUserByOrgCode(page, orgCode, userParams); List<SysUserSysDepPostModel> sysDepartModels = baseMapper.queryDepartPostUserByOrgCode(page, orgCode, userParams);
if(CollectionUtil.isNotEmpty(sysDepartModels)){ if(CollectionUtil.isNotEmpty(sysDepartModels)){
List<String> userIds = sysDepartModels.stream().map(SysUserSysDepPostModel::getId).toList(); List<String> userIds = sysDepartModels.stream().map(SysUserSysDepPostModel::getId).collect(Collectors.toList());
//获取部门名称 //获取部门名称
Map<String, String> useDepNames = this.getDepNamesByUserIds(userIds); Map<String, String> useDepNames = this.getDepNamesByUserIds(userIds);
sysDepartModels.forEach(item -> { sysDepartModels.forEach(item -> {

View File

@ -62,14 +62,13 @@
<!-- 积木报表--> <!-- 积木报表-->
<jimureport-spring-boot-starter.version>2.1.3</jimureport-spring-boot-starter.version> <jimureport-spring-boot-starter.version>2.1.3</jimureport-spring-boot-starter.version>
<jimubi-spring-boot-starter.version>2.1.4</jimubi-spring-boot-starter.version> <jimubi-spring-boot-starter.version>2.1.4</jimubi-spring-boot-starter.version>
<minidao.version>1.10.14</minidao.version> <minidao.version>1.10.16</minidao.version>
<autopoi-web.version>1.4.18</autopoi-web.version> <autopoi-web.version>1.4.18</autopoi-web.version>
<!-- 持久层 --> <!-- 持久层 -->
<mybatis-plus.version>3.5.12</mybatis-plus.version> <mybatis-plus.version>3.5.12</mybatis-plus.version>
<dynamic-datasource-spring-boot-starter.version>4.1.3</dynamic-datasource-spring-boot-starter.version> <dynamic-datasource-spring-boot-starter.version>4.1.3</dynamic-datasource-spring-boot-starter.version>
<druid.version>1.2.24</druid.version> <druid.version>1.2.24</druid.version>
<minidao.version>1.10.14</minidao.version>
<commons-io.version>2.11.0</commons-io.version> <commons-io.version>2.11.0</commons-io.version>
<commons-fileupload.version>1.5</commons-fileupload.version> <commons-fileupload.version>1.5</commons-fileupload.version>
@ -269,7 +268,7 @@
<dependency> <dependency>
<groupId>org.jeecgframework.boot</groupId> <groupId>org.jeecgframework.boot</groupId>
<artifactId>hibernate-re</artifactId> <artifactId>hibernate-re</artifactId>
<version>3.8.2-beta</version> <version>3.8.2.2</version>
</dependency> </dependency>
<!--mongon db--> <!--mongon db-->
@ -494,7 +493,7 @@
<dependency> <dependency>
<groupId>org.jeecgframework.boot</groupId> <groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-starter-chatgpt</artifactId> <artifactId>jeecg-boot-starter-chatgpt</artifactId>
<version>${jeecgboot.version}</version> <version>3.8.3.1</version>
</dependency> </dependency>
<!--flyway 支持 mysql5.7+、MariaDB10.3.16--> <!--flyway 支持 mysql5.7+、MariaDB10.3.16-->
<!--mysql5.6需要把版本号改成5.2.1--> <!--mysql5.6需要把版本号改成5.2.1-->

View File

@ -35,9 +35,9 @@ JeecgBoot-Vue3采用 Vue3.0、Vite、 Ant-Design-Vue4、TypeScript 等新技术
## 安装与使用 ## 安装与使用
* 本地环境安装 `Node.js 、npm 、pnpm` * 本地环境安装 `Node.js 、npm 、pnpm`
* Node.js 版本建议`v20.15.0`要求`Node 20+` 版本以上 * Node.js 版本要求`Node 20+` 版本以上
` ( 因为Vite5 不再支持已 EOL 的 Node.js 14 / 16 / 17 / 19现在需要 Node.js 18 / 20+ )` ` ( Vite 不再支持已结束生命周期(EOL的 Node.js 18。现在需要使用 Node.js 20.19+ 或 22.12+)`

View File

@ -107,7 +107,7 @@
"@types/sortablejs": "^1.15.8", "@types/sortablejs": "^1.15.8",
"@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0", "@typescript-eslint/parser": "^6.21.0",
"@vitejs/plugin-vue": "^5.2.1", "@vitejs/plugin-vue": "5.2.1",
"@vitejs/plugin-vue-jsx": "4.1.1", "@vitejs/plugin-vue-jsx": "4.1.1",
"@vue/compiler-sfc": "^3.5.13", "@vue/compiler-sfc": "^3.5.13",
"@vue/test-utils": "^2.4.6", "@vue/test-utils": "^2.4.6",
@ -141,8 +141,8 @@
"prettier": "^3.4.2", "prettier": "^3.4.2",
"pretty-quick": "^4.0.0", "pretty-quick": "^4.0.0",
"rimraf": "^5.0.10", "rimraf": "^5.0.10",
"rollup": "^4.30.0", "rollup": "4.52.5",
"rollup-plugin-visualizer": "^5.13.1", "rollup-plugin-visualizer": "5.14.0",
"stylelint": "^16.12.0", "stylelint": "^16.12.0",
"stylelint-config-prettier": "^9.0.5", "stylelint-config-prettier": "^9.0.5",
"stylelint-config-recommended": "^14.0.1", "stylelint-config-recommended": "^14.0.1",