SpringCloud+Vue+Python人工智能(fastAPI,机器学习,深度学习)前后端架构各功能实现思路——SpringCloud后端——权限管理rbac接口实现

SpringCloud整合php、python示例 SpringCloud整合php、python示例代码已上传至: https://github.com/KeoZmy/SpringCloudDemo.git ,博客中没有写到网关 zuul,但是git中已上传前言最近一直在花时间研究微服务,各种开源组件组合一个framework到最后决定用springcloud这样成熟的framework。不得不说,springcloud确实很强大,还有Pivota 阅读详情
SpringCloud+Vue+Python人工智能(fastAPI,机器学习,深度学习)前后端架构各功能实现思路——主目录(持续更新):https://blog.youkuaiyun.com/grd_java/article/details/144986730
SpringCloud+Vue+Python人工智能(fastAPI,机器学习,深度学习)前后端架构各功能实现思路——SpringCloud后端——Sa-Token实现Security权限管理https://blog.youkuaiyun.com/grd_java/article/details/145013189

1. user相关接口

在这里插入图片描述

1.0 实体类

user实体类比较特殊,除了自动填充主键外,还有数据库表中不存在的字段,保存用户角色信息
在这里插入图片描述

package com.yd_oa_java_cloud.security.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.List;

import lombok.Getter;
import lombok.Setter;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
@Getter
@Setter
@TableName("sys_user")
public class SysUser implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 用户id
     */
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private String id;

    /**
     * 用户名
     */
    @TableField("username")
    private String username;

    /**
     * 密码
     */
    @TableField("password")
    private String password;
    /**
     * 非数据库表中字段,封装角色信息
     */
    @TableField(exist = false)
    private List<SysRole> roles;
}

1.1 mapper

在这里插入图片描述

package com.yd_oa_java_cloud.security.mapper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import java.util.List;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
public interface SysUserMapper extends BaseMapper<SysUser> {
    /**分页查询所有用户**/
    List<SysUser> getAllUserPage(Page<SysUser> sysUserPage);

    List<SysUser> getByUsername(String username);
    //精确匹配
    SysUser getByUsernameOne(String username);

    void insertRecord(String uid, String[] rids);
}

mapper.xml


