2 天以前 dc3336685e80c593a3654a6e53e3e1d1d13b2b50
fix(approve): 修复流程配置节点审批人为空时的异常处理

- 修正了当审批人列表为空时抛出运行时异常的逻辑
- 确保在节点ID集合为空的情况下流程能够正确处理
- 优化了代码缩进和格式以提高可读性
已添加2个文件
已修改4个文件
113 ■■■■■ 文件已修改
doc/20260506_add_ai_enabled_to_sys_user.sql 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260506_用户AI功能字段前端联调说明.md 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/framework/security/LoginUser.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/controller/SysLoginController.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/domain/SysUser.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/system/SysUserMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260506_add_ai_enabled_to_sys_user.sql
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,2 @@
alter table sys_user
    add ai_enabled tinyint(1) not null default 0 comment '是否开通AI功能(0否 1是)';
doc/20260506_Óû§AI¹¦ÄÜ×Ö¶Îǰ¶ËÁªµ÷˵Ã÷.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
# ç”¨æˆ· AI åŠŸèƒ½å­—æ®µå‰ç«¯è”è°ƒè¯´æ˜Ž
## èƒŒæ™¯
后端已在用户表增加隐藏字段 `ai_enabled`,用于标识用户是否开通 AI åŠŸèƒ½ã€‚
该字段不开放给用户资料维护接口(不通过用户编辑页面下发/回写)。
## å­—段定义
| å­—段 | ç±»åž‹ | é»˜è®¤å€¼ | è¯´æ˜Ž |
| --- | --- | --- | --- |
| ai_enabled | tinyint(1) | 0 | æ˜¯å¦å¼€é€š AI åŠŸèƒ½ï¼š`0`=未开通,`1`=已开通 |
## è”调接口
登录后调用:
```http
GET /getInfo
```
返回中新增顶层字段 `aiEnabled`:
```json
{
  "code": 200,
  "msg": "操作成功",
  "user": {
    "userId": 1,
    "userName": "admin"
  },
  "aiEnabled": 1,
  "roles": [
    "admin"
  ],
  "permissions": [
    "*:*:*"
  ]
}
```
## å‰ç«¯ä½¿ç”¨å»ºè®®
1. ç™»å½•成功后按现有流程调用 `/getInfo`。
2. ä»Žå“åº”顶层读取 `aiEnabled`。
3. åˆ¤å®šé€»è¾‘建议:
   - `aiEnabled === 1`:展示/放开 AI ç›¸å…³å…¥å£ã€‚
   - å…¶ä»–值(`0`、`null`、`undefined`):按未开通处理。
## ç¼“存说明
- `aiEnabled` å·²æ”¾å…¥ç™»å½•缓存对象(`LoginUser`)并随 token ç”Ÿå‘½å‘¨æœŸç®¡ç†ã€‚
- ç¼“å­˜ key å‰ç¼€ï¼š`login_tokens:`。
src/main/java/com/ruoyi/framework/security/LoginUser.java
@@ -81,6 +81,11 @@
     */
    private Long currentDeptId;
    /**
     * æ˜¯å¦å¼€é€šAI功能(0否 1是)
     */
    private Integer aiEnabled;
    private String dataScope;
    public LoginUser()
@@ -91,6 +96,7 @@
    {
        this.user = user;
        this.permissions = permissions;
        this.aiEnabled = user == null ? null : user.getAiEnabled();
    }
    public LoginUser(Long userId, Long [] deptId, SysUser user, Set<String> permissions)
@@ -99,6 +105,7 @@
        this.deptIds = deptId;
        this.user = user;
        this.permissions = permissions;
        this.aiEnabled = user == null ? null : user.getAiEnabled();
    }
    public LoginUser(Long userId, Long [] deptIds, SysUser user,Long tenantId, Set<String> permissions)
@@ -108,6 +115,7 @@
        this.user = user;
        this.permissions = permissions;
        this.tenantId = tenantId;
        this.aiEnabled = user == null ? null : user.getAiEnabled();
    }
    public LoginUser(Long userId, Long [] deptIds, SysUser user,Long tenantId,Long currentDeptId, Set<String> permissions)
