L13_若依数据权限
作业

参考
抄了部分:https://blog.csdn.net/2301_80194233/article/details/155482968?spm=1011.2415.3001.5331
正文 作业1
菜单权限

部门权限

超级管理员下的权限

普通角色的权限

数据库SQL语句位置

整体框架上的作用
例子代码
@Before("@annotation(controllerDataScope)") // 拦截所有标记了@DataScope注解的方法
public void doBefore(JoinPoint point, DataScope controllerDataScope) {
clearDataScope(point); // 清空,防止SQL注入
handleDataScope(point, controllerDataScope); // 再添加真正的权限SQL
}
标签汇总
| 常量 | 值 | 含义 | SQL效果 |
|---|---|---|---|
DATA_SCOPE_ALL |
"1" | 全部数据权限 | 查询所有的数据 |
DATA_SCOPE_CUSTOM |
"2" | 自定义数据权限 | 可设置权限,查询指定的内容 |
DATA_SCOPE_DEPT |
"3" | 本部门数据权限 | 只看自己部门 |
DATA_SCOPE_DEPT_AND_CHILD |
"4" | 本部门及以下权限 | 看自己和所有子部门 |
DATA_SCOPE_SELF |
"5" | 仅本人数据权限 | 只看自己创建的数据 |
权限判断
DATA_SCOPE_ALL
点击查看代码
if (DATA_SCOPE_ALL.equals(dataScope))
{
sqlString = new StringBuilder(); // 全部清空
conditions.add(dataScope);
break; // 不执行后面的权限判断
}
DATA_SCOPE_CUSTOM
收集用户ID确认权限
user.getRoles().forEach(role -> {
if (DATA_SCOPE_CUSTOM.equals(role.getDataScope())
&& role是正常的
&& 角色包含所需权限字符) {
scopeCustomIds.add(role.getRoleId().toString());
}
});
生成查询SQL
if (scopeCustomIds.size() > 1)
{
// 多个自定数据权限使用in查询,避免多次拼接。
sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id in ({}) ) ", deptAlias, String.join(",", scopeCustomIds)));
}
else
{
sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, role.getRoleId()));
}
AND (u.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id IN (1, 2) ))
查询sys_role_dept关联表:这个角色能看哪些部门?
把查出来的部门ID列表,作为IN条件过滤主表数据
DATA_SCOPE_DEPT
点击查看代码
else if (DATA_SCOPE_DEPT.equals(dataScope))
{
sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
}
AND (u.dept_id = 105)
只看dept_id等于自己部门ID的数据
DATA_SCOPE_DEPT_AND_CHILD
点击查看代码
else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
{
sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
deptAlias, user.getDeptId(), user.getDeptId()));
}
AND (u.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = 105 OR find_in_set(105, ancestors) ))
查询结果示例:
| dept_id | dept_name | ancestors |
|---|---|---|
| 100 | 总公司 | 0 |
| 105 | 研发部 | 0,100 |
| 106 | 后端组 | 0,100,105 |
| 107 | 前端组 | 0,100,105 |
DATA_SCOPE_SELF
点击查看代码
else if (DATA_SCOPE_SELF.equals(dataScope))
{
if (StringUtils.isNotBlank(userAlias)) {
// 正常情况:过滤user_id
sqlString.append(" OR {}.user_id = {} ", userAlias, user.getUserId());
} else {
// 异常情况:开发者没配userAlias,直接查空数据,保护隐私
sqlString.append(" OR {}.dept_id = 0 ", deptAlias);
}
}
最终拼接语句
点击查看代码
if (StringUtils.isNotBlank(sqlString.toString()))
{
Object params = joinPoint.getArgs()[0];
if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
{
BaseEntity baseEntity = (BaseEntity) params;
baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
}
}
substring(4):循环中每个条件都是 OR xxx,第一个" OR "没用,需要砍掉。
拼接过程
// 循环第一个角色(自定义)
sqlString = " OR u.dept_id IN (SELECT...)"
// 循环第二个角色(仅本人)
sqlString = " OR u.dept_id IN (SELECT...) OR u.user_id = 1001"
// 最终处理
" AND (" + " OR u.dept_id IN (SELECT...) OR u.user_id = 1001".substring(4) + ")"
// 结果:
" AND (u.dept_id IN (SELECT...) OR u.user_id = 1001)"
流程
流程
用户请求
↓
@DataScope注解触发AOP
↓
获取当前登录用户
↓
是超级管理员? → 是 → SQL = "" → 直接放行
↓ 否
遍历用户的所有角色
↓
根据dataScope类型拼接SQL
├─ 1: 清空SQL,break
├─ 2: dept_id IN (SELECT dept_id FROM sys_role_dept...)
├─ 3: dept_id = 用户部门ID
├─ 4: dept_id IN (SELECT...find_in_set...)
└─ 5: user_id = 用户ID (或 dept_id = 0)
↓
把SQL塞进params.dataScope
↓
Mybatis XML中 ${params.dataScope} 动态执行
↓
返回过滤后的数据
正文 作业2
sql语句
点击查看代码
-- ----------------------------
-- 车间设备管理表
-- ----------------------------
DROP TABLE IF EXISTS `mes_workshop_device`;
CREATE TABLE `mes_workshop_device` (
`device_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '设备ID',
`device_code` varchar(64) NOT NULL COMMENT '设备编号(如:LiuYi_001)',
`device_name` varchar(50) NOT NULL COMMENT '设备名称',
`device_type` varchar(30) DEFAULT '' COMMENT '设备类型(加工设备、检测设备、辅助设备)',
`workshop_id` bigint(20) NOT NULL COMMENT '所属车间ID',
`workshop_name` varchar(50) DEFAULT '' COMMENT '所属车间名称',
`device_status` char(1) DEFAULT '0' COMMENT '设备状态(0正常 1停机 2维修 3报废)',
`device_model` varchar(100) DEFAULT '' COMMENT '设备型号',
`manufacturer` varchar(100) DEFAULT '' COMMENT '生产厂家',
`purchase_date` datetime DEFAULT NULL COMMENT '购买日期',
`price` decimal(10,2) DEFAULT '0.00' COMMENT '设备价格(万元)',
`remark` varchar(500) DEFAULT '' COMMENT '备注',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`device_id`),
UNIQUE KEY `device_code` (`device_code`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='车间设备管理表';
-- ----------------------------
-- 插入示例数据(帮你测试)
-- ----------------------------
INSERT INTO `mes_workshop_device` VALUES
(1, 'LiuYi_001', '数控车床CNC-01', '加工设备', 101, '一车间', '0', 'CK-6140', '沈阳机床', '2023-03-15', 25.50, '精加工设备', '0', 'admin', '2024-01-10 10:00:00', 'admin', '2024-01-10 10:00:00'),
(2, 'LiuYi_002', '数控车床CNC-02', '加工设备', 101, '一车间', '1', 'CK-6140', '沈阳机床', '2023-03-15', 25.50, '精加工设备', '0', 'admin', '2024-01-10 10:30:00', 'admin', '2024-01-10 10:30:00'),
(3, 'LiuYi_003', '三坐标测量仪', '检测设备', 102, '二车间', '0', 'CMM-665', '海克斯康', '2024-01-20', 45.80, '精度检测', '0', 'admin', '2024-01-20 14:00:00', 'admin', '2024-01-20 14:00:00');
复制粘贴数据库执行

表创建完成,把表导入代码生成一键生成,作业完成
手写代码——后端
创建一个模块


将模块添加到ruoyi下进行管理
在主目录的pom文件下添加

在ruoyi-admin的pom文件下添加

添加完成后刷新maven
实体类:MesWorkshopDevice.java
路径:com.ruoyi.mes.domain.MesWorkshopDevice
创建java类


编写代码
点击查看代码
public class MesWorkshopDevice extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 设备ID */
private Long deviceId;
/** 设备编号(如:LiuYi_001) */
@Excel(name = "设备编号")
private String deviceCode;
/** 设备名称 */
@Excel(name = "设备名称")
private String deviceName;
/** 设备类型 */
@Excel(name = "设备类型")
private String deviceType;
/** 所属车间ID */
private Long workshopId;
/** 所属车间名称 */
@Excel(name = "所属车间")
private String workshopName;
/** 设备状态(0正常 1停机 2维修 3报废) */
@Excel(name = "设备状态", readConverterExp = "0=正常,1=停机,2=维修,3=报废")
private String deviceStatus;
/** 设备型号 */
@Excel(name = "设备型号")
private String deviceModel;
/** 生产厂家 */
@Excel(name = "生产厂家")
private String manufacturer;
/** 购买日期 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "购买日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date purchaseDate;
/** 设备价格(万元) */
@Excel(name = "设备价格(万元)")
private BigDecimal price;
/** 备注 */
@Excel(name = "备注")
private String remark;
/** 删除标志(0代表存在 2代表删除) */
private String delFlag;
不使用@Data,快捷键Alt+F12,生成getter和setter

Alt+F12,生成toString()

Mapper接口:MesWorkshopDeviceMapper.java
路径:com.ruoyi.mes.mapper.MesWorkshopDeviceMapper
代码
点击查看代码
@Mapper
public interface MesWorkshopDeviceMapper
{
/**
* 查询车间设备管理
*
* @param deviceId 车间设备管理主键
* @return 车间设备管理
*/
public MesWorkshopDevice selectMesWorkshopDeviceByDeviceId(Long deviceId);
/**
* 根据设备编号查询
*
* @param deviceCode 设备编号
* @return 车间设备管理
*/
public MesWorkshopDevice selectMesWorkshopDeviceByDeviceCode(String deviceCode);
/**
* 查询车间设备管理列表
*
* @param mesWorkshopDevice 车间设备管理
* @return 车间设备管理集合
*/
public List<MesWorkshopDevice> selectMesWorkshopDeviceList(MesWorkshopDevice mesWorkshopDevice);
/**
* 新增车间设备管理
*
* @param mesWorkshopDevice 车间设备管理
* @return 结果
*/
public int insertMesWorkshopDevice(MesWorkshopDevice mesWorkshopDevice);
/**
* 修改车间设备管理
*
* @param mesWorkshopDevice 车间设备管理
* @return 结果
*/
public int updateMesWorkshopDevice(MesWorkshopDevice mesWorkshopDevice);
/**
* 删除车间设备管理
*
* @param deviceId 车间设备管理主键
* @return 结果
*/
public int deleteMesWorkshopDeviceByDeviceId(Long deviceId);
/**
* 批量删除车间设备管理
*
* @param deviceIds 需要删除的数据主键集合
* @return 结果
*/
public int deleteMesWorkshopDeviceByDeviceIds(Long[] deviceIds);
}
Mapper XML:MesWorkshopDeviceMapper.xml
路径:src/main/resources/mapper/mes/MesWorkshopDeviceMapper.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.ruoyi.mes.mapper.MesWorkshopDeviceMapper">
<!-- 结果映射 -->
<resultMap type="com.ruoyi.mes.domain.MesWorkshopDevice" id="MesWorkshopDeviceResult">
<result property="deviceId" column="device_id" />
<result property="deviceCode" column="device_code" />
<result property="deviceName" column="device_name" />
<result property="deviceType" column="device_type" />
<result property="workshopId" column="workshop_id" />
<result property="workshopName" column="workshop_name" />
<result property="deviceStatus" column="device_status" />
<result property="deviceModel" column="device_model" />
<result property="manufacturer" column="manufacturer" />
<result property="purchaseDate" column="purchase_date" />
<result property="price" column="price" />
<result property="remark" column="remark" />
<result property="delFlag" column="del_flag" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<!-- 根据ID查询 -->
<sql id="selectMesWorkshopDeviceVo">
select device_id, device_code, device_name, device_type, workshop_id, workshop_name, device_status, device_model, manufacturer, purchase_date, price, remark, del_flag, create_by, create_time, update_by, update_time from mes_workshop_device
</sql>
<!-- 查询单个 -->
<select id="selectMesWorkshopDeviceByDeviceId" parameterType="Long" resultMap="MesWorkshopDeviceResult">
<include refid="selectMesWorkshopDeviceVo"/>
where device_id = #{deviceId}
</select>
<!-- 根据设备编号查询 -->
<select id="selectMesWorkshopDeviceByDeviceCode" parameterType="String" resultMap="MesWorkshopDeviceResult">
<include refid="selectMesWorkshopDeviceVo"/>
where device_code = #{deviceCode}
</select>
<!-- 查询列表(核心:数据权限在此生效) -->
<select id="selectMesWorkshopDeviceList" parameterType="com.ruoyi.mes.domain.MesWorkshopDevice" resultMap="MesWorkshopDeviceResult">
select device_id, device_code, device_name, device_type, workshop_id, workshop_name, device_status, device_model, manufacturer, purchase_date, price, remark, del_flag, create_by, create_time, update_by, update_time
from mes_workshop_device d
where d.del_flag = '0'
<!-- 设备编号 -->
<if test="deviceCode != null and deviceCode != ''">
and d.device_code like concat('%', #{deviceCode}, '%')
</if>
<!-- 设备名称 -->
<if test="deviceName != null and deviceName != ''">
and d.device_name like concat('%', #{deviceName}, '%')
</if>
<!-- 设备类型 -->
<if test="deviceType != null and deviceType != ''">
and d.device_type = #{deviceType}
</if>
<!-- 所属车间 -->
<if test="workshopId != null">
and d.workshop_id = #{workshopId}
</if>
<!-- 设备状态 -->
<if test="deviceStatus != null and deviceStatus != ''">
and d.device_status = #{deviceStatus}
</if>
<!-- 数据权限:这里的d别名要和@DataScope(deptAlias="d")保持一致 -->
${params.dataScope}
</select>
<!-- 新增 -->
<insert id="insertMesWorkshopDevice" parameterType="com.ruoyi.mes.domain.MesWorkshopDevice" useGeneratedKeys="true" keyProperty="deviceId">
insert into mes_workshop_device
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="deviceCode != null">device_code,</if>
<if test="deviceName != null">device_name,</if>
<if test="deviceType != null">device_type,</if>
<if test="workshopId != null">workshop_id,</if>
<if test="workshopName != null">workshop_name,</if>
<if test="deviceStatus != null">device_status,</if>
<if test="deviceModel != null">device_model,</if>
<if test="manufacturer != null">manufacturer,</if>
<if test="purchaseDate != null">purchase_date,</if>
<if test="price != null">price,</if>
<if test="remark != null">remark,</if>
<if test="delFlag != null">del_flag,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="deviceCode != null">#{deviceCode},</if>
<if test="deviceName != null">#{deviceName},</if>
<if test="deviceType != null">#{deviceType},</if>
<if test="workshopId != null">#{workshopId},</if>
<if test="workshopName != null">#{workshopName},</if>
<if test="deviceStatus != null">#{deviceStatus},</if>
<if test="deviceModel != null">#{deviceModel},</if>
<if test="manufacturer != null">#{manufacturer},</if>
<if test="purchaseDate != null">#{purchaseDate},</if>
<if test="price != null">#{price},</if>
<if test="remark != null">#{remark},</if>
<if test="delFlag != null">#{delFlag},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
</trim>
</insert>
<!-- 修改 -->
<update id="updateMesWorkshopDevice" parameterType="com.ruoyi.mes.domain.MesWorkshopDevice">
update mes_workshop_device
<trim prefix="SET" suffixOverrides=",">
<if test="deviceCode != null">device_code = #{deviceCode},</if>
<if test="deviceName != null">device_name = #{deviceName},</if>
<if test="deviceType != null">device_type = #{deviceType},</if>
<if test="workshopId != null">workshop_id = #{workshopId},</if>
<if test="workshopName != null">workshop_name = #{workshopName},</if>
<if test="deviceStatus != null">device_status = #{deviceStatus},</if>
<if test="deviceModel != null">device_model = #{deviceModel},</if>
<if test="manufacturer != null">manufacturer = #{manufacturer},</if>
<if test="purchaseDate != null">purchase_date = #{purchaseDate},</if>
<if test="price != null">price = #{price},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="delFlag != null">del_flag = #{delFlag},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where device_id = #{deviceId}
</update>
<!-- 删除(逻辑删除) -->
<delete id="deleteMesWorkshopDeviceByDeviceId" parameterType="Long">
update mes_workshop_device set del_flag = '2' where device_id = #{deviceId}
</delete>
<!-- 批量删除 -->
<delete id="deleteMesWorkshopDeviceByDeviceIds" parameterType="Long">
update mes_workshop_device set del_flag = '2' where device_id in
<foreach collection="array" item="deviceId" open="(" separator="," close=")">
#{deviceId}
</foreach>
</delete>
<!-- 检查设备编号是否唯一 -->
<select id="checkDeviceCodeUnique" resultType="int">
select count(*) from mes_workshop_device where device_code = #{deviceCode} and del_flag = '0' limit 1
</select>
</mapper>
- d别名:要和后面Controller的@DataScope(deptAlias = "d")保持一致
- ${params.dataScope}:数据权限SQL插入口,AOP就是往这塞SQL
- 逻辑删除:update set del_flag = '2',不是真删
Service接口:IMesWorkshopDeviceService.java
路径:com.ruoyi.mes.service.IMesWorkshopDeviceService
代码
点击查看代码
public interface IMesWorkshopDeviceService
{
/**
* 查询车间设备管理
* @param deviceId 车间设备管理主键
* @return 车间设备管理
*/
public MesWorkshopDevice selectMesWorkshopDeviceByDeviceId(Long deviceId);
/**
* 查询车间设备管理列表
* @param mesWorkshopDevice 车间设备管理
* @return 车间设备管理集合
*/
public List<MesWorkshopDevice> selectMesWorkshopDeviceList(MesWorkshopDevice mesWorkshopDevice);
/**
* 新增车间设备管理
* @param mesWorkshopDevice 车间设备管理
* @return 结果
*/
public int insertMesWorkshopDevice(MesWorkshopDevice mesWorkshopDevice);
/**
* 修改车间设备管理
* @param mesWorkshopDevice 车间设备管理
* @return 结果
*/
public int updateMesWorkshopDevice(MesWorkshopDevice mesWorkshopDevice);
/**
* 批量删除车间设备管理
* @param deviceIds 需要删除的车间设备管理主键集合
* @return 结果
*/
public int deleteMesWorkshopDeviceByDeviceIds(Long[] deviceIds);
/**
* 删除车间设备管理信息
* @param deviceId 车间设备管理主键
* @return 结果
*/
public int deleteMesWorkshopDeviceByDeviceId(Long deviceId);
/**
* 检查设备编号唯一性
*/
public String checkDeviceCodeUnique(MesWorkshopDevice mesWorkshopDevice);
}
Service实现类:MesWorkshopDeviceServiceImpl.java
路径:com.ruoyi.mes.service.impl.MesWorkshopDeviceServiceImpl
代码
点击查看代码
@Service
public class MesWorkshopDeviceServiceImpl implements IMesWorkshopDeviceService
{
@Autowired
private MesWorkshopDeviceMapper mesWorkshopDeviceMapper;
/**
* 查询车间设备管理
*
* @param deviceId 车间设备管理主键
* @return 车间设备管理
*/
@Override
public MesWorkshopDevice selectMesWorkshopDeviceByDeviceId(Long deviceId)
{
return mesWorkshopDeviceMapper.selectMesWorkshopDeviceByDeviceId(deviceId);
}
/**
* 查询车间设备管理列表
*
* @param mesWorkshopDevice 车间设备管理
* @return 车间设备管理
*/
@Override
public List<MesWorkshopDevice> selectMesWorkshopDeviceList(MesWorkshopDevice mesWorkshopDevice)
{
return mesWorkshopDeviceMapper.selectMesWorkshopDeviceList(mesWorkshopDevice);
}
/**
* 新增车间设备管理
*
* @param mesWorkshopDevice 车间设备管理
* @return 结果
*/
@Override
public int insertMesWorkshopDevice(MesWorkshopDevice mesWorkshopDevice)
{
return mesWorkshopDeviceMapper.insertMesWorkshopDevice(mesWorkshopDevice);
}
/**
* 修改车间设备管理
*
* @param mesWorkshopDevice 车间设备管理
* @return 结果
*/
@Override
public int updateMesWorkshopDevice(MesWorkshopDevice mesWorkshopDevice)
{
return mesWorkshopDeviceMapper.updateMesWorkshopDevice(mesWorkshopDevice);
}
/**
* 批量删除车间设备管理
*
* @param deviceIds 需要删除的车间设备管理主键
* @return 结果
*/
@Override
public int deleteMesWorkshopDeviceByDeviceIds(Long[] deviceIds)
{
return mesWorkshopDeviceMapper.deleteMesWorkshopDeviceByDeviceIds(deviceIds);
}
/**
* 删除车间设备管理信息
*
* @param deviceId 车间设备管理主键
* @return 结果
*/
@Override
public int deleteMesWorkshopDeviceByDeviceId(Long deviceId)
{
return mesWorkshopDeviceMapper.deleteMesWorkshopDeviceByDeviceId(deviceId);
}
/**
* 检查设备编号是否唯一
*/
@Override
public boolean checkDeviceCodeUnique(MesWorkshopDevice mesWorkshopDevice) {
Long deviceId = StringUtils.isNull(mesWorkshopDevice.getDeviceId()) ? -1L : mesWorkshopDevice.getDeviceId();
MesWorkshopDevice info = mesWorkshopDeviceMapper.selectMesWorkshopDeviceByDeviceCode(mesWorkshopDevice.getDeviceCode());
if (StringUtils.isNotNull(info) && info.getDeviceId().longValue() != deviceId.longValue()) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
}
Controller:MesWorkshopDeviceController.java
路径:com.ruoyi.mes.controller.MesWorkshopDeviceController
代码
点击查看代码
@RestController
@RequestMapping("/mes/device")
public class MesWorkshopDeviceController extends BaseController
{
@Autowired
private IMesWorkshopDeviceService mesWorkshopDeviceService;
/**
* 查询车间设备管理列表
*
* 数据权限说明:
* - 超级管理员:所有设备
* - 车间主任:本车间及子车间
* - 普通员工:仅本人
*/
@PreAuthorize("@ss.hasPermi('mes:device:list')")
@GetMapping("/list")
@DataScope(deptAlias = "d")
public TableDataInfo list(MesWorkshopDevice mesWorkshopDevice)
{
startPage();
List<MesWorkshopDevice> list = mesWorkshopDeviceService.selectMesWorkshopDeviceList(mesWorkshopDevice);
return getDataTable(list);
}
/**
* 导出车间设备管理列表
*/
@PreAuthorize("@ss.hasPermi('mes:device:export')")
@Log(title = "车间设备管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, MesWorkshopDevice mesWorkshopDevice)
{
List<MesWorkshopDevice> list = mesWorkshopDeviceService.selectMesWorkshopDeviceList(mesWorkshopDevice);
ExcelUtil<MesWorkshopDevice> util = new ExcelUtil<MesWorkshopDevice>(MesWorkshopDevice.class);
util.exportExcel(response, list, "车间设备管理数据");
}
/**
* 获取车间设备管理详细信息
*/
@PreAuthorize("@ss.hasPermi('mes:device:query')")
@GetMapping(value = "/{deviceId}")
public AjaxResult getInfo(@PathVariable("deviceId") Long deviceId)
{
return success(mesWorkshopDeviceService.selectMesWorkshopDeviceByDeviceId(deviceId));
}
/**
* 新增车间设备管理
*/
@PreAuthorize("@ss.hasPermi('mes:device:add')")
@Log(title = "车间设备管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody MesWorkshopDevice mesWorkshopDevice)
{
// 校验设备编号唯一性
if (!mesWorkshopDeviceService.checkDeviceCodeUnique(mesWorkshopDevice)){
return error("新增设备失败,设备编号'" + mesWorkshopDevice.getDeviceCode() + "'已存在");
}
mesWorkshopDevice.setCreateBy(getUsername());
return toAjax(mesWorkshopDeviceService.insertMesWorkshopDevice(mesWorkshopDevice));
}
/**
* 修改车间设备管理
*/
@PreAuthorize("@ss.hasPermi('mes:device:edit')")
@Log(title = "车间设备管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody MesWorkshopDevice mesWorkshopDevice)
{
// 校验设备编号唯一性(排除自己)
if (!mesWorkshopDeviceService.checkDeviceCodeUnique(mesWorkshopDevice)){
return error("修改设备失败,设备编号'" + mesWorkshopDevice.getDeviceCode() + "'已存在");
}
mesWorkshopDevice.setUpdateBy(getUsername());
return toAjax(mesWorkshopDeviceService.updateMesWorkshopDevice(mesWorkshopDevice));
}
/**
* 删除车间设备管理
*/
@PreAuthorize("@ss.hasPermi('mes:device:remove')")
@Log(title = "车间设备管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{deviceIds}")
public AjaxResult remove(@PathVariable Long[] deviceIds)
{
return toAjax(mesWorkshopDeviceService.deleteMesWorkshopDeviceByDeviceIds(deviceIds));
}
}
手写代码——后台前端
创建API文件
路径:ruoyi-ui\src\api\mes\device.js
代码
点击查看代码
import request from '@/utils/request'
// 基础URL,对应你的Controller的@RequestMapping("/mes/device")
const baseURL = '/mes/device'
// 查询设备列表
export function listDevice(query) {
return request({
url: `${baseURL}/list`,
method: 'get',
params: query
})
}
// 查询设备详情
export function getDevice(deviceId) {
return request({
url: `${baseURL}/${deviceId}`,
method: 'get'
})
}
// 新增设备
export function addDevice(data) {
return request({
url: baseURL,
method: 'post',
data: data
})
}
// 修改设备
export function updateDevice(data) {
return request({
url: baseURL,
method: 'put',
data: data
})
}
// 删除设备
export function delDevice(deviceIds) {
return request({
url: `${baseURL}/${deviceIds}`,
method: 'delete'
})
}
// 导出设备列表
export function exportDevice(query) {
return request({
url: `${baseURL}/export`,
method: 'post',
data: query,
responseType: 'blob' // 重要!导出用blob类型
})
}
前端Vue页面
路径:ruoyi-ui/src/views/mes/device/index.vue
代码
点击查看代码
<template>
<div class="app-container">
<!-- 搜索栏 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="设备编号" prop="deviceCode">
<el-input
v-model="queryParams.deviceCode"
placeholder="请输入设备编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="设备名称" prop="deviceName">
<el-input
v-model="queryParams.deviceName"
placeholder="请输入设备名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="设备状态" prop="deviceStatus">
<el-select v-model="queryParams.deviceStatus" placeholder="请选择设备状态" clearable>
<el-option label="正常" value="0" />
<el-option label="停机" value="1" />
<el-option label="维修" value="2" />
<el-option label="报废" value="3" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 按钮栏 -->
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['mes:device:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['mes:device:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['mes:device:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['mes:device:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<!-- 表格 -->
<el-table v-loading="loading" :data="deviceList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="设备ID" align="center" prop="deviceId" />
<el-table-column label="设备编号" align="center" prop="deviceCode" />
<el-table-column label="设备名称" align="center" prop="deviceName" />
<el-table-column label="设备类型" align="center" prop="deviceType" />
<el-table-column label="所属车间" align="center" prop="workshopName" />
<el-table-column label="设备状态" align="center" prop="deviceStatus">
<template slot-scope="scope">
<dict-tag :options="dict.type.mes_device_status" :value="scope.row.deviceStatus"/>
</template>
</el-table-column>
<el-table-column label="设备型号" align="center" prop="deviceModel" />
<el-table-column label="生产厂家" align="center" prop="manufacturer" />
<el-table-column label="购买日期" align="center" prop="purchaseDate" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.purchaseDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['mes:device:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['mes:device:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row>
<el-col :span="12">
<el-form-item label="设备编号" prop="deviceCode">
<el-input v-model="form.deviceCode" placeholder="请输入设备编号,如:LiuYi_001" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备名称" prop="deviceName">
<el-input v-model="form.deviceName" placeholder="请输入设备名称" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="设备类型" prop="deviceType">
<el-select v-model="form.deviceType" placeholder="请选择设备类型" style="width: 100%">
<el-option label="加工设备" value="加工设备" />
<el-option label="检测设备" value="检测设备" />
<el-option label="辅助设备" value="辅助设备" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属车间" prop="workshopId">
<treeselect v-model="form.workshopId" :options="workshopOptions" :normalizer="normalizer" placeholder="请选择所属车间" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="设备状态" prop="deviceStatus">
<el-select v-model="form.deviceStatus" placeholder="请选择设备状态" style="width: 100%">
<el-option label="正常" value="0" />
<el-option label="停机" value="1" />
<el-option label="维修" value="2" />
<el-option label="报废" value="3" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备型号" prop="deviceModel">
<el-input v-model="form.deviceModel" placeholder="请输入设备型号" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="生产厂家" prop="manufacturer">
<el-input v-model="form.manufacturer" placeholder="请输入生产厂家" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="购买日期" prop="purchaseDate">
<el-date-picker clearable
v-model="form.purchaseDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择购买日期"
style="width: 100%">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="设备价格" prop="price">
<el-input-number v-model="form.price" controls-position="right" :precision="2" :min="0" style="width: 100%"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listDevice, getDevice, delDevice, addDevice, updateDevice } from "@/api/mes/device";
import { treeselect } from "@/api/system/dept";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
name: "Device",
components: { Treeselect },
dicts: ['mes_device_status'],
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 车间设备管理表格数据
deviceList: [],
// 部门树选项
workshopOptions: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
deviceCode: null,
deviceName: null,
deviceStatus: null,
workshopId: null
},
// 表单参数
form: {},
// 表单校验
rules: {
deviceCode: [
{ required: true, message: "设备编号不能为空", trigger: "blur" },
{ pattern: /^[A-Z][a-zA-Z]*_\d{3}$/, message: "格式必须为:英文名_三位序号,如LiuYi_001", trigger: "blur" }
],
deviceName: [
{ required: true, message: "设备名称不能为空", trigger: "blur" }
],
workshopId: [
{ required: true, message: "请选择所属车间", trigger: "blur" }
],
deviceStatus: [
{ required: true, message: "请选择设备状态", trigger: "blur" }
]
}
};
},
created() {
this.getList();
this.getTreeselect();
},
methods: {
/** 查询车间设备管理列表 */
getList() {
this.loading = true;
listDevice(this.queryParams).then(response => {
this.deviceList = response.rows;
this.total = response.total;
this.loading = false;
});
},
/** 查询部门下拉树结构 */
getTreeselect() {
treeselect().then(response => {
this.workshopOptions = response.data;
});
},
/** 转换菜单数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.id,
label: node.label,
children: node.children
};
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
deviceId: null,
deviceCode: null,
deviceName: null,
deviceType: null,
workshopId: null,
workshopName: null,
deviceStatus: "0",
deviceModel: null,
manufacturer: null,
purchaseDate: null,
price: null,
remark: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.deviceId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加车间设备";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const deviceId = row.deviceId || this.ids[0];
getDevice(deviceId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改车间设备";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
// 根据车间ID填充车间名称
const selectedDept = this.workshopOptions.find(dept => dept.id === this.form.workshopId);
if (selectedDept) {
this.form.workshopName = selectedDept.label;
}
if (this.form.deviceId != null) {
updateDevice(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addDevice(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const deviceIds = row.deviceId || this.ids;
this.$modal.confirm('是否确认删除设备编号为"' + row.deviceCode + '"的数据项?').then(function() {
return delDevice(deviceIds);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有设备数据项?').then(() => {
this.exportLoading = true;
return exportDevice(queryParams);
}).then(response => {
this.$download.name(response.msg);
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>
前端要点:
- dicts: ['mes_device_status']:字典数据,在系统管理-字典管理里加mes_device_status字典
- 校验规则:deviceCode用正则/[1][a-zA-Z]*_\d{3}$/强制格式为"英文名_三位序号"
- @DataScope在后端的魔法 :前端无感知,后端自动过滤数据
- v-hasPermi:按钮级权限控制,没权限的人看不到按钮
后台操作
添加字典
位置 系统管理-字典管理
字典类型:mes_device_status
字典名称:设备状态
字典数据:
键值:0-标签:正常
键值:1-标签:停机
键值:2-标签:维修
键值:3-标签:报废
- 使用了 <dict-tag :options="dict.type.mes_device_status" ...>
- 需要在系统管理-字典管理里添加 mes_device_status 字典:
添加菜单
位置 系统管理-菜单管理
| 字段 | 值 | 说明 |
|---|---|---|
| 菜单名称 | 车间管理 | 一级菜单名称 |
| 父菜单 | 主目录 | 根级别 |
| 菜单类型 | 目录 | 用来放子菜单的文件夹 |
| 路由地址 | mes | /mes开头的都归它管 |
| 显示排序 | 5 | 数字越小越靠前 |
添加子菜单"设备管理"
位置 系统管理-菜单管理
| 字段 | 值 | 说明 |
|---|---|---|
| 菜单名称 | 设备管理 | 页面标题 |
| 父菜单 | 车间管理 | 上一步创建的目录 |
| 菜单类型 | 菜单 | 真正的页面 |
| 路由地址 | device | 完整路径将是 /mes/device |
| 组件路径 | mes/device/index | 对应 views/mes/device/index.vue |
| 权限字符 | mes:device:list | 和Controller的@PreAuthorize对应 |
| 显示状态 | 显示 | |
| 显示排序 | 1 | 在同级菜单中排第一 |
| 菜单图标 | fa fa-cog 或 el-icon-monitor |
随便选个设备相关的 |
添加按钮
位置 系统管理-菜单管理
| 字段 | 值 |
|---|---|
| 菜单名称 | 查询 |
| 父菜单 | 设备管理 |
| 菜单类型 | 按钮 |
| 权限字符 | mes:device:query |
| 字段 | 值 |
|---|---|
| 菜单名称 | 新增 |
| 父菜单 | 设备管理 |
| 菜单类型 | 按钮 |
| 权限字符 | mes:device:add |
| 字段 | 值 |
|---|---|
| 菜单名称 | 修改 |
| 父菜单 | 设备管理 |
| 菜单类型 | 按钮 |
| 权限字符 | mes:device:edit |
| 字段 | 值 |
|---|---|
| 菜单名称 | 删除 |
| 父菜单 | 设备管理 |
| 菜单类型 | 按钮 |
| 权限字符 | mes:device:remove |
| 字段 | 值 |
|---|---|
| 菜单名称 | 导出 |
| 父菜单 | 设备管理 |
| 菜单类型 | 按钮 |
| 权限字符 | mes:device:export |
菜单添加成功
手写了之后已经彻底忘记,作业是权限分配
权限添加
抄自:https://blog.csdn.net/2301_80194233/article/details/155482968?spm=1011.2415.3001.5331

抄自:https://blog.csdn.net/2301_80194233/article/details/155482968?spm=1011.2415.3001.5331

结束
感觉在自己给自己找罪受,写了5个多小时,现在存在一个问题,时间好像不够?
一个小作业可能需要半天一天来写
一周会增加3-6个小作业,要花掉2-3天的时间
大作业简单的一天,难的一个星期起步
最后的3周,目前出现4个大作业,预计还会增加3个大作业
A-Z ↩︎

浙公网安备 33010602011771号