在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yd_oa_java_cloud.security.mapper.SysUserMapper">
    <!--分页查询所有用户-->
    <select id="getAllUserPage" resultType="com.yd_oa_java_cloud.security.entity.SysUser">
        select id,username,password from sys_user
    </select>
    <!--分页条件查询用户-->
    <select id="getAllUserPageByCondition" resultType="com.yd_oa_java_cloud.security.entity.SysUser" parameterType="com.yd_oa_java_cloud.security.entity.SysUser">
        select
            u.id as id,
            u.username as username,
            u.`password` as `password`,
            r.id as rid,
            r.`name` as rname,
            r.name_zh as rnameZh
        from
            sys_user as u
        left join
            sys_user_role as ur
        on
            u.id = ur.uid
        left join
            sys_role as r
        on
            ur.rid = r.id
        <where>
            <trim>
                <if test="sysUser.id != null  and sysUser.id != '' and sysUser.id!=0">and u.id = #{sysUser.id}</if>
                <if test="sysUser.username != null  and sysUser.username != ''">and u.username like concat('%', #{sysUser.username}, '%')</if>
                <if test="sysUser.roles != null">and r.name_zh like concat('%', #{sysUser.roles[0].nameZh}, '%')</if>
            </trim>
        </where>
    </select>
    <select id="getByUsername" resultType="com.yd_oa_java_cloud.security.entity.SysUser">
        select
            u1.id as id,
            u1.username as username,
            u1.password as password
        from
            sys_user as u1
        <where>
            <trim>
                <if test="username != null and username != ''">and u1.username like concat('%',#{username},'%')</if>
            </trim>
        </where>
    </select>
    <select id="getByUsernameOne" resultType="com.yd_oa_java_cloud.security.entity.SysUser">
        select
        u1.id as id,
        u1.username as username,
        u1.password as password
        from
        sys_user as u1
        <where>
            <trim>
                <if test="username != null and username != ''">and u1.username = #{username}</if>
            </trim>
        </where>
    </select>
</mapper>

1.2 service

service


在这里插入图片描述

package com.yd_oa_java_cloud.security.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd_oa_java_cloud.base.entity.vo.YdOaResult;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.baomidou.mybatisplus.extension.service.IService;

import java.util.List;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author Taylor Sinclair(殷志鹏)
 * @since 2025-01-10
 */
public interface ISysUserService extends IService<SysUser> {

    List<SysUser> getAllUserPage(Page<SysUser> sysUserPage);

    List<SysUser> getByUsername(String username);//模糊匹配
    SysUser getByUsernameOne(String username);//精确匹配

    boolean deleteById(String id);

    YdOaResult updateUserRole(String uid, String[] rids);
}

impl


在这里插入图片描述

package com.yd_oa_java_cloud.security.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd_oa_java_cloud.base.entity.vo.YdOaResult;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.yd_oa_java_cloud.security.entity.SysUserRole;
import com.yd_oa_java_cloud.security.mapper.SysUserMapper;
import com.yd_oa_java_cloud.security.mapper.SysUserRoleMapper;
import com.yd_oa_java_cloud.security.service.ISysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Taylor Sinclair(殷志鹏)
 * @since 2025-01-10
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Override
    public List<SysUser> getAllUserPage(Page<SysUser> sysUserPage) {
        return sysUserMapper.getAllUserPage(sysUserPage);
    }

    @Override
    public List<SysUser> getByUsername(String username) {
        return sysUserMapper.getByUsername(username);
    }
    //精确匹配
    @Override
    public SysUser getByUsernameOne(String username) {
        return sysUserMapper.getByUsernameOne(username);
    }

    @Override
    @Transactional
    public boolean deleteById(String id) {
        return sysUserRoleMapper.deleteUserAndRoleById(id)>=1;
    }

    /**
     * 更新用户拥有的角色
     * @param uid 用户id
     * @param rids 用户要修改的角色id
     */
    @Override
    @Transactional//自己写更新的操作,一定要加事务
    public YdOaResult updateUserRole(String uid, String[] rids) {
        //要更新的菜单id为空,则直接返回
        if(null == rids||rids.length == 0){
            return YdOaResult.ok("更新用户角色成功");
        }
        //先全删了,否则得一次次判断,太费资源
        sysUserRoleMapper.delete(new QueryWrapper<SysUserRole>().eq("uid", uid));
        //如果传了菜单id过来,则更新
        sysUserMapper.insertRecord(uid,rids);
        return YdOaResult.ok("更新菜单成功");
    }
}

1.3 controller


在这里插入图片描述

package com.yd_oa_java_cloud.security.controller;

import cn.dev33.satoken.secure.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd_oa_java_cloud.base.entity.enums.ResponseCodeEnum;
import com.yd_oa_java_cloud.base.entity.vo.YdOaResult;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.yd_oa_java_cloud.security.entity.SysUserRole;
import com.yd_oa_java_cloud.security.service.ISysUserRoleService;
import com.yd_oa_java_cloud.security.service.ISysUserService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
@RestController
@RequestMapping("/sysUser")
@Log4j2
public class SysUserController {

    @Autowired
    private ISysUserService iSysUserService;

    /**分页获取用户**/
    @GetMapping("/page/{current}/{size}")
    public YdOaResult getAllUserPage(@PathVariable Integer current,@PathVariable Integer size){
        Page<SysUser> sysUserPage = new Page<>(current, size);//构建分页对象

        try {
            List<SysUser> sysUserList = iSysUserService.getAllUserPage(sysUserPage);//传入分页对象,分页查询
            return YdOaResult.ok()
                    .set("current",sysUserPage.getCurrent())//当前所在页
                    .set("pages",sysUserPage.getPages())//共可以分几页
                    .set("Size",sysUserPage.getSize())//每页记录数
                    .set("Total",sysUserPage.getTotal())//数据库表共有多少条数据
                    .set("hasNext",sysUserPage.hasNext())//是否有下一页
                    .set("hasPrevious",sysUserPage.hasPrevious())//是否有前一页
                    .setData(sysUserList)//放入查询结果
                    ;
        } catch (Exception e) {
            log.error("分页获取用户出错!!————",e);
            return YdOaResult.error().setMsg("查询出错!");
        }
    }
    /**根据用户名获取用户,模糊匹配**/
    @GetMapping("/getByUsername")
    public YdOaResult getByUsername(@RequestBody SysUser sysUser){
        if (!isUserHaveUsername(sysUser)){
            return YdOaResult.error().setMsg("请输入用户名");
        }
        try {
            List<SysUser> sysUserList = iSysUserService.getByUsername(sysUser.getUsername());
            if (sysUserList.isEmpty()) return YdOaResult.ok().setMsg("无相关结果").setData(null);//放入查询结果;
            return YdOaResult.ok().setData(sysUserList);//放入查询结果
        } catch (Exception e) {
            log.error("据用户名获取用户出错!!————",e);
            return YdOaResult.error().setCode(ResponseCodeEnum.CODE_503.getCode()).setMsg("查询出错!");
        }
    }
    /**添加用户**/
    @PostMapping("/add")
    public YdOaResult addUser (@RequestBody SysUser sysUser){
        if (!isUserHaveUsername(sysUser)){
            return YdOaResult.error().setMsg("请输入用户名!");
        }else if(!isUsernameValid(sysUser.getUsername())){
            return YdOaResult.error().setMsg("用户名长度应介于8-25之间");
        }
        try {
            List<SysUser> sysUserList = iSysUserService.getByUsername(sysUser.getUsername());
            if (!sysUserList.isEmpty()) return YdOaResult.error().setMsg("用户名已存在!");

            if (!isUserHavePassword(sysUser)){
                return YdOaResult.error().setMsg("请输入密码!");
            } else if (!isPasswordValid(sysUser.getPassword())) return YdOaResult.error().setMsg("密码长度因介于8-18之间!");

            sysUser.setId(null);//自动生成id

            //密码需要加密
            String strong_salt = BCrypt.gensalt(10);
            String password_salt = BCrypt.hashpw(sysUser.getPassword(),strong_salt);

            sysUser.setPassword(password_salt);

            if(iSysUserService.save(sysUser)){
                return YdOaResult.ok("添加成功");
            }
            return YdOaResult.error("添加失败");
        } catch (Exception e) {
            log.error("添加用户出错!!————",e);
            return YdOaResult.error().setCode(ResponseCodeEnum.CODE_503.getCode()).setMsg("添加用户出错!");
        }
    }
    /**修改用户**/
    @PutMapping("/update")
    public YdOaResult updateUser (@RequestBody SysUser sysUser){
        if (!isUserHaveId(sysUser)){
            return YdOaResult.error().setMsg("请指定要修改的用户id!");
        }
        try {
            if (!isUserHaveUsername(sysUser)){//如果是空串,不修改用户名
                sysUser.setUsername(null);
            }else if(!isUsernameValid(sysUser.getUsername())){//指定了用户名
                return YdOaResult.error().setMsg("用户名长度应介于8-25之间");
            }else{
                //判断是否是别人的用户名
                List<SysUser> sysUserList = iSysUserService.getByUsername(sysUser.getUsername());
                //如果用户名存在,且这个用户名是别人在用的话,不可以修改
                if (!sysUserList.isEmpty() && !Objects.equals(sysUserList.get(0).getId(), sysUser.getId())) return YdOaResult.error().setMsg("用户名已存在!");
            }
            if (!isUserHavePassword(sysUser)){
                sysUser.setPassword(null);
            } else if (!isPasswordValid(sysUser.getPassword()))
                return YdOaResult.error().setMsg("密码长度因介于8-18之间!");
            else{
                //密码需要加密
                String strong_salt = BCrypt.gensalt(10);
                String password_salt = BCrypt.hashpw(sysUser.getPassword(),strong_salt);

                sysUser.setPassword(password_salt);
            }

            if(iSysUserService.updateById(sysUser)){
                return YdOaResult.ok("修改成功");
            }
            return YdOaResult.error("修改失败");
        } catch (Exception e) {
            log.error("修改用户出错!!————",e);
            return YdOaResult.error().setCode(ResponseCodeEnum.CODE_503.getCode()).setMsg("修改用户出错!");
        }
    }
    @Autowired
    private ISysUserRoleService sysUserRoleService;
    /**删除用户**/
    @DeleteMapping("/delete")
    @Transactional
    public YdOaResult updateUser (@RequestParam String id){
        if (id.isEmpty()){
            return YdOaResult.error().setMsg("请指定要删除的用户id!");
        }else if(id.equals("1")) return YdOaResult.error().setMsg("无法删除的用户!");
        try {

            if(iSysUserService.deleteById(id)){
                sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("uid",id));
                return YdOaResult.ok("删除成功");
            }
            return YdOaResult.error("删除失败");
        } catch (Exception e) {
            log.error("删除用户出错!!————",e);
            return YdOaResult.error().setCode(ResponseCodeEnum.CODE_503.getCode()).setMsg("删除用户出错!");
        }
    }

    /**
     * 用户输入信息是否有效
     */
    private boolean userHave(SysUser sysUser,boolean id,boolean username,boolean password){
        if (sysUser == null) return false;
        if ( id &&(sysUser.getId()==null || sysUser.getId().isEmpty())){
            return false;
        }
        if (username && (sysUser.getUsername()==null || sysUser.getUsername().isEmpty())) return false;
        return !password || (sysUser.getPassword() != null && !sysUser.getPassword().isEmpty());
    }
    private boolean isUserHaveId(SysUser sysUser){return userHave(sysUser,true,false,false);}
    private boolean isUserHaveUsername(SysUser sysUser){return userHave(sysUser,false,true,false);}
    private boolean isUserHavePassword(SysUser sysUser){return userHave(sysUser,false,false,true);}
    //用户名是否合法有效
    private boolean isUsernameValid(String username) {return username.length()>=8 && username.length()<=25;}
    private boolean isPasswordValid(String password) {return password.length()>=8 && password.length()<=18;}
}

2. user_role相关接口实现

在这里插入图片描述

2.0 实体类

在这里插入图片描述

package com.yd_oa_java_cloud.security.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Getter;
import lombok.Setter;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
@Getter
@Setter
@TableName("sys_user_role")
public class SysUserRole implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 用户id
     */
    @TableField("uid")
    private String uid;

    /**
     * 角色id
     */
    @TableField("rid")
    private String rid;
}

2.1 mapper

在这里插入图片描述

package com.yd_oa_java_cloud.security.mapper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd_oa_java_cloud.security.entity.SysRole;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.yd_oa_java_cloud.security.entity.SysUserRole;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import java.util.List;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
public interface SysUserRoleMapper extends BaseMapper<SysUserRole> {
    List<SysRole> getRolesByUserId(String id);
    int deleteUserAndRoleById(String id);
}

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yd_oa_java_cloud.security.mapper.SysUserRoleMapper">
    <resultMap id="SysUserResult" type="com.yd_oa_java_cloud.security.entity.SysUser">
        <result property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <collection property="roles" ofType="com.yd_oa_java_cloud.security.entity.SysRole">
            <id column="rid" property="id"/>
            <result column="rname" property="name"/>
            <result column="rnameZh" property="nameZh"/>
        </collection>
    </resultMap>
    <resultMap id="SysUserRoleResult" type="com.yd_oa_java_cloud.security.entity.SysUser" extends="SysUserResult">
        <collection property="roles" ofType="com.yd_oa_java_cloud.security.entity.SysRole">
            <id column="rid" property="id"/>
            <result column="rname" property="name"/>
            <result column="rnameZh" property="nameZh"/>
        </collection>
    </resultMap>