@@ -118,6 +126,7 @@
        this.permissions = permissions;
        this.tenantId = tenantId;
        this.currentDeptId = currentDeptId;
        this.aiEnabled = user == null ? null : user.getAiEnabled();
    }
    public Long getUserId()
@@ -292,6 +301,7 @@
    public void setUser(SysUser user)
    {
        this.user = user;
        this.aiEnabled = user == null ? null : user.getAiEnabled();
    }
    @Override
@@ -320,6 +330,20 @@
        this.currentDeptId = currentDeptId;
    }
    public Integer getAiEnabled() {
        if (aiEnabled != null) {
            return aiEnabled;
        }
        if (user != null && user.getAiEnabled() != null) {
            return user.getAiEnabled();
        }
        return 0;
    }
    public void setAiEnabled(Integer aiEnabled) {
        this.aiEnabled = aiEnabled;
    }
    public String getDataScope() {
        return dataScope;
    }
src/main/java/com/ruoyi/project/system/controller/SysLoginController.java
@@ -15,6 +15,7 @@
import com.ruoyi.project.system.mapper.SysDeptMapper;
import com.ruoyi.project.system.service.ISysMenuService;
import com.ruoyi.project.system.service.ISysUserDeptService;
import com.ruoyi.project.system.service.ISysUserService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
@@ -43,6 +44,7 @@
    private SysPermissionService permissionService;
    private TokenService tokenService;
    private ISysUserDeptService userDeptService;
    private ISysUserService userService;
    private SysDeptMapper sysDeptMapper;
    /**
@@ -71,7 +73,17 @@
    public AjaxResult getInfo()
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        SysUser user = userService.selectUserById(loginUser.getUserId());
        if (user == null)
        {
            user = loginUser.getUser();
        }
        else
        {
            loginUser.setUser(user);
            loginUser.setAiEnabled(user.getAiEnabled());
            tokenService.setLoginUser(loginUser);
        }
        // èŽ·å–å½“å‰ç™»å½•å…¬å¸
        Long tenantId = loginUser.getTenantId();
        if(null != tenantId){
@@ -92,6 +104,7 @@
        }
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("aiEnabled", loginUser.getAiEnabled());
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
src/main/java/com/ruoyi/project/system/domain/SysUser.java
@@ -1,6 +1,7 @@
package com.ruoyi.project.system.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ruoyi.common.xss.Xss;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
@@ -61,6 +62,10 @@
    /** åˆ é™¤æ ‡å¿—(0代表存在 2代表删除) */
    private String delFlag;
    /** æ˜¯å¦å¼€é€šAI功能(0否 1是) */
    @JsonIgnore
    private Integer aiEnabled;
    /** æœ€åŽç™»å½•IP */
    @Excel(name = "最后登录IP", type = Type.EXPORT)
@@ -260,6 +265,16 @@
        this.delFlag = delFlag;
    }
    public Integer getAiEnabled()
    {
        return aiEnabled;
    }
    public void setAiEnabled(Integer aiEnabled)
    {
        this.aiEnabled = aiEnabled;
    }
    public String getLoginIp()
    {
        return loginIp;
@@ -375,6 +390,7 @@
            .append("password", getPassword())
            .append("status", getStatus())
            .append("delFlag", getDelFlag())
            .append("aiEnabled", getAiEnabled())
            .append("loginIp", getLoginIp())
            .append("loginDate", getLoginDate())
            .append("createBy", getCreateBy())
src/main/resources/mapper/system/SysUserMapper.xml
@@ -15,6 +15,7 @@
        <result property="password"     column="password"     />
        <result property="status"       column="status"       />
        <result property="delFlag"      column="del_flag"     />
        <result property="aiEnabled"    column="ai_enabled"   />
        <result property="loginIp"      column="login_ip"     />
        <result property="loginDate"    column="login_date"   />
        <result property="createBy"     column="create_by"    />
@@ -48,7 +49,7 @@
    </resultMap>
    <sql id="selectUserVo">
        select u.user_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
        select u.user_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.ai_enabled, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
        r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status,u.tenant_id
        from sys_user u
            left join sys_user_role ur on u.user_id = ur.user_id