<!--    查询用户和角色权限,可以根据用户id,用户名,角色名查询,三者可以相互组合-->
    <select id="getSysUserRoleList" resultMap="SysUserResult" parameterType="com.yd_oa_java_cloud.security.entity.SysUser">
        select
            u.id as id,
            u.username as username,
            u.`password` as `password`,
            r.id as rid,
            r.`name` as rname,
            r.name_zh as rnameZh
        from
            sys_user as u
        left join
            sys_user_role as ur
        on
            u.id = ur.uid
        left join
            sys_role as r
        on
            ur.rid = r.id
<!--        <where>-->
<!--            <trim>-->
<!--                <if test="id != null  and id != '' and id!=0">and u.id = #{id}</if>-->
<!--                <if test="username != null  and username != ''">and u.username like concat('%', #{username}, '%')</if>-->
<!--                <if test="roles != null">and r.name_zh like concat('%', #{roles[0].nameZh}, '%')</if>-->
<!--            </trim>-->
<!--        </where>-->
    </select>
    <select id="getRolesByUserId" resultType="com.yd_oa_java_cloud.security.entity.SysRole">
        select
            *
        from
            sys_role as r
        left join
            sys_user_role as ur
        on
            ur.rid = r.id
        <where>
            <trim>
                <if test="id != null  and id != '' and id!=0">and ur.uid = #{id}</if>
            </trim>
        </where>
    </select>
    <delete id="deleteUserAndRoleById" parameterType="String">
        delete u,ur from
            sys_user as u
        LEFT JOIN
            sys_user_role as ur
        on
            ur.uid = u.id
        <where>
            <trim>
                <if test="id != null and id !=''">and u.id=#{id}</if>
            </trim>
        </where>
    </delete>
</mapper>

2.2 service

在这里插入图片描述

package com.yd_oa_java_cloud.security.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd_oa_java_cloud.security.entity.SysRole;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.yd_oa_java_cloud.security.entity.SysUserRole;
import com.baomidou.mybatisplus.extension.service.IService;

import java.util.List;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author Taylor Sinclair(殷志鹏)
 * @since 2025-01-10
 */
public interface ISysUserRoleService extends IService<SysUserRole> {

    List<SysRole> getRolesByUserId(String id);
}

在这里插入图片描述

package com.yd_oa_java_cloud.security.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd_oa_java_cloud.security.entity.SysRole;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.yd_oa_java_cloud.security.entity.SysUserRole;
import com.yd_oa_java_cloud.security.mapper.SysUserRoleMapper;
import com.yd_oa_java_cloud.security.service.ISysUserRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Taylor Sinclair(殷志鹏)
 * @since 2025-01-10
 */
@Service
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRole> implements ISysUserRoleService {
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Override
    public List<SysRole> getRolesByUserId(String id) {
        return sysUserRoleMapper.getRolesByUserId(id);
    }
}

2.3 controller

在这里插入图片描述

package com.yd_oa_java_cloud.security.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd_oa_java_cloud.base.entity.vo.YdOaResult;
import com.yd_oa_java_cloud.security.entity.SysRole;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.yd_oa_java_cloud.security.entity.SysUserRole;
import com.yd_oa_java_cloud.security.service.ISysUserRoleService;
import com.yd_oa_java_cloud.security.service.ISysUserService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
@RestController
@RequestMapping("/sysUserRole")
@Log4j2
public class SysUserRoleController {
    @Autowired
    private ISysUserRoleService sysUserRoleService;
    @Autowired
    private ISysUserService sysUserService;
    /**
     * 分页查询用户,并封装用户角色信息
     */
    @GetMapping("/getAllPage/{current}/{size}")
    public YdOaResult getAllPage(@PathVariable Integer current,@PathVariable Integer size){
        Page<SysUser> page = new Page<>(current, size);//构建分页对象

        try {
            List<SysUser> sysUserList = sysUserService.getAllUserPage(page);//传入分页对象,分页查询
            if (sysUserList.isEmpty()) return YdOaResult.error("没有查询到任何用户信息");
            for (int i = 0;i<sysUserList.size();i++){
                SysUser sysUser = sysUserList.get(i);
                List<SysRole> roles = sysUserRoleService.getRolesByUserId(sysUser.getId());
                sysUser.setRoles(roles);

            }
            return YdOaResult.ok()
                    .set("current",page.getCurrent())//当前所在页
                    .set("pages",page.getPages())//共可以分几页
                    .set("Size",page.getSize())//每页记录数
                    .set("Total",page.getTotal())//数据库表共有多少条数据
                    .set("hasNext",page.hasNext())//是否有下一页
                    .set("hasPrevious",page.hasPrevious())//是否有前一页
                    .setData(sysUserList)//放入查询结果
                    ;
        } catch (Exception e) {
            log.error("分页获取用户角色出错!!————",e);
            return YdOaResult.error().setMsg("查询出错!");
        }
    }
    /**
     * 根据用户id返回角色
     */
    @GetMapping("getById/{uid}")
    public YdOaResult getById(@PathVariable String uid){
        try {
            List<SysRole> roles = sysUserRoleService.getRolesByUserId(uid);
            return YdOaResult.ok()
                    .setData(roles)//放入查询结果
                    ;
        } catch (Exception e) {
            log.error("根据用户id返回角色出错!!————",e);
            return YdOaResult.error().setMsg("查询出错!");
        }
    }
    //"更新用户拥有的角色")
    @PutMapping("/updateUserRole")
    public YdOaResult updateUserRole(String uid,String[] rids){
        return sysUserService.updateUserRole(uid,rids);
    }
}

3. role相关接口

在这里插入图片描述

3.0 实体类

在这里插入图片描述

package com.yd_oa_java_cloud.security.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Getter;
import lombok.Setter;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
@Getter
@Setter
@TableName("sys_role")
public class SysRole implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * id
     */
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private String id;

    /**
     * 角色名
     */
    @TableField("name")
    private String name;

    /**
     * 角色描述
     */
    @TableField("name_zh")
    private String nameZh;
}

3.1 mapper

无需编写

3.2 service

在这里插入图片描述

package com.yd_oa_java_cloud.security.service;

import com.yd_oa_java_cloud.security.entity.SysRole;
import com.baomidou.mybatisplus.extension.service.IService;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author Taylor Sinclair(殷志鹏)
 * @since 2025-01-10
 */
public interface ISysRoleService extends IService<SysRole> {
    /**
     * 删除角色,同时删除与菜单的对应关系
     */
    boolean deleteById(String id);
}

在这里插入图片描述

package com.yd_oa_java_cloud.security.service.impl;

import com.yd_oa_java_cloud.security.entity.SysRole;
import com.yd_oa_java_cloud.security.mapper.SysRoleMapper;
import com.yd_oa_java_cloud.security.mapper.SysRoleMenuMapper;
import com.yd_oa_java_cloud.security.service.ISysRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Taylor Sinclair(殷志鹏)
 * @since 2025-01-10
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;
    /**
     * 根据id,删除角色,同时删除与菜单的对应关系
     */
    @Override
    @Transactional//自己写增删改的操作,一定要加事务
    public boolean deleteById(String id) {
        return sysRoleMenuMapper.deleteRoleAndRoleMenuById(id)>=1;
    }
}

3.3 controller

在这里插入图片描述

package com.yd_oa_java_cloud.security.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd_oa_java_cloud.base.entity.vo.YdOaResult;
import com.yd_oa_java_cloud.security.entity.SysRole;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.yd_oa_java_cloud.security.entity.SysUserRole;
import com.yd_oa_java_cloud.security.service.ISysRoleService;
import com.yd_oa_java_cloud.security.service.ISysUserRoleService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
@RestController
@RequestMapping("/sysRole")
@Log4j2
public class SysRoleController {
    @Autowired
    private ISysRoleService sysRoleService;
    @Autowired
    private ISysUserRoleService sysUserRoleService;

    //获取所有角色
    @GetMapping("/getAllRoles")
    public YdOaResult getAllRoles(){
        try {
            List<SysRole> list = sysRoleService.list();
            if(list.isEmpty()){
                return YdOaResult.error("没有获取的任何角色信息!!!");
            }
            return YdOaResult.ok().set("RoleAllList",list);
        } catch (Exception e) {
            log.error("获取所有角色出错!!————",e);
            return YdOaResult.error().setMsg("查询出错!");
        }
    }
    //分页获取所有角色
    @GetMapping("/page/{current}/{size}")
    public YdOaResult getAllRolesPage(@PathVariable Integer current, @PathVariable Integer size){
        Page<SysRole> page = new Page<>(current, size);//构建分页对象
        try {
            List<SysRole> list = sysRoleService.list(page);
            if(list.isEmpty()){
                return YdOaResult.error("没有获取的任何角色信息!!!");
            }
            return YdOaResult.ok()
                    .set("current",page.getCurrent())//当前所在页
                    .set("pages",page.getPages())//共可以分几页
                    .set("Size",page.getSize())//每页记录数
                    .set("Total",page.getTotal())//数据库表共有多少条数据
                    .set("hasNext",page.hasNext())//是否有下一页
                    .set("hasPrevious",page.hasPrevious())//是否有前一页
                    .setData(list)//放入查询结果
                    ;
        } catch (Exception e) {
            log.error("分页获取所有角色出错!!————",e);
            return YdOaResult.error().setMsg("查询出错!");
        }
    }
    //修改角色
    @PutMapping("/updateRole")
    public YdOaResult updateRole(@RequestBody SysRole sysRole){
        //如果角色名不是ROLE_打头,就补充上
        if(!sysRole.getName().startsWith("ROLE_")){
            sysRole.setName("ROLE_"+sysRole.getName());
        }
        try {
            if(sysRoleService.updateById(sysRole)){
                return YdOaResult.ok("修改成功");
            }
            return YdOaResult.error("修改失败");
        } catch (Exception e) {
            log.error("修改角色出错!!————",e);
            return YdOaResult.error().setMsg("修改出错!");
        }
    }
    //"添加角色"
    @PostMapping("/addRole")
    public YdOaResult addRole(@RequestBody SysRole sysRole){
        //如果角色名不是ROLE_打头,就补充上
        if(!sysRole.getName().startsWith("ROLE_")){
            sysRole.setName("ROLE_"+sysRole.getName());
        }
        try {
            sysRole.setId(null);
            if(sysRoleService.save(sysRole)){
                return YdOaResult.ok("添加成功");
            }
            return YdOaResult.error("添加失败");
        } catch (Exception e) {
            log.error("添加角色出错!!————",e);
            return YdOaResult.error().setMsg("添加出错!");
        }
    }

    //"删除角色"
    @DeleteMapping("/{id}")
    @Transactional
    public YdOaResult deleteRole(@PathVariable(value = "id",name = "id") String id){
        try {
            //删除角色的同时,要将角色和菜单对应表的数据删掉
            if(sysRoleService.deleteById(id)){
                sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("rid",id));//用户与角色对应关系删除
                return YdOaResult.ok("删除成功");
            }
            return YdOaResult.error("删除失败");
        } catch (Exception e) {
            log.error("删除角色出错!!————",e);
            return YdOaResult.error().setMsg("删除出错!");
        }
    }
}

4. user_role相关接口

在这里插入图片描述

4.0 实体类

在这里插入图片描述

package com.yd_oa_java_cloud.security.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Getter;
import lombok.Setter;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
@Getter
@Setter
@TableName("sys_user_role")
public class SysUserRole implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 用户id
     */
    @TableField("uid")
    private String uid;

    /**
     * 角色id
     */
    @TableField("rid")
    private String rid;
}

4.1 mapper

在这里插入图片描述

package com.yd_oa_java_cloud.security.mapper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd_oa_java_cloud.security.entity.SysRole;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.yd_oa_java_cloud.security.entity.SysUserRole;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import java.util.List;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
public interface SysUserRoleMapper extends BaseMapper<SysUserRole> {

    List<SysRole> getRolesByUserId(String id);

    int deleteUserAndRoleById(String id);
}

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yd_oa_java_cloud.security.mapper.SysUserRoleMapper">
    <resultMap id="SysUserResult" type="com.yd_oa_java_cloud.security.entity.SysUser">
        <result property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <collection property="roles" ofType="com.yd_oa_java_cloud.security.entity.SysRole">
            <id column="rid" property="id"/>
            <result column="rname" property="name"/>
            <result column="rnameZh" property="nameZh"/>
        </collection>
    </resultMap>
    <resultMap id="SysUserRoleResult" type="com.yd_oa_java_cloud.security.entity.SysUser" extends="SysUserResult">
        <collection property="roles" ofType="com.yd_oa_java_cloud.security.entity.SysRole">
            <id column="rid" property="id"/>
            <result column="rname" property="name"/>
            <result column="rnameZh" property="nameZh"/>
        </collection>
    </resultMap>


<!--    查询用户和角色权限,可以根据用户id,用户名,角色名查询,三者可以相互组合-->
    <select id="getSysUserRoleList" resultMap="SysUserResult" parameterType="com.yd_oa_java_cloud.security.entity.SysUser">
        select
            distinct
            u.id as id,
            u.username as username,
            u.`password` as `password`,
            r.id as rid,
            r.`name` as rname,
            r.name_zh as rnameZh
        from
            sys_user as u
        left join
            sys_user_role as ur
        on
            u.id = ur.uid
        left join
            sys_role as r
        on
            ur.rid = r.id
<!--        <where>-->
<!--            <trim>-->
<!--                <if test="id != null  and id != '' and id!=0">and u.id = #{id}</if>-->
<!--                <if test="username != null  and username != ''">and u.username like concat('%', #{username}, '%')</if>-->
<!--                <if test="roles != null">and r.name_zh like concat('%', #{roles[0].nameZh}, '%')</if>-->
<!--            </trim>-->
<!--        </where>-->
    </select>
    <select id="getRolesByUserId" resultType="com.yd_oa_java_cloud.security.entity.SysRole">
        select
            *
        from
            sys_role as r
        left join
            sys_user_role as ur
        on
            ur.rid = r.id
        <where>
            <trim>
                <if test="id != null  and id != '' and id!=0">and ur.uid = #{id}</if>
            </trim>
        </where>
    </select>
    <delete id="deleteUserAndRoleById" parameterType="String">
        delete u,ur from
            sys_user as u
        LEFT JOIN
            sys_user_role as ur
        on
            ur.uid = u.id
        <where>
            <trim>
                <if test="id != null and id !=''">and u.id=#{id}</if>
            </trim>
        </where>
    </delete>
    <!--根据uid删除-->
    <delete id="deleteByUid" parameterType="String">
        delete from sys_user_role where uid = #{uid}
    </delete>

    <!--更新用户角色-->
    <insert id="insertRecord">
        insert into sys_user_role(uid,rid) values
        <foreach collection="rids" item="rid" separator=",">
            (#{uid},#{rid})
        </foreach>
    </insert>
</mapper>


4.2 service

在这里插入图片描述

package com.yd_oa_java_cloud.security.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd_oa_java_cloud.security.entity.SysRole;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.yd_oa_java_cloud.security.entity.SysUserRole;
import com.baomidou.mybatisplus.extension.service.IService;

import java.util.List;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author Taylor Sinclair(殷志鹏)
 * @since 2025-01-10
 */
public interface ISysUserRoleService extends IService<SysUserRole> {

    List<SysRole> getRolesByUserId(String id);
}

在这里插入图片描述

package com.yd_oa_java_cloud.security.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd_oa_java_cloud.security.entity.SysRole;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.yd_oa_java_cloud.security.entity.SysUserRole;
import com.yd_oa_java_cloud.security.mapper.SysUserRoleMapper;
import com.yd_oa_java_cloud.security.service.ISysUserRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Taylor Sinclair(殷志鹏)
 * @since 2025-01-10
 */
@Service
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRole> implements ISysUserRoleService {
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Override
    public List<SysRole> getRolesByUserId(String id) {
        return sysUserRoleMapper.getRolesByUserId(id);
    }
}

4.3 controller

在这里插入图片描述

package com.yd_oa_java_cloud.security.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd_oa_java_cloud.base.entity.vo.YdOaResult;
import com.yd_oa_java_cloud.security.entity.SysRole;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.yd_oa_java_cloud.security.entity.SysUserRole;
import com.yd_oa_java_cloud.security.service.ISysUserRoleService;
import com.yd_oa_java_cloud.security.service.ISysUserService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
@RestController
@RequestMapping("/sysUserRole")
@Log4j2
public class SysUserRoleController {
    @Autowired
    private ISysUserRoleService sysUserRoleService;
    @Autowired
    private ISysUserService sysUserService;
    /**
     * 分页查询用户,并封装用户角色信息
     */
    @GetMapping("/getAllPage/{current}/{size}")
    public YdOaResult getAllPage(@PathVariable Integer current,@PathVariable Integer size){
        Page<SysUser> page = new Page<>(current, size);//构建分页对象

        try {
            List<SysUser> sysUserList = sysUserService.getAllUserPage(page);//传入分页对象,分页查询
            if (sysUserList.isEmpty()) return YdOaResult.error("没有查询到任何用户信息");
            for (int i = 0;i<sysUserList.size();i++){
                SysUser sysUser = sysUserList.get(i);
                List<SysRole> roles = sysUserRoleService.getRolesByUserId(sysUser.getId());
                sysUser.setRoles(roles);

            }
            return YdOaResult.ok()
                    .set("current",page.getCurrent())//当前所在页
                    .set("pages",page.getPages())//共可以分几页
                    .set("Size",page.getSize())//每页记录数
                    .set("Total",page.getTotal())//数据库表共有多少条数据
                    .set("hasNext",page.hasNext())//是否有下一页
                    .set("hasPrevious",page.hasPrevious())//是否有前一页
                    .setData(sysUserList)//放入查询结果
                    ;
        } catch (Exception e) {
            log.error("分页获取用户角色出错!!————",e);
            return YdOaResult.error().setMsg("查询出错!");
        }
    }
    /**
     * 根据用户id返回角色
     */
    @GetMapping("getById/{uid}")
    public YdOaResult getById(@PathVariable String uid){
        try {
            List<SysRole> roles = sysUserRoleService.getRolesByUserId(uid);
            return YdOaResult.ok()
                    .setData(roles)//放入查询结果
                    ;
        } catch (Exception e) {
            log.error("根据用户id返回角色出错!!————",e);
            return YdOaResult.error().setMsg("查询出错!");
        }
    }
    //"更新用户拥有的角色")
    @PutMapping("/updateUserRole")
    public YdOaResult updateUserRole(String uid,String[] rids){
        return sysUserService.updateUserRole(uid,rids);
    }
}

5. menu相关接口

在这里插入图片描述

5.0 实体类

菜单接口最难,因为是树形结构的,实体类需要保存自己的子菜单


在这里插入图片描述

package com.yd_oa_java_cloud.security.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.List;

import lombok.Getter;
import lombok.Setter;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
@Getter
@Setter
@TableName("sys_menu")
public class SysMenu implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * id
     */
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private String id;

    /**
     * 父菜单id
     */
    @TableField("pid")
    private String pid;

    /**
     * 菜单名
     */
    @TableField("name")
    private String name;

    /**
     * 菜单类型(目录,按钮)
     */
    @TableField("type")
    private String type;

    /**
     * 菜单权限
     */
    @TableField("permission")
    private String permission;

    /**
     * url
     */
    @TableField("url")
    private String url;

    /**
     * path
     */
    @TableField("path")
    private String path;

    /**
     * 组件
     */
    @TableField("component")
    private String component;

    /**
     * 图标
     */
    @TableField("iconCls")
    private String iconCls;

    /**
     * 是否保持激活
     */
    @TableField("keepAlive")
    private Boolean keepAlive;

    /**
     * 是否要求权限
     */
    @TableField("requireAuth")
    private Boolean requireAuth;

    /**
     * 是否启用
     */
    @TableField("enabled")
    private Boolean enabled;
    /**
     * 子菜单
     */

    @TableField(exist = false)//告诉Mybatis,表中没有这个字段,否则操作时会去数据库找这个字段
    private List<SysMenu> children;
}

5.1 mapper

在这里插入图片描述

package com.yd_oa_java_cloud.security.mapper;

import com.yd_oa_java_cloud.security.entity.SysMenu;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
public interface SysMenuMapper extends BaseMapper<SysMenu> {

    List<SysMenu> getMenusByUserId(String id);
    /**
     * 更新角色菜单
     * 先将当前角色所有菜单都删除,然后再更新
     * @param rid 角色id
     * @param mids 要更新的菜单id
     */
    Integer insertRecord(String rid, String[] mids);
}

注意这里实现了将用户所有菜单(包括子菜单)返回出来(无论多少层级),但是只能返回成一个2级结构,所以还需要代码进行额外处理


在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yd_oa_java_cloud.security.mapper.SysMenuMapper">
    <!-- DdMenu映射对象-->
    <resultMap id="BaseResultMap" type="com.yd_oa_java_cloud.security.entity.SysMenu">
        <id column="id" property="id" />
        <result column="pid" property="pid" />
        <result column="name" property="name" />
        <result column="type" property="type" />
        <result column="permission" property="permission" />
        <result column="url" property="url" />
        <result column="path" property="path" />
        <result column="component" property="component" />
        <result column="iconCls" property="iconCls" />
        <result column="keepAlive" property="keepAlive" />
        <result column="requireAuth" property="requireAuth" />
        <result column="enabled" property="enabled" />
    </resultMap>
    <!--子菜单,继承上面DdMenu映射对象-->
    <resultMap id="Menus" type="com.yd_oa_java_cloud.security.entity.SysMenu" extends="BaseResultMap">
        <collection property="children" ofType="com.yd_oa_java_cloud.security.entity.SysMenu">
            <id column="id2" property="id" />
            <result column="pid2" property="pid" />
            <result column="name2" property="name" />
            <result column="type2" property="type" />
            <result column="permission2" property="permission" />
            <result column="url2" property="url" />
            <result column="path2" property="path" />
            <result column="component2" property="component" />
            <result column="iconCls2" property="iconCls" />
            <result column="keepAlive2" property="keepAlive" />
            <result column="requireAuth2" property="requireAuth" />
            <result column="enabled2" property="enabled" />
        </collection>
    </resultMap>
    <select id="getMenusByUserId" resultMap="Menus">
        select
            distinct
            m1.*,
            m2.id as id2,
            m2.pid as pid2,
            m2.`name` as name2,
            m2.type as type2,
            m2.permission as permission2,
            m2.url as url2,
            m2.path as path2,
            m2.component as component2,
            m2.iconCls as iconCls2,
            m2.keepAlive as keepAlive2,
            m2.requireAuth as requireAuth,
            m2.enabled as enabled2
        from
            sys_menu as m1
        inner join
            sys_menu as m2
        on
            m1.id = m2.pid
        inner join
            sys_role_menu as rm
        on
            rm.mid = m2.id
        inner join
            sys_user_role as ur
        on
            ur.rid = rm.rid
        where
            ur.uid = #{id}
    </select>
    <!--更新角色菜单-->
    <insert id="insertRecord">
        insert into sys_role_menu(rid,mid) values
        <foreach collection="mids" item="mid" separator=",">
            (#{rid},#{mid})
        </foreach>
    </insert>
</mapper>

5.2 service

在这里插入图片描述

package com.yd_oa_java_cloud.security.service;

import com.yd_oa_java_cloud.base.entity.vo.YdOaResult;
import com.yd_oa_java_cloud.security.entity.SysMenu;
import com.baomidou.mybatisplus.extension.service.IService;

import java.util.List;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author Taylor Sinclair(殷志鹏)
 * @since 2025-01-10
 */
public interface ISysMenuService extends IService<SysMenu> {
    /**
     * 根据用户id获取菜单
     */
    List<SysMenu> getMenusByUserId(String id);
    //更新角色菜单
    YdOaResult updateMenuRole(String rid, String[] mids);

    List<SysMenu> getMenusByLoginId();

    List<SysMenu> listTree();
}

在这里插入图片描述

package com.yd_oa_java_cloud.security.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yd_oa_java_cloud.base.entity.vo.YdOaResult;
import com.yd_oa_java_cloud.security.entity.SysMenu;
import com.yd_oa_java_cloud.security.entity.SysRoleMenu;
import com.yd_oa_java_cloud.security.entity.SysUser;
import com.yd_oa_java_cloud.security.mapper.SysMenuMapper;
import com.yd_oa_java_cloud.security.mapper.SysRoleMenuMapper;
import com.yd_oa_java_cloud.security.service.ISysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.SerializationUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;



    private List<SysMenu> treeData(List<SysMenu> menus){
        return treeData(menus,"0");
    }
    /**
     * 转换为树形结构
     * @param menus 数据列表
     * @param rootId 这个是根结点id,不是字段名,例如根结点是由0标识的
     * @return 转为树形结构的数据列表
     * >>>>>>>>>>>>>>>殷志鹏-2025-1-15
     */
    private List<SysMenu> treeData(List<SysMenu> menus,String rootId){
        //对源数据深拷贝
        Object clone = SerializationUtils.clone((Serializable) menus);
        ArrayList<SysMenu> deepCopy = new ArrayList<SysMenu>((List)clone);
        //最终结果
        List<SysMenu> ans = new ArrayList<>();
        ans = treeData(deepCopy,rootId,ans);
        return ans;
    }
    private List<SysMenu> treeData(List<SysMenu> deepCopy,String rootId,List<SysMenu> result){
        return deepCopy.stream().filter(father->{
            List<SysMenu> collect = deepCopy.stream().filter(child -> {
                return father.getId().equals(child.getPid());
            }).collect(Collectors.toList());
            if (!collect.isEmpty()) father.setChildren(collect);
            else father.setChildren(null);
            return father.getPid().equals(rootId);
        }).collect(Collectors.toList());
    }


    private List<SysMenu> unTreeData(List<SysMenu> menus){
        //对源数据深拷贝
        Object clone = SerializationUtils.clone((Serializable) menus);
        ArrayList<SysMenu> deepCopy = new ArrayList<SysMenu>((List)clone);
        //最终结果
        ArrayList<SysMenu> ans = new ArrayList<>();
        //递归
        unTreeData(deepCopy,ans);

        return ans;
    }
    private void unTreeData(List<SysMenu> source,List<SysMenu> result){
        for (SysMenu father:source) {
            if(father.getChildren()!=null){
                result.add(father);
                unTreeData(father.getChildren(),result);
                father.setChildren(null);
            } else {
                result.add(father);
            }
        }
    }
    /**
     * 根据登录用户id获取菜单
     */
    @Override
    public List<SysMenu> getMenusByLoginId() {
        //上下文获取user对象
        SysUser user = (SysUser)StpUtil.getSession().get("user");
//        //获取redis对象
//        ValueOperations<String,Object> valueOperations = redisTemplate.opsForValue();
//        //先从redis中查询
//        List<SysMenu> menus = (List<SysMenu>) valueOperations.get("menu_" + user.getId());
//        //如果redis没有,查mysql
//        if(CollectionUtils.isEmpty(menus)){
//            menus = sysMenuMapper.getMenusByUserId(user.getId());
//            valueOperations.set("menu_" + user.getId(),menus,30, TimeUnit.MINUTES);
//        }
        List<SysMenu> menus = sysMenuMapper.getMenusByUserId(user.getId());
        List<SysMenu> unTreeData = unTreeData(menus);
        List<SysMenu> treeData = treeData(unTreeData);
        return treeData;
    }

    /**
     * 获取树形结构
     * @return
     */
    @Override
    public List<SysMenu> listTree() {
        List<SysMenu> list = (List<SysMenu>)sysMenuMapper.selectList((Wrapper) Wrappers.emptyWrapper());
        List<SysMenu> treeData = treeData(list);
        return treeData;
    }

    /**
     * 根据用户id获取菜单,非菜单结构
     */
    @Override
    public List<SysMenu> getMenusByUserId(String id) {
        List<SysMenu> menus = sysMenuMapper.getMenusByUserId(id);
        List<SysMenu> unTreeData = unTreeData(menus);
        return unTreeData;
    }


    /**
     * 更新角色菜单
     * 先将当前角色所有菜单都删除,然后再更新
     * @param rid 角色id
     * @param mids 要更新的菜单id
     */
    @Override
    @Transactional//自己写更新的操作,一定要加事务,一个操作失败,则所有操作失败
    public YdOaResult updateMenuRole(String rid, String[] mids) {
        //要更新的菜单id为空,则直接返回
        if(null == mids||mids.length == 0){
            return YdOaResult.ok("更新菜单成功");
        }
        //先全删了,否则得一次次判断,太费资源
        sysRoleMenuMapper.delete(new QueryWrapper<SysRoleMenu>().eq("rid", rid));
        //如果传了菜单id过来,则更新
        sysMenuMapper.insertRecord(rid,mids);
        return YdOaResult.ok("更新菜单成功");
    }


}

5.3 controller

在这里插入图片描述

package com.yd_oa_java_cloud.security.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yd_oa_java_cloud.base.entity.vo.YdOaResult;
import com.yd_oa_java_cloud.security.entity.SysMenu;
import com.yd_oa_java_cloud.security.entity.SysRoleMenu;
import com.yd_oa_java_cloud.security.service.ISysMenuService;
import com.yd_oa_java_cloud.security.service.ISysRoleMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * _*_ coding : utf-8 _*_
 * @Time : 2025/1/14 星期二 10:30
 * @Author : Taylor Sinclair(殷志鹏)
 * @File : ${NAME}
 * @Project : ${PROJECT_NAME}
 * @Description :
 */
@RestController
@RequestMapping("/sysMenu")
public class SysMenuController {
    @Autowired
    private ISysMenuService sysMenuService;
    @Autowired
    private ISysRoleMenuService sysRoleMenuService;
    //根据当前登录用户id获取菜单
    @GetMapping("/LoginMenu")
    public YdOaResult getMenusByLoginId(){
        List<SysMenu> list = sysMenuService.getMenusByLoginId();
//        if(list.isEmpty()){
//            return Result.error().message("没有菜单!!");
//        }
        return YdOaResult.ok().set("menus",list);
    }
    //根据用户id获取菜单
    @GetMapping("/getMenusByUserId/{id}")
    public YdOaResult getMenusByUserId(@PathVariable String id){
        List<SysMenu> list = sysMenuService.getMenusByUserId(id);
//        if(list.isEmpty()){
//            return Result.error().message("没有菜单!!");
//        }
        return YdOaResult.ok().set("menus",list);
    }
    //查询所有菜单
    @GetMapping("/menus")
    public YdOaResult getMenus(){
        List<SysMenu> list = sysMenuService.listTree();
        if(list.isEmpty()){
            return YdOaResult.error("没有菜单!!");
        }
        return YdOaResult.ok().set("menuAllList",list);
    }
    //"添加菜单"
    @PostMapping("/")
    public YdOaResult insertMenu(@RequestBody SysMenu sysMenu){
        sysMenu.setId(null);//自动生成
        if(sysMenuService.save(sysMenu)){
            return YdOaResult.ok("添加成功");
        }
        return YdOaResult.error("添加失败");
    }
    //"修改菜单"
    @PutMapping("/")
    public YdOaResult updateMenu(@RequestBody SysMenu ddMenu){
        if(sysMenuService.updateById(ddMenu)){
            return YdOaResult.ok("修改成功");
        }
        return YdOaResult.error("修改失败");
    }
    //"删除菜单"
    @DeleteMapping("/{id}")
    @Transactional
    public YdOaResult deleteRole(@PathVariable(value = "id",name = "id") String id){
        if(sysMenuService.removeById(id)){//删除菜单成功
            sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("mid",id));//删除对应关系
            return YdOaResult.ok("删除成功");
        }
        return YdOaResult.error("删除失败");
    }
    //"批量删除菜单"
    @DeleteMapping ("/ids")
    public YdOaResult deleteRoleList(String ids){
        System.out.println(ids);
        String[] split = ids.split(",");
        if(sysMenuService.removeByIds(Arrays.asList(split.clone()))){
            return YdOaResult.ok("删除成功");
        }
        return YdOaResult.error("删除失败");
    }
    //"根据角色id查询菜单id"
    @GetMapping("/menuIdByRoleId/{rid}")
    public YdOaResult getMenuIdByRoleId(@PathVariable String rid){
        List<String> mids = sysRoleMenuService.list(new QueryWrapper<SysRoleMenu>().eq("rid", rid))
                .stream().map(SysRoleMenu::getMid).collect(Collectors.toList());
        if(mids.isEmpty()){
            return YdOaResult.error("此用户还没有分配菜单");
        }
        return YdOaResult.ok().set("menuId",mids);
    }
    //"更新角色菜单"
    @PutMapping("/roleAndMenu")
    public YdOaResult updateMenuRole(String rid,String[] mids){
        return sysMenuService.updateMenuRole(rid,mids);
    }
}
SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层? 这里,通过Python 图像识别与文本提取(OCR) 业务为例,实现一个 SpringCloud + Python 混合微服务架构实操。在日常的开发中,图像识别与文本提取(OCR)技术扮演着至关重要的角色,它们极大地促进了业务流程的自动化,提升了用户体验。特别是在互联网和金融行业,这一需求尤为显著。一般来说,图像识别与文本提取(OCR)都是通过python实现。并且在Python生态中,有一个OCR的明星库——PaddleOCR。 阅读详情

相关推荐

【FasAPI】使用FastAPI来实现一个基于RBAC(基于角色的访问控制)的用户权限控制系统

使用FastAPI来实现一个基于RBAC(基于角色的访问控制)的用户权限控制系统。以下是一个简单的实现方案,涵盖了用户管理、角色管理和权限管理的基本功能。

h1773655323的博客 2462

SpringCloud+Vue+Python人工智能(fastAPI,机器学习,深度学习)前后端架构各功能实现思路——SpringCloud后端——整合mybatis plus和代码生成器

【代码】SpringCloud+Vue+Python人工智能(fastAPI,机器学习,深度学习)前后端架构各功能实现思路——SpringCloud后端——整合mybatis plus和代码生成器。

殷志鹏的博客 1133

Cadence Sigrity PowerSI实战:从.brd到S参数提取的完整避坑指南

本文详细介绍了使用Cadence Sigrity PowerSI进行信号完整性分析的完整流程,从.brd文件预处理到S参数提取的关键技巧。通过实战案例和避坑指南,帮助工程师高效解决高速PCB设计中的信号质量问题,提升仿真精度和设计效率。

carrot的博客 694

SpringCloud+Vue+Python人工智能(fastAPI,机器学习,深度学习)前后端架构各功能实现思路——SpringCloud后端——Gateway网关

【代码】SpringCloud+Vue+Python人工智能(fastAPI,机器学习,深度学习)前后端架构各功能实现思路——SpringCloud后端——Gateway网关。

殷志鹏的博客 1204

【网络图】:附Origin详细画图教程

网络图,是一种由节点(或顶点)和连接这些节点的边(或链路)组成的图形结构。在网络图中,节点通常代表系统中的一个实体(如项目中的一项任务、通信网络中的一个设备、或运输网络中的一个站点),而边则代表这些实体之间的直接联系或流动(如任务的先后顺序、数据的传输路径、或乘客的旅行路线)。 有向图:如果边具有方向性,即从一个节点指向另一个节点,则称为有向图。这种图常用于表示具有明确先后顺序或方向性的系统,如项目管理中的任务依赖关系。 无向图:如果图中的边没有方向,则称为无向图。它适用于表示实体间相互关联但无明确方向性的

weixin_50236590的博客 3954

深入解析Uplift模型评估:AUUC指标的计算与应用

本文深入解析了Uplift模型评估的核心指标AUUC。针对传统响应模型无法区分用户真实转化动因的痛点,AUUC通过量化模型对用户增益(Uplift)的排序能力,有效衡量营销干预的增量收益。文章详细拆解了AUUC的计算逻辑,从构建Qini曲线到Python代码实战,并强调了其在预算约束下的精准营销等场景的应用价值与常见陷阱。

weixin_29254029的博客 475

SpringCloud集成Python-web服务

SpringCloud集成Python-web服务 对于springcloud集成python的web服务刚开始也没头绪,于是就翻官方文档,当然官网文档说的是相当笼统,具体链接奉上: 19.Polyglot support with Sidecar ,看19小节即可,看完后就决定自己摸一下喽,没想到可以实现,哈哈。好了不废话了直接说整体,我们公司需求就是讲python的web服务集成到spri...

试验ing 3411

MTK PE+2.0介绍

  PE+2.0介绍:   1.      PE+2.0的状态机: 2.      升压波形协议及编码规则: PE+2.0软件设计:   在充电器类型为标充且底层电量SOC在1%—95%之间时,开始PE+2.0升压充电器的检测:首先将VBUSreset至5V,之后发送8.5的current pattern再获取此时VBUS电压和8.5V比较,若其与8.5的差值绝对值在0.5之...

raydom07的博客 1万+

SpringCloud+Vue+Python人工智能(fastAPI,机器学习,深度学习)前后端架构各功能实现思路——SpringCloud后端——登录,网关统一鉴权

【代码】SpringCloud+Vue+Python人工智能(fastAPI,机器学习,深度学习)前后端架构各功能实现思路——SpringCloud后端——登录,网关统一鉴权。

殷志鹏的博客 1033

计算机网络基础:揭开网络世界的神秘面纱

计算机网络基础:揭开网络世界的神秘面纱,计算机网络已深度融入现代生活,这篇文章对其基础内容展开全面阐述。开篇介绍计算机网络的定义,说明其由计算机设备、网络设备和传输介质构成。接着从地域范围和拓扑结构两个维度对计算机网络进行分类,并详细讲解 OSI 和 TCP/IP 参考模型,明晰各层功能与联系。随后阐述网络通信协议的定义及常见协议,如 TCP/IP、HTTP 等。最后聚焦网络安全,涵盖定义、重要性以及防火墙、加密技术等常用安全技术。文章旨在帮助读者构建计算机网络基础知识体系,理解其在生活和工作中的应用与价值

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 6万+

TurboQuant: Online Vector Quantization with Near-optimal Distortion Rate

这篇被 ICLR 2026 接收的论文提出了一种名为TurboQuant的全新在线向量量化(Vector Quantization, VQ)算法。该研究的核心目标是解决大语言模型(LLM)在长上下文推理时面临的 KV Cache 显存消耗瓶颈,以及大规模向量数据库在近似最近邻检索中的存储与延迟问题。有别于现有技术,TurboQuant 是一种无需任何校准数据、无需训练的在线算法(Data-oblivious)。

c_cpp_csharp的专栏 118

SpringCloud+Vue+Python人工智能(fastAPI,机器学习,深度学习)前后端架构各功能实现思路——SpringCloud后端——Sa-Token实现Security权限管理

【代码】SpringCloud+Vue+Python人工智能(fastAPI,机器学习,深度学习)前后端架构各功能实现思路——SpringCloud后端——Sa-Token实现Security权限管理。

殷志鹏的博客 936

【学习系列】SAP RAP 16:RAP应用部署集成至Fiori Launchpad 【On-Premise】

本文详细介绍了如何将开发完成的RAP应用部署到S4HANA 2023 On-Premise环境并集成到Fiori Launchpad的完整流程。主要内容包括:1)通过ADT工具创建Fiori项目并配置外部IDE(VSCode);2)使用npm命令部署应用到系统;3)通过事务代码创建语义对象、磁贴目录和目标映射;4)配置PFCG角色分配;5)补充了部署失败解决方案、翻译问题处理、自定义主题设置以及登录页面LOGO修改等内容。文章提供了step-by-step的操作指南,帮助开发者将预览模式的应用正式部署到生产

DeveloperMrMeng的博客 633

[转载]基于 Spring Boot、Spring Cloud、Spring Oauth2 和 Spring Cloud Netflix 等框架构建的微服务项目

基于 Spring Cloud 的微服务架构本项目是一个基于 Spring Boot、Spring Cloud、Spring Oauth2 和 Spring Cloud Netflix 等框架构建的微服务项目。技术栈Spring boot - 微服务的入门级微框架,用来简化 Spring 应用的初始搭建以及开发过程。 Eureka - 云端服务发现,一个基于 REST 的服务,用于定位服务,以实现

zhouxiaoxiao的专栏 998

YOLO26 实例分割技术:Mask 分支与特征融合

YOLO26实例分割技术研究摘要:本文提出了一种基于YOLO架构的高效实例分割方法,通过创新设计Mask分支和特征融合策略解决像素级分割精度、多尺度目标处理等挑战。系统采用共享Backbone提取特征,检测分支输出边界框和类别,Mask分支生成原型Mask和组合系数。核心创新包括:1)原型Mask生成与线性组合机制;2)检测与Mask特征共享;3)结合BCE和Dice的多任务损失函数。实验表明该方法在保持实时性的同时实现了高质量分割,为轻量级实例分割提供了新思路。

一键难忘的博客 248

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

SpringCloud + Python 混合微服务架构,打造AI分布式应用的技术底层

SpringCloud + Python 混合微服务架构,打造AI分布式应用的技术底层

安静的软件工程师 2583

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

(1)SpringCloud 整合Python

引言 什么是sidecar 1 Polyglot支持Sidecar官网描述 11 使用Sidecar步骤 12 Java调用非JVM程序接口 13 非JVM接口调用Java接口 2 Sidecar总结 Python和SpringCloud整合实例 1 定义Python服务 2 定义SpringCloud注册中心 3 定义sidecar 4 定义Java服务 5 服务相互调用 51 调用Java原生服

王培晓Carpenter 1万+

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

springcloud 文件上传 is not a type supported by this encoder

在服务消费方添加依赖 <dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form</artifactId> <version>3.0.3</version> </dependency&gt...

weixin_43724508的博客 4166

6 款电商 AI 图片生成软件实测|国内 + 跨境卖家工具清单

电商 AI 作图工具已经从 "能不能用" 进入了 "好不好用" 的阶段。对于绝大多数卖家而言,现在的 AI 工具已经可以覆盖 60%-80% 的基础商品图需求,显著降低拍摄和设计成本。选择工具的核心逻辑不是 "哪款最强",而是 "哪款最适配你的品类、平台规模和团队能力"。垂直电商工具胜在工作流效率,通用生图工具强在创意上限,模板类工具赢在上手速度。建议根据自身业务阶段,搭配 1-2 款主力工具 + 1 款辅助工具,形成适合自己的视觉生产流程。

Mardi_Ladin的博客 361

视频隐私脱敏工程化:CSRT/KCF追踪算法在本地推理中的实现与边界

在短视频内容合规审查中,动态遮挡(Dynamic Masking)是高频且高耗时的环节。传统手动关键帧打码不仅效率低下,且在目标快速移动或遮挡时极易出现遮罩漂移。本文从计算机视觉工程角度,解析基于CSRT与KCF算法的目标追踪方案在视频隐私处理中的技术路径、性能权衡及落地实践。

Mysssone的博客 201

我用 GPUWorks 在 M1 Pro 上搭了个发票识别原型

公司里经常要看电子发票。我想先做个小原型:把 PDF 发给一个自己部署的图文模型,让它提取发票类型、日期、交易双方和金额,再把结果交给同事核对。这个原型不用先接财务系统,先看看从部署到调用要走多少步,模型返回的内容能不能帮上忙。

鸽芷咕的博客 2万+

您您这可以把问小白的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。AI导出鸭

第三层是格式编译层。这个决策背后的判断很清晰:一个批量导出工具的价值,不在于“试三次”,而在于你真正用它处理了几十份技术文档、访谈记录或课程讲义之后,它是否值得留在你的工作流里。问小白的会话列表通过分页接口加载,AI导出鸭 在页面运行时建立旁路监听,捕获每一次分页请求返回的完整对话清单,包括会话 ID、标题、时间戳和隐藏的元数据字段。让AI导出回归优雅——这句话说的是:导出不该是体力活,而应该是一次完整的、可预期的文件交付。注意:这里的“批量”指的是左侧列表里的多个独立会话,不是一条会话内的多轮对话。

laoyunsi的博客 238

医疗 AI 有两种,别混着谈:一个改流程,一个改范式

InfoXMed 是面向医生、医学生和医学科研人员的 AI 医学工具平台,提供文献检索、全文翻译、AI 解读、指南查询和题库练习等功能,辅助临床学习、科研汇报与医学备考。原文是日本医学会杂志(JMA Journal)的一篇综述(Review Article):基本事实:这一点必须先说清:这篇论文提出的是一个研究纲领。它文中的"预测"指的是科学设想,不是可以拿来用的临床预测能力。文中甚至自己承认了一个硬缺口(见第三节)。本文只谈它的术语辨析与科学方法论,不转述任何可作为临床依据的预测或处置主张。这篇论文的全部

2601_96948740的博客 241

河道漂浮物目标检测数据集

目标检测,yolo,河道漂浮物目标检测数据集

DL_data_set的博客 195

AI Agent之核心框架

A: 显式 Thought 有三类价值:可解释性(便于人类审计)、可调试性(定位哪一步选错工具)、学习信号(可做监督微调或评估中间步骤质量)。ReAct 把推理与 可执行行动 绑定,每一步行动后都有 真实 Observation 反馈,从而用工具结果约束生成,降低闭卷幻觉。做完不等于结束——还要 评估做得好不好,把 教训 记下来,下次 带着教训重试,反思作为 记忆,影响后续尝试的策略。工作流程:Action → Evaluation → Reflection → Retry。A: 普通 CoT 只在。

剑雨巍巍的博客 195

AI 应用开发工程师技术实践:大模型接入、通用组件封装与性能优化

本文提出AI应用从PoC到生产的核心挑战:模型调用的持续可用、可控与可优化。通过构建统一LLM网关实现多供应商路由与故障转移,封装对话、工具调用与RAG组件以解耦业务逻辑,结合前缀缓存、批处理与流式背压治理等性能优化手段,形成“接通→接稳→接快”的工程路径,最终以工程化能力决定AI应用的生产可用性。

2301_79189962的博客 550
上一篇: SpringCloud+Vue+Python人工智能(fastAPI,机器学习,深度学习)前后端架构各功能实现思路——SpringCloud后端——登录,网关统一鉴权
下一篇: SpringCloud+Vue+Python人工智能(fastAPI,机器学习,深度学习)前后端架构各功能实现思路——Vue3.0前后端分离架构——后台系统前端环境搭建
ydenergy_殷志鹏
博客等级 码龄7年 5885粉丝 543原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ydenergy_殷志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值