Browse Source

数据权限

skyline 3 months ago
parent
commit
37750d39b0
29 changed files with 1122 additions and 0 deletions
  1. 1 0
      haha-admin-mp/src/pages.json
  2. 24 0
      haha-admin/src/main/java/com/haha/admin/annotation/RequirePermission.java
  3. 18 0
      haha-admin/src/main/java/com/haha/admin/annotation/SuperAdmin.java
  4. 136 0
      haha-admin/src/main/java/com/haha/admin/aspect/PermissionAspect.java
  5. 8 0
      haha-admin/src/main/java/com/haha/admin/controller/AdminController.java
  6. 17 0
      haha-admin/src/main/java/com/haha/admin/controller/AnnouncementController.java
  7. 5 0
      haha-admin/src/main/java/com/haha/admin/controller/DashboardController.java
  8. 78 0
      haha-admin/src/main/java/com/haha/admin/controller/DataPermissionController.java
  9. 6 0
      haha-admin/src/main/java/com/haha/admin/controller/DataSyncController.java
  10. 7 0
      haha-admin/src/main/java/com/haha/admin/controller/DeviceController.java
  11. 16 0
      haha-admin/src/main/java/com/haha/admin/controller/InventoryController.java
  12. 9 0
      haha-admin/src/main/java/com/haha/admin/controller/NewProductApplyController.java
  13. 8 0
      haha-admin/src/main/java/com/haha/admin/controller/OperationLogController.java
  14. 5 0
      haha-admin/src/main/java/com/haha/admin/controller/OrderController.java
  15. 8 0
      haha-admin/src/main/java/com/haha/admin/controller/ProductController.java
  16. 6 0
      haha-admin/src/main/java/com/haha/admin/controller/RoleController.java
  17. 21 0
      haha-admin/src/main/java/com/haha/admin/controller/ShopController.java
  18. 43 0
      haha-admin/src/main/java/com/haha/admin/service/impl/AdminLoginServiceImpl.java
  19. 131 0
      haha-admin/src/main/resources/sql/data_permission.sql
  20. 73 0
      haha-entity/src/main/java/com/haha/entity/DataPermission.java
  21. 38 0
      haha-entity/src/main/java/com/haha/entity/RolePermission.java
  22. 55 0
      haha-mapper/src/main/java/com/haha/mapper/DataPermissionMapper.java
  23. 45 0
      haha-mapper/src/main/java/com/haha/mapper/RolePermissionMapper.java
  24. 80 0
      haha-mapper/src/main/resources/mapper/DataPermissionMapper.xml
  25. 43 0
      haha-mapper/src/main/resources/mapper/RolePermissionMapper.xml
  26. 61 0
      haha-service/src/main/java/com/haha/service/DataPermissionService.java
  27. 15 0
      haha-service/src/main/java/com/haha/service/RoleService.java
  28. 115 0
      haha-service/src/main/java/com/haha/service/impl/DataPermissionServiceImpl.java
  29. 50 0
      haha-service/src/main/java/com/haha/service/impl/RoleServiceImpl.java

+ 1 - 0
haha-admin-mp/src/pages.json

@@ -107,6 +107,7 @@
 		"backgroundColor": "#f8fafc"
 		"backgroundColor": "#f8fafc"
 	},
 	},
 	"tabBar": {
 	"tabBar": {
+		"custom": true,
 		"color": "#94a3b8",
 		"color": "#94a3b8",
 		"selectedColor": "#10b981",
 		"selectedColor": "#10b981",
 		"backgroundColor": "#ffffff",
 		"backgroundColor": "#ffffff",

+ 24 - 0
haha-admin/src/main/java/com/haha/admin/annotation/RequirePermission.java

@@ -0,0 +1,24 @@
+package com.haha.admin.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 权限校验注解
+ * 用于Controller方法上,标注该方法需要的权限
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface RequirePermission {
+    
+    /**
+     * 权限编码
+     * 格式: module:operation,如 "product:create"
+     */
+    String value();
+    
+    /**
+     * 权限描述信息
+     */
+    String message() default "无操作权限";
+}

+ 18 - 0
haha-admin/src/main/java/com/haha/admin/annotation/SuperAdmin.java

@@ -0,0 +1,18 @@
+package com.haha.admin.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 超级管理员权限注解
+ * 用于标注仅超级管理员可访问的接口
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface SuperAdmin {
+    
+    /**
+     * 描述信息
+     */
+    String message() default "仅超级管理员可访问";
+}

+ 136 - 0
haha-admin/src/main/java/com/haha/admin/aspect/PermissionAspect.java

@@ -0,0 +1,136 @@
+package com.haha.admin.aspect;
+
+import cn.dev33.satoken.stp.StpUtil;
+import com.haha.admin.annotation.RequirePermission;
+import com.haha.admin.annotation.SuperAdmin;
+import com.haha.common.vo.Result;
+import com.haha.service.DataPermissionService;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 权限校验切面
+ */
+@Slf4j
+@Aspect
+@Component
+public class PermissionAspect {
+
+    @Autowired
+    private DataPermissionService dataPermissionService;
+
+    /**
+     * 超级管理员角色ID
+     */
+    private static final Long SUPER_ADMIN_ROLE_ID = 1L;
+
+    /**
+     * 拦截带有@RequirePermission注解的方法
+     */
+    @Around("@annotation(com.haha.admin.annotation.RequirePermission)")
+    public Object checkPermission(ProceedingJoinPoint joinPoint) throws Throwable {
+        // 获取当前登录用户ID
+        Object loginId = StpUtil.getLoginId();
+        if (loginId == null) {
+            log.warn("权限校验失败: 未登录");
+            return Result.error(401, "请先登录");
+        }
+
+        // 获取方法上的注解
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        Method method = signature.getMethod();
+        RequirePermission annotation = method.getAnnotation(RequirePermission.class);
+        
+        if (annotation == null) {
+            return joinPoint.proceed();
+        }
+
+        String requiredPermission = annotation.value();
+        log.debug("权限校验: userId={}, requiredPermission={}", loginId, requiredPermission);
+
+        // 获取用户的角色ID列表
+        String roleIdsStr = (String) StpUtil.getSession().get("roleIds");
+        if (roleIdsStr == null || roleIdsStr.trim().isEmpty()) {
+            log.warn("权限校验失败: 用户无角色 userId={}", loginId);
+            return Result.error(403, annotation.message());
+        }
+
+        // 解析角色ID列表
+        List<Long> roleIds = Arrays.stream(roleIdsStr.split(","))
+                .map(String::trim)
+                .filter(s -> !s.isEmpty())
+                .map(Long::parseLong)
+                .toList();
+
+        // 检查是否是超级管理员
+        if (roleIds.contains(SUPER_ADMIN_ROLE_ID)) {
+            log.debug("超级管理员跳过权限校验: userId={}", loginId);
+            return joinPoint.proceed();
+        }
+
+        // 获取用户的权限列表
+        List<String> userPermissions = dataPermissionService.getPermissionCodesByRoleIds(roleIds);
+        
+        // 检查是否拥有所需权限
+        if (userPermissions.contains(requiredPermission)) {
+            log.debug("权限校验通过: userId={}, permission={}", loginId, requiredPermission);
+            return joinPoint.proceed();
+        }
+
+        log.warn("权限校验失败: userId={}, requiredPermission={}, userPermissions={}", 
+                loginId, requiredPermission, userPermissions);
+        return Result.error(403, annotation.message());
+    }
+
+    /**
+     * 拦截带有@SuperAdmin注解的方法
+     */
+    @Around("@annotation(com.haha.admin.annotation.SuperAdmin)")
+    public Object checkSuperAdmin(ProceedingJoinPoint joinPoint) throws Throwable {
+        // 获取当前登录用户ID
+        Object loginId = StpUtil.getLoginId();
+        if (loginId == null) {
+            log.warn("超级管理员校验失败: 未登录");
+            return Result.error(401, "请先登录");
+        }
+
+        // 获取方法上的注解
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        Method method = signature.getMethod();
+        SuperAdmin annotation = method.getAnnotation(SuperAdmin.class);
+        
+        String message = annotation != null ? annotation.message() : "仅超级管理员可访问";
+
+        // 获取用户的角色ID列表
+        String roleIdsStr = (String) StpUtil.getSession().get("roleIds");
+        if (roleIdsStr == null || roleIdsStr.trim().isEmpty()) {
+            log.warn("超级管理员校验失败: 用户无角色 userId={}", loginId);
+            return Result.error(403, message);
+        }
+
+        // 解析角色ID列表
+        List<Long> roleIds = Arrays.stream(roleIdsStr.split(","))
+                .map(String::trim)
+                .filter(s -> !s.isEmpty())
+                .map(Long::parseLong)
+                .toList();
+
+        // 检查是否是超级管理员
+        if (roleIds.contains(SUPER_ADMIN_ROLE_ID)) {
+            log.debug("超级管理员校验通过: userId={}", loginId);
+            return joinPoint.proceed();
+        }
+
+        log.warn("超级管理员校验失败: userId={}", loginId);
+        return Result.error(403, message);
+    }
+}

+ 8 - 0
haha-admin/src/main/java/com/haha/admin/controller/AdminController.java

@@ -1,6 +1,7 @@
 package com.haha.admin.controller;
 package com.haha.admin.controller;
 
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.haha.admin.annotation.RequirePermission;
 import com.haha.service.AdminService;
 import com.haha.service.AdminService;
 import com.haha.common.annotation.Log;
 import com.haha.common.annotation.Log;
 import com.haha.common.enums.OperationType;
 import com.haha.common.enums.OperationType;
@@ -26,6 +27,7 @@ public class AdminController {
     /**
     /**
      * 分页查询管理员列表
      * 分页查询管理员列表
      */
      */
+    @RequirePermission("admin:read")
     @PostMapping
     @PostMapping
     public Result<Map<String, Object>> list(@RequestBody Map<String, Object> params) {
     public Result<Map<String, Object>> list(@RequestBody Map<String, Object> params) {
         int page = Integer.parseInt(params.getOrDefault("page", 1).toString());
         int page = Integer.parseInt(params.getOrDefault("page", 1).toString());
@@ -54,6 +56,7 @@ public class AdminController {
     /**
     /**
      * 获取管理员详情
      * 获取管理员详情
      */
      */
+    @RequirePermission("admin:read")
     @GetMapping("/{id}")
     @GetMapping("/{id}")
     public Result<Admin> getById(@PathVariable Long id) {
     public Result<Admin> getById(@PathVariable Long id) {
         Admin admin = adminService.getById(id);
         Admin admin = adminService.getById(id);
@@ -68,6 +71,7 @@ public class AdminController {
     /**
     /**
      * 添加管理员
      * 添加管理员
      */
      */
+    @RequirePermission("admin:create")
     @Log(module = "用户管理", operation = OperationType.INSERT, summary = "添加管理员")
     @Log(module = "用户管理", operation = OperationType.INSERT, summary = "添加管理员")
     @PostMapping("/add")
     @PostMapping("/add")
     public Result<Void> add(@RequestBody Admin admin) {
     public Result<Void> add(@RequestBody Admin admin) {
@@ -77,6 +81,7 @@ public class AdminController {
     /**
     /**
      * 更新管理员
      * 更新管理员
      */
      */
+    @RequirePermission("admin:update")
     @Log(module = "用户管理", operation = OperationType.UPDATE, summary = "更新管理员")
     @Log(module = "用户管理", operation = OperationType.UPDATE, summary = "更新管理员")
     @PostMapping("/update")
     @PostMapping("/update")
     public Result<Void> update(@RequestBody Admin admin) {
     public Result<Void> update(@RequestBody Admin admin) {
@@ -86,6 +91,7 @@ public class AdminController {
     /**
     /**
      * 删除管理员
      * 删除管理员
      */
      */
+    @RequirePermission("admin:delete")
     @Log(module = "用户管理", operation = OperationType.DELETE, summary = "删除管理员")
     @Log(module = "用户管理", operation = OperationType.DELETE, summary = "删除管理员")
     @DeleteMapping("/{id}")
     @DeleteMapping("/{id}")
     public Result<Void> delete(@PathVariable Long id) {
     public Result<Void> delete(@PathVariable Long id) {
@@ -95,6 +101,7 @@ public class AdminController {
     /**
     /**
      * 重置密码
      * 重置密码
      */
      */
+    @RequirePermission("admin:update")
     @Log(module = "用户管理", operation = OperationType.UPDATE, summary = "重置管理员密码")
     @Log(module = "用户管理", operation = OperationType.UPDATE, summary = "重置管理员密码")
     @PostMapping("/reset-password")
     @PostMapping("/reset-password")
     public Result<Void> resetPassword(@RequestBody Map<String, Object> params) {
     public Result<Void> resetPassword(@RequestBody Map<String, Object> params) {
@@ -106,6 +113,7 @@ public class AdminController {
     /**
     /**
      * 获取统计数据
      * 获取统计数据
      */
      */
+    @RequirePermission("admin:read")
     @GetMapping("/statistics")
     @GetMapping("/statistics")
     public Result<Map<String, Object>> statistics() {
     public Result<Map<String, Object>> statistics() {
         return adminService.getStatistics();
         return adminService.getStatistics();

+ 17 - 0
haha-admin/src/main/java/com/haha/admin/controller/AnnouncementController.java

@@ -2,6 +2,9 @@ package com.haha.admin.controller;
 
 
 import cn.dev33.satoken.stp.StpUtil;
 import cn.dev33.satoken.stp.StpUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.haha.admin.annotation.RequirePermission;
+import com.haha.common.annotation.Log;
+import com.haha.common.enums.OperationType;
 import com.haha.common.vo.Result;
 import com.haha.common.vo.Result;
 import com.haha.entity.Announcement;
 import com.haha.entity.Announcement;
 import com.haha.service.AnnouncementService;
 import com.haha.service.AnnouncementService;
@@ -27,6 +30,7 @@ public class AnnouncementController {
     /**
     /**
      * 分页查询公告列表
      * 分页查询公告列表
      */
      */
+    @RequirePermission("announcement:read")
     @GetMapping("/list")
     @GetMapping("/list")
     public Result<Map<String, Object>> list(@RequestParam Map<String, Object> params) {
     public Result<Map<String, Object>> list(@RequestParam Map<String, Object> params) {
         int page = 1;
         int page = 1;
@@ -55,6 +59,7 @@ public class AnnouncementController {
     /**
     /**
      * 获取公告详情
      * 获取公告详情
      */
      */
+    @RequirePermission("announcement:read")
     @GetMapping("/{id}")
     @GetMapping("/{id}")
     public Result<Announcement> getDetail(@PathVariable Long id) {
     public Result<Announcement> getDetail(@PathVariable Long id) {
         Announcement announcement = announcementService.getById(id);
         Announcement announcement = announcementService.getById(id);
@@ -67,6 +72,8 @@ public class AnnouncementController {
     /**
     /**
      * 创建公告
      * 创建公告
      */
      */
+    @RequirePermission("announcement:create")
+    @Log(module = "公告管理", operation = OperationType.INSERT, summary = "创建公告")
     @PostMapping
     @PostMapping
     public Result<Announcement> create(@RequestBody Announcement announcement) {
     public Result<Announcement> create(@RequestBody Announcement announcement) {
         try {
         try {
@@ -87,6 +94,8 @@ public class AnnouncementController {
     /**
     /**
      * 更新公告
      * 更新公告
      */
      */
+    @RequirePermission("announcement:update")
+    @Log(module = "公告管理", operation = OperationType.UPDATE, summary = "更新公告")
     @PutMapping("/{id}")
     @PutMapping("/{id}")
     public Result<Announcement> update(@PathVariable Long id, @RequestBody Announcement announcement) {
     public Result<Announcement> update(@PathVariable Long id, @RequestBody Announcement announcement) {
         try {
         try {
@@ -113,6 +122,8 @@ public class AnnouncementController {
     /**
     /**
      * 删除公告
      * 删除公告
      */
      */
+    @RequirePermission("announcement:delete")
+    @Log(module = "公告管理", operation = OperationType.DELETE, summary = "删除公告")
     @DeleteMapping("/{id}")
     @DeleteMapping("/{id}")
     public Result<String> delete(@PathVariable Long id) {
     public Result<String> delete(@PathVariable Long id) {
         try {
         try {
@@ -132,6 +143,8 @@ public class AnnouncementController {
     /**
     /**
      * 发布公告
      * 发布公告
      */
      */
+    @RequirePermission("announcement:update")
+    @Log(module = "公告管理", operation = OperationType.UPDATE, summary = "发布公告")
     @PutMapping("/{id}/publish")
     @PutMapping("/{id}/publish")
     public Result<String> publish(@PathVariable Long id) {
     public Result<String> publish(@PathVariable Long id) {
         try {
         try {
@@ -153,6 +166,8 @@ public class AnnouncementController {
     /**
     /**
      * 下线公告
      * 下线公告
      */
      */
+    @RequirePermission("announcement:update")
+    @Log(module = "公告管理", operation = OperationType.UPDATE, summary = "下线公告")
     @PutMapping("/{id}/offline")
     @PutMapping("/{id}/offline")
     public Result<String> offline(@PathVariable Long id) {
     public Result<String> offline(@PathVariable Long id) {
         try {
         try {
@@ -171,6 +186,8 @@ public class AnnouncementController {
     /**
     /**
      * 置顶/取消置顶
      * 置顶/取消置顶
      */
      */
+    @RequirePermission("announcement:update")
+    @Log(module = "公告管理", operation = OperationType.UPDATE, summary = "置顶公告")
     @PutMapping("/{id}/top")
     @PutMapping("/{id}/top")
     public Result<String> setTop(@PathVariable Long id, @RequestParam Integer isTop) {
     public Result<String> setTop(@PathVariable Long id, @RequestParam Integer isTop) {
         try {
         try {

+ 5 - 0
haha-admin/src/main/java/com/haha/admin/controller/DashboardController.java

@@ -1,5 +1,6 @@
 package com.haha.admin.controller;
 package com.haha.admin.controller;
 
 
+import com.haha.admin.annotation.RequirePermission;
 import com.haha.common.vo.Result;
 import com.haha.common.vo.Result;
 import com.haha.service.DashboardService;
 import com.haha.service.DashboardService;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
@@ -22,6 +23,7 @@ public class DashboardController {
     /**
     /**
      * 获取概览数据(今日实时数据)
      * 获取概览数据(今日实时数据)
      */
      */
+    @RequirePermission("dashboard:read")
     @GetMapping("/overview")
     @GetMapping("/overview")
     public Result<Map<String, Object>> getOverview() {
     public Result<Map<String, Object>> getOverview() {
         try {
         try {
@@ -37,6 +39,7 @@ public class DashboardController {
      * 获取统计数据(按时间维度)
      * 获取统计数据(按时间维度)
      * @param type 时间类型:yesterday/week/month/days30
      * @param type 时间类型:yesterday/week/month/days30
      */
      */
+    @RequirePermission("dashboard:read")
     @GetMapping("/statistics")
     @GetMapping("/statistics")
     public Result<Map<String, Object>> getStatistics(@RequestParam(defaultValue = "week") String type) {
     public Result<Map<String, Object>> getStatistics(@RequestParam(defaultValue = "week") String type) {
         try {
         try {
@@ -51,6 +54,7 @@ public class DashboardController {
     /**
     /**
      * 获取快捷入口数据
      * 获取快捷入口数据
      */
      */
+    @RequirePermission("dashboard:read")
     @GetMapping("/quick-links")
     @GetMapping("/quick-links")
     public Result<Map<String, Object>> getQuickLinks() {
     public Result<Map<String, Object>> getQuickLinks() {
         try {
         try {
@@ -65,6 +69,7 @@ public class DashboardController {
     /**
     /**
      * 获取设备状态分布
      * 获取设备状态分布
      */
      */
+    @RequirePermission("dashboard:read")
     @GetMapping("/device-status")
     @GetMapping("/device-status")
     public Result<Object> getDeviceStatus() {
     public Result<Object> getDeviceStatus() {
         try {
         try {

+ 78 - 0
haha-admin/src/main/java/com/haha/admin/controller/DataPermissionController.java

@@ -0,0 +1,78 @@
+package com.haha.admin.controller;
+
+import com.haha.admin.annotation.RequirePermission;
+import com.haha.common.annotation.Log;
+import com.haha.common.enums.OperationType;
+import com.haha.common.vo.Result;
+import com.haha.entity.DataPermission;
+import com.haha.service.DataPermissionService;
+import com.haha.service.RoleService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 数据权限管理控制器
+ */
+@Slf4j
+@RestController
+@RequestMapping("/permission")
+public class DataPermissionController {
+
+    @Autowired
+    private DataPermissionService dataPermissionService;
+
+    @Autowired
+    private RoleService roleService;
+
+    /**
+     * 获取所有权限列表
+     */
+    @RequirePermission("role:read")
+    @GetMapping("/list")
+    public Result<List<DataPermission>> getAllPermissions() {
+        return dataPermissionService.getAllPermissions();
+    }
+
+    /**
+     * 获取所有权限(按模块分组)
+     */
+    @RequirePermission("role:read")
+    @GetMapping("/list-grouped")
+    public Result<Map<String, List<DataPermission>>> getPermissionsGroupedByModule() {
+        return dataPermissionService.getPermissionsGroupByModule();
+    }
+
+    /**
+     * 根据模块编码获取权限列表
+     */
+    @RequirePermission("role:read")
+    @GetMapping("/module/{moduleCode}")
+    public Result<List<DataPermission>> getPermissionsByModule(@PathVariable String moduleCode) {
+        return dataPermissionService.getPermissionsByModule(moduleCode);
+    }
+
+    /**
+     * 根据角色ID获取权限ID列表
+     */
+    @RequirePermission("role:read")
+    @GetMapping("/role/{roleId}")
+    public Result<List<Long>> getRolePermissionIds(@PathVariable Long roleId) {
+        return roleService.getRolePermissionIds(roleId);
+    }
+
+    /**
+     * 更新角色权限
+     */
+    @RequirePermission("role:update")
+    @Log(module = "权限管理", operation = OperationType.UPDATE, summary = "更新角色权限")
+    @PostMapping("/role/{roleId}")
+    public Result<Void> updateRolePermissions(
+            @PathVariable Long roleId,
+            @RequestBody List<Long> permissionIds) {
+        return roleService.updateRolePermissions(roleId, permissionIds);
+    }
+}

+ 6 - 0
haha-admin/src/main/java/com/haha/admin/controller/DataSyncController.java

@@ -1,6 +1,7 @@
 package com.haha.admin.controller;
 package com.haha.admin.controller;
 
 
 import cn.dev33.satoken.stp.StpUtil;
 import cn.dev33.satoken.stp.StpUtil;
+import com.haha.admin.annotation.RequirePermission;
 import com.haha.common.annotation.Log;
 import com.haha.common.annotation.Log;
 import com.haha.common.enums.OperationType;
 import com.haha.common.enums.OperationType;
 import com.haha.common.vo.Result;
 import com.haha.common.vo.Result;
@@ -27,6 +28,7 @@ public class DataSyncController {
      * 同步设备数据
      * 同步设备数据
      * 从哈哈平台拉取设备列表并存储到本地数据库
      * 从哈哈平台拉取设备列表并存储到本地数据库
      */
      */
+    @RequirePermission("sync:execute")
     @Log(module = "数据同步", operation = OperationType.SYNC, summary = "同步设备数据")
     @Log(module = "数据同步", operation = OperationType.SYNC, summary = "同步设备数据")
     @PostMapping("/devices")
     @PostMapping("/devices")
     public Result<SyncRecord> syncDevices() {
     public Result<SyncRecord> syncDevices() {
@@ -61,6 +63,7 @@ public class DataSyncController {
      * 同步商品数据
      * 同步商品数据
      * 从哈哈平台商家商品库拉取商品列表并存储到本地数据库
      * 从哈哈平台商家商品库拉取商品列表并存储到本地数据库
      */
      */
+    @RequirePermission("sync:execute")
     @Log(module = "数据同步", operation = OperationType.SYNC, summary = "同步商品数据")
     @Log(module = "数据同步", operation = OperationType.SYNC, summary = "同步商品数据")
     @PostMapping("/products")
     @PostMapping("/products")
     public Result<SyncRecord> syncProducts() {
     public Result<SyncRecord> syncProducts() {
@@ -94,6 +97,7 @@ public class DataSyncController {
     /**
     /**
      * 获取同步记录列表
      * 获取同步记录列表
      */
      */
+    @RequirePermission("sync:read")
     @GetMapping("/records")
     @GetMapping("/records")
     public Result<Map<String, Object>> getSyncRecords(
     public Result<Map<String, Object>> getSyncRecords(
             @RequestParam(required = false) String syncType,
             @RequestParam(required = false) String syncType,
@@ -112,6 +116,7 @@ public class DataSyncController {
     /**
     /**
      * 获取同步日志列表
      * 获取同步日志列表
      */
      */
+    @RequirePermission("sync:read")
     @GetMapping("/logs/{recordId}")
     @GetMapping("/logs/{recordId}")
     public Result<Map<String, Object>> getSyncLogs(
     public Result<Map<String, Object>> getSyncLogs(
             @PathVariable Long recordId,
             @PathVariable Long recordId,
@@ -129,6 +134,7 @@ public class DataSyncController {
     /**
     /**
      * 获取同步统计信息
      * 获取同步统计信息
      */
      */
+    @RequirePermission("sync:read")
     @GetMapping("/statistics")
     @GetMapping("/statistics")
     public Result<Map<String, Object>> getSyncStatistics() {
     public Result<Map<String, Object>> getSyncStatistics() {
         try {
         try {

+ 7 - 0
haha-admin/src/main/java/com/haha/admin/controller/DeviceController.java

@@ -1,6 +1,7 @@
 package com.haha.admin.controller;
 package com.haha.admin.controller;
 
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.haha.admin.annotation.RequirePermission;
 import com.haha.admin.dto.DeviceQueryDTO;
 import com.haha.admin.dto.DeviceQueryDTO;
 import com.haha.common.annotation.Log;
 import com.haha.common.annotation.Log;
 import com.haha.common.enums.OperationType;
 import com.haha.common.enums.OperationType;
@@ -30,6 +31,7 @@ public class DeviceController {
      * @param queryDTO 查询参数
      * @param queryDTO 查询参数
      * @return 设备列表
      * @return 设备列表
      */
      */
+    @RequirePermission("device:read")
     @GetMapping("/list")
     @GetMapping("/list")
     public Result<PageResult<Device>> list(DeviceQueryDTO queryDTO) {
     public Result<PageResult<Device>> list(DeviceQueryDTO queryDTO) {
         queryDTO.validate();
         queryDTO.validate();
@@ -50,6 +52,7 @@ public class DeviceController {
      * @param id 设备ID
      * @param id 设备ID
      * @return 设备详情
      * @return 设备详情
      */
      */
+    @RequirePermission("device:read")
     @GetMapping("/{id}")
     @GetMapping("/{id}")
     public Result<Device> getById(@PathVariable Long id) {
     public Result<Device> getById(@PathVariable Long id) {
         Device device = deviceService.getDetailById(id);
         Device device = deviceService.getDetailById(id);
@@ -63,6 +66,7 @@ public class DeviceController {
      * 获取设备统计数据
      * 获取设备统计数据
      * @return 统计数据
      * @return 统计数据
      */
      */
+    @RequirePermission("device:read")
     @GetMapping("/statistics")
     @GetMapping("/statistics")
     public Result<Map<String, Object>> getStatistics() {
     public Result<Map<String, Object>> getStatistics() {
         Map<String, Object> statistics = deviceService.getStatistics();
         Map<String, Object> statistics = deviceService.getStatistics();
@@ -75,6 +79,7 @@ public class DeviceController {
      * @param params 开门参数
      * @param params 开门参数
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("device:update")
     @Log(module = "设备管理", operation = OperationType.OTHER, summary = "远程开门")
     @Log(module = "设备管理", operation = OperationType.OTHER, summary = "远程开门")
     @PostMapping("/{id}/open")
     @PostMapping("/{id}/open")
     public Result<Void> openDoor(@PathVariable Long id, @RequestBody Map<String, Object> params) {
     public Result<Void> openDoor(@PathVariable Long id, @RequestBody Map<String, Object> params) {
@@ -89,6 +94,7 @@ public class DeviceController {
      * @param params 温度参数
      * @param params 温度参数
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("device:update")
     @PutMapping("/{id}/temperature")
     @PutMapping("/{id}/temperature")
     public Result<Void> setTemperature(@PathVariable Long id, @RequestBody Map<String, Object> params) {
     public Result<Void> setTemperature(@PathVariable Long id, @RequestBody Map<String, Object> params) {
         Double temperature = Double.valueOf(params.get("temperature").toString());
         Double temperature = Double.valueOf(params.get("temperature").toString());
@@ -102,6 +108,7 @@ public class DeviceController {
      * @param params 音量参数
      * @param params 音量参数
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("device:update")
     @PutMapping("/{id}/volume")
     @PutMapping("/{id}/volume")
     public Result<Void> setVolume(@PathVariable Long id, @RequestBody Map<String, Object> params) {
     public Result<Void> setVolume(@PathVariable Long id, @RequestBody Map<String, Object> params) {
         Integer volume = Integer.valueOf(params.get("volume").toString());
         Integer volume = Integer.valueOf(params.get("volume").toString());

+ 16 - 0
haha-admin/src/main/java/com/haha/admin/controller/InventoryController.java

@@ -2,6 +2,7 @@ package com.haha.admin.controller;
 
 
 import cn.dev33.satoken.stp.StpUtil;
 import cn.dev33.satoken.stp.StpUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.haha.admin.annotation.RequirePermission;
 import com.haha.common.annotation.Log;
 import com.haha.common.annotation.Log;
 import com.haha.common.enums.OperationType;
 import com.haha.common.enums.OperationType;
 import com.haha.common.vo.Result;
 import com.haha.common.vo.Result;
@@ -42,6 +43,7 @@ public class InventoryController {
      * 分页查询设备库存统计列表
      * 分页查询设备库存统计列表
      * 按设备分组展示库存汇总信息
      * 按设备分组展示库存汇总信息
      */
      */
+    @RequirePermission("inventory:read")
     @GetMapping("/device-stats")
     @GetMapping("/device-stats")
     public Result<Map<String, Object>> deviceStats(@RequestParam Map<String, Object> params) {
     public Result<Map<String, Object>> deviceStats(@RequestParam Map<String, Object> params) {
         int page = 1;
         int page = 1;
@@ -70,6 +72,7 @@ public class InventoryController {
     /**
     /**
      * 分页查询库存列表
      * 分页查询库存列表
      */
      */
+    @RequirePermission("inventory:read")
     @GetMapping("/list")
     @GetMapping("/list")
     public Result<Map<String, Object>> list(@RequestParam Map<String, Object> params) {
     public Result<Map<String, Object>> list(@RequestParam Map<String, Object> params) {
         int page = 1;
         int page = 1;
@@ -103,6 +106,7 @@ public class InventoryController {
     /**
     /**
      * 查询设备库存详情
      * 查询设备库存详情
      */
      */
+    @RequirePermission("inventory:read")
     @GetMapping("/device/{deviceId}")
     @GetMapping("/device/{deviceId}")
     public Result<Map<String, Object>> getDeviceInventory(@PathVariable String deviceId) {
     public Result<Map<String, Object>> getDeviceInventory(@PathVariable String deviceId) {
         List<Map<String, Object>> inventory = deviceInventoryService.getInventoryWithProduct(deviceId);
         List<Map<String, Object>> inventory = deviceInventoryService.getInventoryWithProduct(deviceId);
@@ -114,6 +118,7 @@ public class InventoryController {
     /**
     /**
      * 查询低库存商品
      * 查询低库存商品
      */
      */
+    @RequirePermission("inventory:read")
     @GetMapping("/low-stock")
     @GetMapping("/low-stock")
     public Result<List<Map<String, Object>>> getLowStock() {
     public Result<List<Map<String, Object>>> getLowStock() {
         List<Map<String, Object>> lowStockList = deviceInventoryService.getLowStockList();
         List<Map<String, Object>> lowStockList = deviceInventoryService.getLowStockList();
@@ -123,6 +128,7 @@ public class InventoryController {
     /**
     /**
      * 获取库存统计
      * 获取库存统计
      */
      */
+    @RequirePermission("inventory:read")
     @GetMapping("/statistics")
     @GetMapping("/statistics")
     public Result<Map<String, Object>> getStatistics() {
     public Result<Map<String, Object>> getStatistics() {
         Map<String, Object> stats = deviceInventoryService.getStatistics();
         Map<String, Object> stats = deviceInventoryService.getStatistics();
@@ -134,6 +140,7 @@ public class InventoryController {
     /**
     /**
      * 增加库存(上货)
      * 增加库存(上货)
      */
      */
+    @RequirePermission("inventory:update")
     @Log(module = "库存管理", operation = OperationType.INSERT, summary = "上货增加库存")
     @Log(module = "库存管理", operation = OperationType.INSERT, summary = "上货增加库存")
     @PostMapping("/increase")
     @PostMapping("/increase")
     public Result<DeviceInventory> increaseStock(@RequestBody Map<String, Object> params) {
     public Result<DeviceInventory> increaseStock(@RequestBody Map<String, Object> params) {
@@ -166,6 +173,7 @@ public class InventoryController {
     /**
     /**
      * 调整库存
      * 调整库存
      */
      */
+    @RequirePermission("inventory:update")
     @Log(module = "库存管理", operation = OperationType.UPDATE, summary = "调整库存")
     @Log(module = "库存管理", operation = OperationType.UPDATE, summary = "调整库存")
     @PostMapping("/adjust")
     @PostMapping("/adjust")
     public Result<DeviceInventory> adjustStock(@RequestBody Map<String, Object> params) {
     public Result<DeviceInventory> adjustStock(@RequestBody Map<String, Object> params) {
@@ -193,6 +201,7 @@ public class InventoryController {
     /**
     /**
      * 分页查询库存变动日志
      * 分页查询库存变动日志
      */
      */
+    @RequirePermission("inventory:read")
     @GetMapping("/logs")
     @GetMapping("/logs")
     public Result<Map<String, Object>> getLogList(@RequestParam Map<String, Object> params) {
     public Result<Map<String, Object>> getLogList(@RequestParam Map<String, Object> params) {
         int page = 1;
         int page = 1;
@@ -221,6 +230,7 @@ public class InventoryController {
     /**
     /**
      * 查询设备库存变动统计
      * 查询设备库存变动统计
      */
      */
+    @RequirePermission("inventory:read")
     @GetMapping("/logs/statistics")
     @GetMapping("/logs/statistics")
     public Result<List<Map<String, Object>>> getLogStatistics(
     public Result<List<Map<String, Object>>> getLogStatistics(
             @RequestParam String deviceId,
             @RequestParam String deviceId,
@@ -235,6 +245,7 @@ public class InventoryController {
     /**
     /**
      * 分页查询上货记录
      * 分页查询上货记录
      */
      */
+    @RequirePermission("inventory:read")
     @GetMapping("/records")
     @GetMapping("/records")
     public Result<Map<String, Object>> getRecordList(@RequestParam Map<String, Object> params) {
     public Result<Map<String, Object>> getRecordList(@RequestParam Map<String, Object> params) {
         int page = 1;
         int page = 1;
@@ -263,6 +274,7 @@ public class InventoryController {
     /**
     /**
      * 获取上货记录详情
      * 获取上货记录详情
      */
      */
+    @RequirePermission("inventory:read")
     @GetMapping("/records/{id}")
     @GetMapping("/records/{id}")
     public Result<Map<String, Object>> getRecordDetail(@PathVariable Long id) {
     public Result<Map<String, Object>> getRecordDetail(@PathVariable Long id) {
         Map<String, Object> detail = stockRecordService.getDetailWithDeviceName(id);
         Map<String, Object> detail = stockRecordService.getDetailWithDeviceName(id);
@@ -272,6 +284,7 @@ public class InventoryController {
     /**
     /**
      * 创建上货记录
      * 创建上货记录
      */
      */
+    @RequirePermission("inventory:create")
     @PostMapping("/records")
     @PostMapping("/records")
     public Result<StockRecord> createRecord(@RequestBody Map<String, Object> params) {
     public Result<StockRecord> createRecord(@RequestBody Map<String, Object> params) {
         try {
         try {
@@ -298,6 +311,7 @@ public class InventoryController {
     /**
     /**
      * 完成上货记录
      * 完成上货记录
      */
      */
+    @RequirePermission("inventory:update")
     @PutMapping("/records/{id}/complete")
     @PutMapping("/records/{id}/complete")
     public Result<String> completeRecord(
     public Result<String> completeRecord(
             @PathVariable Long id,
             @PathVariable Long id,
@@ -320,6 +334,7 @@ public class InventoryController {
     /**
     /**
      * 取消上货记录
      * 取消上货记录
      */
      */
+    @RequirePermission("inventory:update")
     @PutMapping("/records/{id}/cancel")
     @PutMapping("/records/{id}/cancel")
     public Result<String> cancelRecord(@PathVariable Long id) {
     public Result<String> cancelRecord(@PathVariable Long id) {
         try {
         try {
@@ -334,6 +349,7 @@ public class InventoryController {
     /**
     /**
      * 获取上货员工作统计
      * 获取上货员工作统计
      */
      */
+    @RequirePermission("inventory:read")
     @GetMapping("/records/stocker-statistics")
     @GetMapping("/records/stocker-statistics")
     public Result<Map<String, Object>> getStockerStatistics(
     public Result<Map<String, Object>> getStockerStatistics(
             @RequestParam Long stockerId,
             @RequestParam Long stockerId,

+ 9 - 0
haha-admin/src/main/java/com/haha/admin/controller/NewProductApplyController.java

@@ -2,6 +2,7 @@ package com.haha.admin.controller;
 
 
 import cn.dev33.satoken.stp.StpUtil;
 import cn.dev33.satoken.stp.StpUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.haha.admin.annotation.RequirePermission;
 import com.haha.common.annotation.Log;
 import com.haha.common.annotation.Log;
 import com.haha.common.enums.OperationType;
 import com.haha.common.enums.OperationType;
 import com.haha.common.vo.Result;
 import com.haha.common.vo.Result;
@@ -30,6 +31,7 @@ public class NewProductApplyController {
      * @param params 查询参数
      * @param params 查询参数
      * @return 申请列表
      * @return 申请列表
      */
      */
+    @RequirePermission("product-apply:read")
     @GetMapping("/list")
     @GetMapping("/list")
     public Result<Map<String, Object>> list(@RequestParam Map<String, Object> params) {
     public Result<Map<String, Object>> list(@RequestParam Map<String, Object> params) {
         int page = 1;
         int page = 1;
@@ -61,6 +63,7 @@ public class NewProductApplyController {
      * @param id 申请ID
      * @param id 申请ID
      * @return 申请详情
      * @return 申请详情
      */
      */
+    @RequirePermission("product-apply:read")
     @GetMapping("/{id}")
     @GetMapping("/{id}")
     public Result<NewProductApply> getById(@PathVariable Long id) {
     public Result<NewProductApply> getById(@PathVariable Long id) {
         NewProductApply apply = newProductApplyService.getById(id);
         NewProductApply apply = newProductApplyService.getById(id);
@@ -71,6 +74,7 @@ public class NewProductApplyController {
      * 获取申请统计信息
      * 获取申请统计信息
      * @return 统计信息
      * @return 统计信息
      */
      */
+    @RequirePermission("product-apply:read")
     @GetMapping("/statistics")
     @GetMapping("/statistics")
     public Result<Map<String, Object>> getStatistics() {
     public Result<Map<String, Object>> getStatistics() {
         Map<String, Object> stats = newProductApplyService.getStatistics();
         Map<String, Object> stats = newProductApplyService.getStatistics();
@@ -82,6 +86,7 @@ public class NewProductApplyController {
      * @param apply 申请信息
      * @param apply 申请信息
      * @return 申请ID
      * @return 申请ID
      */
      */
+    @RequirePermission("product-apply:create")
     @Log(module = "新品申请", operation = OperationType.INSERT, summary = "提交新品申请")
     @Log(module = "新品申请", operation = OperationType.INSERT, summary = "提交新品申请")
     @PostMapping("/submit")
     @PostMapping("/submit")
     public Result<Long> submit(@RequestBody NewProductApply apply) {
     public Result<Long> submit(@RequestBody NewProductApply apply) {
@@ -103,6 +108,7 @@ public class NewProductApplyController {
      * @param apply 申请信息
      * @param apply 申请信息
      * @return 申请ID
      * @return 申请ID
      */
      */
+    @RequirePermission("product-apply:create")
     @Log(module = "新品申请", operation = OperationType.INSERT, summary = "保存新品申请草稿")
     @Log(module = "新品申请", operation = OperationType.INSERT, summary = "保存新品申请草稿")
     @PostMapping("/save-draft")
     @PostMapping("/save-draft")
     public Result<Long> saveDraft(@RequestBody NewProductApply apply) {
     public Result<Long> saveDraft(@RequestBody NewProductApply apply) {
@@ -129,6 +135,7 @@ public class NewProductApplyController {
      * @param apply 申请信息
      * @param apply 申请信息
      * @return 是否成功
      * @return 是否成功
      */
      */
+    @RequirePermission("product-apply:update")
     @Log(module = "新品申请", operation = OperationType.UPDATE, summary = "更新新品申请")
     @Log(module = "新品申请", operation = OperationType.UPDATE, summary = "更新新品申请")
     @PutMapping("/{id}")
     @PutMapping("/{id}")
     public Result<Boolean> update(@PathVariable Long id, @RequestBody NewProductApply apply) {
     public Result<Boolean> update(@PathVariable Long id, @RequestBody NewProductApply apply) {
@@ -157,6 +164,7 @@ public class NewProductApplyController {
      * @param id 申请ID
      * @param id 申请ID
      * @return 是否成功
      * @return 是否成功
      */
      */
+    @RequirePermission("product-apply:delete")
     @Log(module = "新品申请", operation = OperationType.DELETE, summary = "删除新品申请")
     @Log(module = "新品申请", operation = OperationType.DELETE, summary = "删除新品申请")
     @DeleteMapping("/{id}")
     @DeleteMapping("/{id}")
     public Result<Boolean> delete(@PathVariable Long id) {
     public Result<Boolean> delete(@PathVariable Long id) {
@@ -184,6 +192,7 @@ public class NewProductApplyController {
      * @param barcode 商品条码
      * @param barcode 商品条码
      * @return 商品信息(如果存在)
      * @return 商品信息(如果存在)
      */
      */
+    @RequirePermission("product-apply:read")
     @GetMapping("/check-barcode")
     @GetMapping("/check-barcode")
     public Result<Map<String, Object>> checkBarcode(@RequestParam String barcode) {
     public Result<Map<String, Object>> checkBarcode(@RequestParam String barcode) {
         try {
         try {

+ 8 - 0
haha-admin/src/main/java/com/haha/admin/controller/OperationLogController.java

@@ -1,6 +1,7 @@
 package com.haha.admin.controller;
 package com.haha.admin.controller;
 
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.haha.admin.annotation.RequirePermission;
 import com.haha.common.annotation.Log;
 import com.haha.common.annotation.Log;
 import com.haha.common.enums.OperationType;
 import com.haha.common.enums.OperationType;
 import com.haha.common.vo.Result;
 import com.haha.common.vo.Result;
@@ -29,6 +30,7 @@ public class OperationLogController {
     /**
     /**
      * 分页查询操作日志列表
      * 分页查询操作日志列表
      */
      */
+    @RequirePermission("operation-log:read")
     @GetMapping("/list")
     @GetMapping("/list")
     public Result<Map<String, Object>> list(
     public Result<Map<String, Object>> list(
             @RequestParam(defaultValue = "1") Integer page,
             @RequestParam(defaultValue = "1") Integer page,
@@ -55,6 +57,7 @@ public class OperationLogController {
     /**
     /**
      * 获取操作日志详情
      * 获取操作日志详情
      */
      */
+    @RequirePermission("operation-log:read")
     @GetMapping("/{id}")
     @GetMapping("/{id}")
     public Result<OperationLog> detail(@PathVariable Long id) {
     public Result<OperationLog> detail(@PathVariable Long id) {
         OperationLog operationLog = operationLogService.getById(id);
         OperationLog operationLog = operationLogService.getById(id);
@@ -67,6 +70,7 @@ public class OperationLogController {
     /**
     /**
      * 批量删除操作日志
      * 批量删除操作日志
      */
      */
+    @RequirePermission("operation-log:delete")
     @Log(module = "系统监控", operation = OperationType.DELETE, summary = "批量删除操作日志")
     @Log(module = "系统监控", operation = OperationType.DELETE, summary = "批量删除操作日志")
     @DeleteMapping("/batch")
     @DeleteMapping("/batch")
     public Result<Void> deleteBatch(@RequestBody List<Long> ids) {
     public Result<Void> deleteBatch(@RequestBody List<Long> ids) {
@@ -77,6 +81,7 @@ public class OperationLogController {
     /**
     /**
      * 删除单条操作日志
      * 删除单条操作日志
      */
      */
+    @RequirePermission("operation-log:delete")
     @Log(module = "系统监控", operation = OperationType.DELETE, summary = "删除操作日志")
     @Log(module = "系统监控", operation = OperationType.DELETE, summary = "删除操作日志")
     @DeleteMapping("/{id}")
     @DeleteMapping("/{id}")
     public Result<Void> delete(@PathVariable Long id) {
     public Result<Void> delete(@PathVariable Long id) {
@@ -87,6 +92,7 @@ public class OperationLogController {
     /**
     /**
      * 清空所有操作日志
      * 清空所有操作日志
      */
      */
+    @RequirePermission("operation-log:delete")
     @Log(module = "系统监控", operation = OperationType.DELETE, summary = "清空操作日志")
     @Log(module = "系统监控", operation = OperationType.DELETE, summary = "清空操作日志")
     @DeleteMapping("/clear")
     @DeleteMapping("/clear")
     public Result<Void> clearAll() {
     public Result<Void> clearAll() {
@@ -97,6 +103,7 @@ public class OperationLogController {
     /**
     /**
      * 清空指定时间之前的日志
      * 清空指定时间之前的日志
      */
      */
+    @RequirePermission("operation-log:delete")
     @Log(module = "系统监控", operation = OperationType.DELETE, summary = "清空历史操作日志")
     @Log(module = "系统监控", operation = OperationType.DELETE, summary = "清空历史操作日志")
     @DeleteMapping("/clear-before")
     @DeleteMapping("/clear-before")
     public Result<Void> clearBeforeTime(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime beforeTime) {
     public Result<Void> clearBeforeTime(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime beforeTime) {
@@ -107,6 +114,7 @@ public class OperationLogController {
     /**
     /**
      * 获取操作日志统计数据
      * 获取操作日志统计数据
      */
      */
+    @RequirePermission("operation-log:read")
     @GetMapping("/statistics")
     @GetMapping("/statistics")
     public Result<Map<String, Object>> statistics() {
     public Result<Map<String, Object>> statistics() {
         Map<String, Object> data = operationLogService.getStatistics();
         Map<String, Object> data = operationLogService.getStatistics();

+ 5 - 0
haha-admin/src/main/java/com/haha/admin/controller/OrderController.java

@@ -1,6 +1,7 @@
 package com.haha.admin.controller;
 package com.haha.admin.controller;
 
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.haha.admin.annotation.RequirePermission;
 import com.haha.admin.dto.OrderQueryDTO;
 import com.haha.admin.dto.OrderQueryDTO;
 import com.haha.common.annotation.Log;
 import com.haha.common.annotation.Log;
 import com.haha.common.enums.OperationType;
 import com.haha.common.enums.OperationType;
@@ -30,6 +31,7 @@ public class OrderController {
      * @param queryDTO 查询参数
      * @param queryDTO 查询参数
      * @return 订单列表
      * @return 订单列表
      */
      */
+    @RequirePermission("order:read")
     @GetMapping("/list")
     @GetMapping("/list")
     public Result<PageResult<Order>> list(OrderQueryDTO queryDTO) {
     public Result<PageResult<Order>> list(OrderQueryDTO queryDTO) {
         queryDTO.validate();
         queryDTO.validate();
@@ -53,6 +55,7 @@ public class OrderController {
      * @param id 订单ID
      * @param id 订单ID
      * @return 订单详情
      * @return 订单详情
      */
      */
+    @RequirePermission("order:read")
     @GetMapping("/{id}")
     @GetMapping("/{id}")
     public Result<Order> getById(@PathVariable Long id) {
     public Result<Order> getById(@PathVariable Long id) {
         Order order = orderService.getDetailById(id);
         Order order = orderService.getDetailById(id);
@@ -66,6 +69,7 @@ public class OrderController {
      * 获取订单统计数据
      * 获取订单统计数据
      * @return 统计数据
      * @return 统计数据
      */
      */
+    @RequirePermission("order:read")
     @GetMapping("/statistics")
     @GetMapping("/statistics")
     public Result<Map<String, Object>> getStatistics() {
     public Result<Map<String, Object>> getStatistics() {
         Map<String, Object> statistics = orderService.getStatistics();
         Map<String, Object> statistics = orderService.getStatistics();
@@ -78,6 +82,7 @@ public class OrderController {
      * @param params 退款参数
      * @param params 退款参数
      * @return 退款结果
      * @return 退款结果
      */
      */
+    @RequirePermission("order:update")
     @Log(module = "订单管理", operation = OperationType.UPDATE, summary = "订单退款")
     @Log(module = "订单管理", operation = OperationType.UPDATE, summary = "订单退款")
     @PostMapping("/{id}/refund")
     @PostMapping("/{id}/refund")
     public Result<Void> refund(@PathVariable Long id, @RequestBody Map<String, Object> params) {
     public Result<Void> refund(@PathVariable Long id, @RequestBody Map<String, Object> params) {

+ 8 - 0
haha-admin/src/main/java/com/haha/admin/controller/ProductController.java

@@ -1,6 +1,7 @@
 package com.haha.admin.controller;
 package com.haha.admin.controller;
 
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.haha.admin.annotation.RequirePermission;
 import com.haha.admin.dto.ProductQueryDTO;
 import com.haha.admin.dto.ProductQueryDTO;
 import com.haha.common.annotation.Log;
 import com.haha.common.annotation.Log;
 import com.haha.common.enums.OperationType;
 import com.haha.common.enums.OperationType;
@@ -30,6 +31,7 @@ public class ProductController {
      * @param queryDTO 查询参数
      * @param queryDTO 查询参数
      * @return 商品列表
      * @return 商品列表
      */
      */
+    @RequirePermission("product:read")
     @GetMapping("/list")
     @GetMapping("/list")
     public Result<PageResult<Product>> list(ProductQueryDTO queryDTO) {
     public Result<PageResult<Product>> list(ProductQueryDTO queryDTO) {
         queryDTO.validate();
         queryDTO.validate();
@@ -51,6 +53,7 @@ public class ProductController {
      * @param id 商品ID
      * @param id 商品ID
      * @return 商品详情
      * @return 商品详情
      */
      */
+    @RequirePermission("product:read")
     @GetMapping("/{id}")
     @GetMapping("/{id}")
     public Result<Product> getById(@PathVariable Long id) {
     public Result<Product> getById(@PathVariable Long id) {
         Product product = productService.getDetailById(id);
         Product product = productService.getDetailById(id);
@@ -64,6 +67,7 @@ public class ProductController {
      * 获取商品统计数据
      * 获取商品统计数据
      * @return 统计数据
      * @return 统计数据
      */
      */
+    @RequirePermission("product:read")
     @GetMapping("/statistics")
     @GetMapping("/statistics")
     public Result<Map<String, Object>> getStatistics() {
     public Result<Map<String, Object>> getStatistics() {
         Map<String, Object> statistics = productService.getStatistics();
         Map<String, Object> statistics = productService.getStatistics();
@@ -75,6 +79,7 @@ public class ProductController {
      * @param product 商品信息
      * @param product 商品信息
      * @return 添加结果
      * @return 添加结果
      */
      */
+    @RequirePermission("product:create")
     @Log(module = "商品管理", operation = OperationType.INSERT, summary = "添加商品")
     @Log(module = "商品管理", operation = OperationType.INSERT, summary = "添加商品")
     @PostMapping
     @PostMapping
     public Result<Product> add(@RequestBody Product product) {
     public Result<Product> add(@RequestBody Product product) {
@@ -88,6 +93,7 @@ public class ProductController {
      * @param product 商品信息
      * @param product 商品信息
      * @return 编辑结果
      * @return 编辑结果
      */
      */
+    @RequirePermission("product:update")
     @Log(module = "商品管理", operation = OperationType.UPDATE, summary = "编辑商品")
     @Log(module = "商品管理", operation = OperationType.UPDATE, summary = "编辑商品")
     @PutMapping("/{id}")
     @PutMapping("/{id}")
     public Result<Product> update(@PathVariable Long id, @RequestBody Product product) {
     public Result<Product> update(@PathVariable Long id, @RequestBody Product product) {
@@ -100,6 +106,7 @@ public class ProductController {
      * @param id 商品ID
      * @param id 商品ID
      * @return 删除结果
      * @return 删除结果
      */
      */
+    @RequirePermission("product:delete")
     @Log(module = "商品管理", operation = OperationType.DELETE, summary = "删除商品")
     @Log(module = "商品管理", operation = OperationType.DELETE, summary = "删除商品")
     @DeleteMapping("/{id}")
     @DeleteMapping("/{id}")
     public Result<Void> delete(@PathVariable Long id) {
     public Result<Void> delete(@PathVariable Long id) {
@@ -112,6 +119,7 @@ public class ProductController {
      * @param id 商品ID
      * @param id 商品ID
      * @return 同步结果
      * @return 同步结果
      */
      */
+    @RequirePermission("product:update")
     @Log(module = "商品管理", operation = OperationType.SYNC, summary = "同步商品")
     @Log(module = "商品管理", operation = OperationType.SYNC, summary = "同步商品")
     @PostMapping("/{id}/sync")
     @PostMapping("/{id}/sync")
     public Result<Void> sync(@PathVariable Long id) {
     public Result<Void> sync(@PathVariable Long id) {

+ 6 - 0
haha-admin/src/main/java/com/haha/admin/controller/RoleController.java

@@ -1,6 +1,7 @@
 package com.haha.admin.controller;
 package com.haha.admin.controller;
 
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.haha.admin.annotation.RequirePermission;
 import com.haha.service.RoleService;
 import com.haha.service.RoleService;
 import com.haha.common.annotation.Log;
 import com.haha.common.annotation.Log;
 import com.haha.common.enums.OperationType;
 import com.haha.common.enums.OperationType;
@@ -27,6 +28,7 @@ public class RoleController {
     /**
     /**
      * 分页查询角色列表
      * 分页查询角色列表
      */
      */
+    @RequirePermission("role:read")
     @PostMapping
     @PostMapping
     public Result<Map<String, Object>> list(@RequestBody Map<String, Object> params) {
     public Result<Map<String, Object>> list(@RequestBody Map<String, Object> params) {
         int page = Integer.parseInt(params.getOrDefault("page", 1).toString());
         int page = Integer.parseInt(params.getOrDefault("page", 1).toString());
@@ -53,6 +55,7 @@ public class RoleController {
     /**
     /**
      * 获取所有角色(不分页)
      * 获取所有角色(不分页)
      */
      */
+    @RequirePermission("role:read")
     @GetMapping("/list-all-role")
     @GetMapping("/list-all-role")
     public Result<List<Role>> listAll() {
     public Result<List<Role>> listAll() {
         return roleService.getAllRoles();
         return roleService.getAllRoles();
@@ -61,6 +64,7 @@ public class RoleController {
     /**
     /**
      * 添加角色
      * 添加角色
      */
      */
+    @RequirePermission("role:create")
     @Log(module = "角色管理", operation = OperationType.INSERT, summary = "添加角色")
     @Log(module = "角色管理", operation = OperationType.INSERT, summary = "添加角色")
     @PostMapping("/add")
     @PostMapping("/add")
     public Result<Void> add(@RequestBody Role role) {
     public Result<Void> add(@RequestBody Role role) {
@@ -70,6 +74,7 @@ public class RoleController {
     /**
     /**
      * 更新角色
      * 更新角色
      */
      */
+    @RequirePermission("role:update")
     @Log(module = "角色管理", operation = OperationType.UPDATE, summary = "更新角色")
     @Log(module = "角色管理", operation = OperationType.UPDATE, summary = "更新角色")
     @PostMapping("/update")
     @PostMapping("/update")
     public Result<Void> update(@RequestBody Role role) {
     public Result<Void> update(@RequestBody Role role) {
@@ -79,6 +84,7 @@ public class RoleController {
     /**
     /**
      * 删除角色
      * 删除角色
      */
      */
+    @RequirePermission("role:delete")
     @Log(module = "角色管理", operation = OperationType.DELETE, summary = "删除角色")
     @Log(module = "角色管理", operation = OperationType.DELETE, summary = "删除角色")
     @DeleteMapping("/{id}")
     @DeleteMapping("/{id}")
     public Result<Void> delete(@PathVariable Long id) {
     public Result<Void> delete(@PathVariable Long id) {

+ 21 - 0
haha-admin/src/main/java/com/haha/admin/controller/ShopController.java

@@ -1,6 +1,7 @@
 package com.haha.admin.controller;
 package com.haha.admin.controller;
 
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.haha.admin.annotation.RequirePermission;
 import com.haha.admin.dto.ShopQueryDTO;
 import com.haha.admin.dto.ShopQueryDTO;
 import com.haha.common.annotation.Log;
 import com.haha.common.annotation.Log;
 import com.haha.common.enums.OperationType;
 import com.haha.common.enums.OperationType;
@@ -41,6 +42,7 @@ public class ShopController {
      * @param queryDTO 查询参数
      * @param queryDTO 查询参数
      * @return 门店列表
      * @return 门店列表
      */
      */
+    @RequirePermission("shop:read")
     @GetMapping("/list")
     @GetMapping("/list")
     public Result<PageResult<Shop>> list(ShopQueryDTO queryDTO) {
     public Result<PageResult<Shop>> list(ShopQueryDTO queryDTO) {
         queryDTO.validate();
         queryDTO.validate();
@@ -60,6 +62,7 @@ public class ShopController {
      * @param id 门店ID
      * @param id 门店ID
      * @return 门店详情
      * @return 门店详情
      */
      */
+    @RequirePermission("shop:read")
     @GetMapping("/{id}")
     @GetMapping("/{id}")
     public Result<Shop> getById(@PathVariable Long id) {
     public Result<Shop> getById(@PathVariable Long id) {
         Shop shop = shopService.getShopWithStats(id);
         Shop shop = shopService.getShopWithStats(id);
@@ -73,6 +76,7 @@ public class ShopController {
      * 获取门店统计数据
      * 获取门店统计数据
      * @return 统计数据
      * @return 统计数据
      */
      */
+    @RequirePermission("shop:read")
     @GetMapping("/statistics")
     @GetMapping("/statistics")
     public Result<Map<String, Object>> getStatistics() {
     public Result<Map<String, Object>> getStatistics() {
         Map<String, Object> statistics = shopService.getStatistics();
         Map<String, Object> statistics = shopService.getStatistics();
@@ -94,6 +98,7 @@ public class ShopController {
      * @param shop 门店信息
      * @param shop 门店信息
      * @return 新增后的门店
      * @return 新增后的门店
      */
      */
+    @RequirePermission("shop:create")
     @Log(module = "门店管理", operation = OperationType.INSERT, summary = "新增门店")
     @Log(module = "门店管理", operation = OperationType.INSERT, summary = "新增门店")
     @PostMapping
     @PostMapping
     public Result<Shop> create(@RequestBody Shop shop) {
     public Result<Shop> create(@RequestBody Shop shop) {
@@ -107,6 +112,7 @@ public class ShopController {
      * @param shop 门店信息
      * @param shop 门店信息
      * @return 编辑后的门店
      * @return 编辑后的门店
      */
      */
+    @RequirePermission("shop:update")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "编辑门店")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "编辑门店")
     @PutMapping("/{id}")
     @PutMapping("/{id}")
     public Result<Shop> update(@PathVariable Long id, @RequestBody Shop shop) {
     public Result<Shop> update(@PathVariable Long id, @RequestBody Shop shop) {
@@ -120,6 +126,7 @@ public class ShopController {
      * @param id 门店ID
      * @param id 门店ID
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("shop:delete")
     @Log(module = "门店管理", operation = OperationType.DELETE, summary = "删除门店")
     @Log(module = "门店管理", operation = OperationType.DELETE, summary = "删除门店")
     @DeleteMapping("/{id}")
     @DeleteMapping("/{id}")
     public Result<String> delete(@PathVariable Long id) {
     public Result<String> delete(@PathVariable Long id) {
@@ -143,6 +150,7 @@ public class ShopController {
      * @param params 状态参数
      * @param params 状态参数
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("shop:update")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "切换门店状态")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "切换门店状态")
     @PutMapping("/{id}/status")
     @PutMapping("/{id}/status")
     public Result<String> toggleStatus(@PathVariable Long id, @RequestBody Map<String, Object> params) {
     public Result<String> toggleStatus(@PathVariable Long id, @RequestBody Map<String, Object> params) {
@@ -161,6 +169,7 @@ public class ShopController {
      * @param id 门店ID
      * @param id 门店ID
      * @return 设备列表
      * @return 设备列表
      */
      */
+    @RequirePermission("shop:read")
     @GetMapping("/{id}/devices")
     @GetMapping("/{id}/devices")
     public Result<List<Map<String, Object>>> getDevices(@PathVariable Long id) {
     public Result<List<Map<String, Object>>> getDevices(@PathVariable Long id) {
         List<Map<String, Object>> devices = shopService.getDevicesByShopId(id);
         List<Map<String, Object>> devices = shopService.getDevicesByShopId(id);
@@ -173,6 +182,7 @@ public class ShopController {
      * @param params 设备ID参数
      * @param params 设备ID参数
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("shop:update")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "关联设备到门店")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "关联设备到门店")
     @PostMapping("/{id}/devices")
     @PostMapping("/{id}/devices")
     public Result<String> linkDevice(@PathVariable Long id, @RequestBody Map<String, Object> params) {
     public Result<String> linkDevice(@PathVariable Long id, @RequestBody Map<String, Object> params) {
@@ -191,6 +201,7 @@ public class ShopController {
      * @param params 设备ID列表参数
      * @param params 设备ID列表参数
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("shop:update")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "批量关联设备到门店")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "批量关联设备到门店")
     @PostMapping("/{id}/devices/batch")
     @PostMapping("/{id}/devices/batch")
     public Result<Map<String, Object>> batchLinkDevices(@PathVariable Long id, @RequestBody Map<String, Object> params) {
     public Result<Map<String, Object>> batchLinkDevices(@PathVariable Long id, @RequestBody Map<String, Object> params) {
@@ -215,6 +226,7 @@ public class ShopController {
      * @param deviceId 设备ID
      * @param deviceId 设备ID
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("shop:update")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "移除门店设备关联")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "移除门店设备关联")
     @DeleteMapping("/{id}/devices/{deviceId}")
     @DeleteMapping("/{id}/devices/{deviceId}")
     public Result<String> unlinkDevice(@PathVariable Long id, @PathVariable Long deviceId) {
     public Result<String> unlinkDevice(@PathVariable Long id, @PathVariable Long deviceId) {
@@ -232,6 +244,7 @@ public class ShopController {
      * @param params 设备ID列表参数
      * @param params 设备ID列表参数
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("shop:update")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "批量移除设备关联")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "批量移除设备关联")
     @DeleteMapping("/{id}/devices/batch")
     @DeleteMapping("/{id}/devices/batch")
     public Result<Map<String, Object>> batchUnlinkDevices(@PathVariable Long id, @RequestBody Map<String, Object> params) {
     public Result<Map<String, Object>> batchUnlinkDevices(@PathVariable Long id, @RequestBody Map<String, Object> params) {
@@ -254,6 +267,7 @@ public class ShopController {
      * 获取未关联门店的设备列表
      * 获取未关联门店的设备列表
      * @return 设备列表
      * @return 设备列表
      */
      */
+    @RequirePermission("shop:read")
     @GetMapping("/unlinked-devices")
     @GetMapping("/unlinked-devices")
     public Result<List<Device>> getUnlinkedDevices() {
     public Result<List<Device>> getUnlinkedDevices() {
         List<Device> devices = deviceService.getUnlinkedDevices();
         List<Device> devices = deviceService.getUnlinkedDevices();
@@ -267,6 +281,7 @@ public class ShopController {
      * @param id 门店ID
      * @param id 门店ID
      * @return 补货员列表
      * @return 补货员列表
      */
      */
+    @RequirePermission("shop:read")
     @GetMapping("/{id}/replenishers")
     @GetMapping("/{id}/replenishers")
     public Result<List<ShopReplenisher>> getReplenishers(@PathVariable Long id) {
     public Result<List<ShopReplenisher>> getReplenishers(@PathVariable Long id) {
         List<ShopReplenisher> replenishers = shopReplenisherService.getReplenishersByShopId(id);
         List<ShopReplenisher> replenishers = shopReplenisherService.getReplenishersByShopId(id);
@@ -279,6 +294,7 @@ public class ShopController {
      * @param params 管理员ID参数
      * @param params 管理员ID参数
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("shop:update")
     @Log(module = "门店管理", operation = OperationType.INSERT, summary = "添加门店补货员")
     @Log(module = "门店管理", operation = OperationType.INSERT, summary = "添加门店补货员")
     @PostMapping("/{id}/replenishers")
     @PostMapping("/{id}/replenishers")
     public Result<String> addReplenisher(@PathVariable Long id, @RequestBody Map<String, Object> params) {
     public Result<String> addReplenisher(@PathVariable Long id, @RequestBody Map<String, Object> params) {
@@ -292,6 +308,7 @@ public class ShopController {
      * @param params 管理员ID列表参数
      * @param params 管理员ID列表参数
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("shop:update")
     @Log(module = "门店管理", operation = OperationType.INSERT, summary = "批量添加门店补货员")
     @Log(module = "门店管理", operation = OperationType.INSERT, summary = "批量添加门店补货员")
     @PostMapping("/{id}/replenishers/batch")
     @PostMapping("/{id}/replenishers/batch")
     public Result<Map<String, Object>> batchAddReplenishers(@PathVariable Long id, @RequestBody Map<String, Object> params) {
     public Result<Map<String, Object>> batchAddReplenishers(@PathVariable Long id, @RequestBody Map<String, Object> params) {
@@ -316,6 +333,7 @@ public class ShopController {
      * @param adminId 管理员ID
      * @param adminId 管理员ID
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("shop:update")
     @Log(module = "门店管理", operation = OperationType.DELETE, summary = "移除门店补货员")
     @Log(module = "门店管理", operation = OperationType.DELETE, summary = "移除门店补货员")
     @DeleteMapping("/{id}/replenishers/{adminId}")
     @DeleteMapping("/{id}/replenishers/{adminId}")
     public Result<String> removeReplenisher(@PathVariable Long id, @PathVariable Long adminId) {
     public Result<String> removeReplenisher(@PathVariable Long id, @PathVariable Long adminId) {
@@ -328,6 +346,7 @@ public class ShopController {
      * @param params 管理员ID列表参数
      * @param params 管理员ID列表参数
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("shop:update")
     @Log(module = "门店管理", operation = OperationType.DELETE, summary = "批量移除门店补货员")
     @Log(module = "门店管理", operation = OperationType.DELETE, summary = "批量移除门店补货员")
     @DeleteMapping("/{id}/replenishers/batch")
     @DeleteMapping("/{id}/replenishers/batch")
     public Result<Map<String, Object>> batchRemoveReplenishers(@PathVariable Long id, @RequestBody Map<String, Object> params) {
     public Result<Map<String, Object>> batchRemoveReplenishers(@PathVariable Long id, @RequestBody Map<String, Object> params) {
@@ -352,6 +371,7 @@ public class ShopController {
      * @param params 状态参数
      * @param params 状态参数
      * @return 操作结果
      * @return 操作结果
      */
      */
+    @RequirePermission("shop:update")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "更新补货员状态")
     @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "更新补货员状态")
     @PutMapping("/replenishers/{id}/status")
     @PutMapping("/replenishers/{id}/status")
     public Result<String> updateReplenisherStatus(@PathVariable Long id, @RequestBody Map<String, Object> params) {
     public Result<String> updateReplenisherStatus(@PathVariable Long id, @RequestBody Map<String, Object> params) {
@@ -363,6 +383,7 @@ public class ShopController {
      * 获取可选的管理员列表(用于添加补货员)
      * 获取可选的管理员列表(用于添加补货员)
      * @return 管理员列表
      * @return 管理员列表
      */
      */
+    @RequirePermission("shop:read")
     @GetMapping("/available-users")
     @GetMapping("/available-users")
     public Result<List<Admin>> getAvailableUsers(@RequestParam(required = false) String keyword) {
     public Result<List<Admin>> getAvailableUsers(@RequestParam(required = false) String keyword) {
         List<Admin> admins = adminService.getAvailableAdmins(keyword);
         List<Admin> admins = adminService.getAvailableAdmins(keyword);

+ 43 - 0
haha-admin/src/main/java/com/haha/admin/service/impl/AdminLoginServiceImpl.java

@@ -8,14 +8,18 @@ import com.haha.common.vo.Result;
 import com.haha.common.vo.UserVO;
 import com.haha.common.vo.UserVO;
 import com.haha.entity.Admin;
 import com.haha.entity.Admin;
 import com.haha.mapper.AdminMapper;
 import com.haha.mapper.AdminMapper;
+import com.haha.service.DataPermissionService;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 
 /**
 /**
  * 管理员登录服务实现
  * 管理员登录服务实现
@@ -26,6 +30,9 @@ public class AdminLoginServiceImpl implements AdminLoginService {
     
     
     @Autowired
     @Autowired
     private AdminMapper adminMapper;
     private AdminMapper adminMapper;
+
+    @Autowired
+    private DataPermissionService dataPermissionService;
     
     
     private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
     private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
     
     
@@ -67,6 +74,10 @@ public class AdminLoginServiceImpl implements AdminLoginService {
                 StpUtil.getSession().set("realName", admin.getRealName());
                 StpUtil.getSession().set("realName", admin.getRealName());
                 StpUtil.getSession().set("roleIds", admin.getRoleIds());
                 StpUtil.getSession().set("roleIds", admin.getRoleIds());
                 
                 
+                // 获取并存储用户权限列表
+                List<String> permissions = getUserPermissions("1");
+                StpUtil.getSession().set("permissions", permissions);
+                
                 log.info("【临时测试账号】登录成功: username={}, userId={}", username, admin.getId());
                 log.info("【临时测试账号】登录成功: username={}, userId={}", username, admin.getId());
                 
                 
                 // 构建返回数据
                 // 构建返回数据
@@ -122,6 +133,10 @@ public class AdminLoginServiceImpl implements AdminLoginService {
             StpUtil.getSession().set("realName", admin.getRealName());
             StpUtil.getSession().set("realName", admin.getRealName());
             StpUtil.getSession().set("roleIds", admin.getRoleIds());
             StpUtil.getSession().set("roleIds", admin.getRoleIds());
             
             
+            // 获取并存储用户权限列表
+            List<String> permissions = getUserPermissions(admin.getRoleIds());
+            StpUtil.getSession().set("permissions", permissions);
+            
             log.info("管理员登录成功: username={}, userId={}", username, admin.getId());
             log.info("管理员登录成功: username={}, userId={}", username, admin.getId());
             
             
             // 构建返回数据
             // 构建返回数据
@@ -164,6 +179,10 @@ public class AdminLoginServiceImpl implements AdminLoginService {
             info.put("department", admin.getDepartment());
             info.put("department", admin.getDepartment());
             info.put("roleIds", admin.getRoleIds());
             info.put("roleIds", admin.getRoleIds());
             
             
+            // 获取用户权限列表
+            List<String> permissions = getUserPermissions(admin.getRoleIds());
+            info.put("permissions", permissions);
+            
             return Result.success("获取成功", info);
             return Result.success("获取成功", info);
             
             
         } catch (Exception e) {
         } catch (Exception e) {
@@ -171,4 +190,28 @@ public class AdminLoginServiceImpl implements AdminLoginService {
             return Result.error(500, "获取信息失败: " + e.getMessage());
             return Result.error(500, "获取信息失败: " + e.getMessage());
         }
         }
     }
     }
+
+    /**
+     * 根据角色ID列表获取用户权限
+     * @param roleIdsStr 角色ID字符串(逗号分隔)
+     * @return 权限编码列表
+     */
+    private List<String> getUserPermissions(String roleIdsStr) {
+        if (roleIdsStr == null || roleIdsStr.trim().isEmpty()) {
+            return List.of();
+        }
+        
+        try {
+            List<Long> roleIds = Arrays.stream(roleIdsStr.split(","))
+                    .map(String::trim)
+                    .filter(s -> !s.isEmpty())
+                    .map(Long::parseLong)
+                    .collect(Collectors.toList());
+            
+            return dataPermissionService.getPermissionCodesByRoleIds(roleIds);
+        } catch (Exception e) {
+            log.error("获取用户权限失败: roleIds={}, error={}", roleIdsStr, e.getMessage());
+            return List.of();
+        }
+    }
 }
 }

+ 131 - 0
haha-admin/src/main/resources/sql/data_permission.sql

@@ -0,0 +1,131 @@
+-- =====================================================
+-- 数据权限系统表结构
+-- 创建时间: 2026-02-15
+-- 说明: 用于实现基于CRUD四个维度的数据权限控制
+-- =====================================================
+
+-- 1. 数据权限表
+DROP TABLE IF EXISTS t_data_permission;
+CREATE TABLE t_data_permission (
+    id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
+    permission_code VARCHAR(100) NOT NULL COMMENT '权限编码(如: product:create)',
+    permission_name VARCHAR(100) NOT NULL COMMENT '权限名称(如: 商品创建)',
+    module_code VARCHAR(50) NOT NULL COMMENT '模块编码(如: product)',
+    module_name VARCHAR(100) NOT NULL COMMENT '模块名称(如: 商品管理)',
+    operation_type VARCHAR(20) NOT NULL COMMENT '操作类型: create/read/update/delete/execute',
+    description VARCHAR(255) COMMENT '权限描述',
+    sort_order INT DEFAULT 0 COMMENT '排序',
+    status TINYINT DEFAULT 1 COMMENT '状态: 1-启用, 0-禁用',
+    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+    UNIQUE KEY uk_permission_code (permission_code),
+    KEY idx_module_code (module_code),
+    KEY idx_operation_type (operation_type)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据权限表';
+
+-- 2. 角色权限关联表
+DROP TABLE IF EXISTS t_role_permission;
+CREATE TABLE t_role_permission (
+    id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
+    role_id BIGINT NOT NULL COMMENT '角色ID',
+    permission_id BIGINT NOT NULL COMMENT '权限ID',
+    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    UNIQUE KEY uk_role_permission (role_id, permission_id),
+    KEY idx_role_id (role_id),
+    KEY idx_permission_id (permission_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色权限关联表';
+
+-- =====================================================
+-- 初始化权限数据
+-- =====================================================
+
+-- 清空现有权限数据
+TRUNCATE TABLE t_data_permission;
+
+-- 商品管理模块
+INSERT INTO t_data_permission (permission_code, permission_name, module_code, module_name, operation_type, description, sort_order) VALUES
+('product:create', '创建商品', 'product', '商品管理', 'create', '添加新商品', 1),
+('product:read', '查询商品', 'product', '商品管理', 'read', '查看商品列表和详情', 2),
+('product:update', '修改商品', 'product', '商品管理', 'update', '编辑商品信息', 3),
+('product:delete', '删除商品', 'product', '商品管理', 'delete', '删除商品', 4);
+
+-- 设备管理模块
+INSERT INTO t_data_permission (permission_code, permission_name, module_code, module_name, operation_type, description, sort_order) VALUES
+('device:create', '添加设备', 'device', '设备管理', 'create', '添加新设备', 11),
+('device:read', '查询设备', 'device', '设备管理', 'read', '查看设备列表和详情', 12),
+('device:update', '修改设备', 'device', '设备管理', 'update', '编辑设备信息', 13),
+('device:delete', '删除设备', 'device', '设备管理', 'delete', '删除设备', 14);
+
+-- 订单管理模块
+INSERT INTO t_data_permission (permission_code, permission_name, module_code, module_name, operation_type, description, sort_order) VALUES
+('order:create', '创建订单', 'order', '订单管理', 'create', '手动创建订单', 21),
+('order:read', '查询订单', 'order', '订单管理', 'read', '查看订单列表和详情', 22),
+('order:update', '修改订单', 'order', '订单管理', 'update', '修改订单信息', 23),
+('order:delete', '删除订单', 'order', '订单管理', 'delete', '删除订单', 24);
+
+-- 门店管理模块
+INSERT INTO t_data_permission (permission_code, permission_name, module_code, module_name, operation_type, description, sort_order) VALUES
+('shop:create', '添加门店', 'shop', '门店管理', 'create', '添加新门店', 31),
+('shop:read', '查询门店', 'shop', '门店管理', 'read', '查看门店列表和详情', 32),
+('shop:update', '修改门店', 'shop', '门店管理', 'update', '编辑门店信息', 33),
+('shop:delete', '删除门店', 'shop', '门店管理', 'delete', '删除门店', 34);
+
+-- 库存管理模块
+INSERT INTO t_data_permission (permission_code, permission_name, module_code, module_name, operation_type, description, sort_order) VALUES
+('inventory:create', '创建库存记录', 'inventory', '库存管理', 'create', '创建库存记录', 41),
+('inventory:read', '查询库存', 'inventory', '库存管理', 'read', '查看库存信息', 42),
+('inventory:update', '修改库存', 'inventory', '库存管理', 'update', '修改库存信息', 43),
+('inventory:delete', '删除库存记录', 'inventory', '库存管理', 'delete', '删除库存记录', 44);
+
+-- 新品申请模块
+INSERT INTO t_data_permission (permission_code, permission_name, module_code, module_name, operation_type, description, sort_order) VALUES
+('product-apply:create', '提交新品申请', 'product-apply', '新品申请', 'create', '提交新品申请', 51),
+('product-apply:read', '查询新品申请', 'product-apply', '新品申请', 'read', '查看新品申请列表和详情', 52),
+('product-apply:update', '修改新品申请', 'product-apply', '新品申请', 'update', '修改新品申请或审核', 53),
+('product-apply:delete', '删除新品申请', 'product-apply', '新品申请', 'delete', '删除新品申请', 54);
+
+-- 用户管理模块
+INSERT INTO t_data_permission (permission_code, permission_name, module_code, module_name, operation_type, description, sort_order) VALUES
+('admin:create', '添加用户', 'admin', '用户管理', 'create', '添加管理员账号', 61),
+('admin:read', '查询用户', 'admin', '用户管理', 'read', '查看用户列表和详情', 62),
+('admin:update', '修改用户', 'admin', '用户管理', 'update', '编辑用户信息', 63),
+('admin:delete', '删除用户', 'admin', '用户管理', 'delete', '删除用户账号', 64);
+
+-- 角色管理模块
+INSERT INTO t_data_permission (permission_code, permission_name, module_code, module_name, operation_type, description, sort_order) VALUES
+('role:create', '添加角色', 'role', '角色管理', 'create', '添加新角色', 71),
+('role:read', '查询角色', 'role', '角色管理', 'read', '查看角色列表和详情', 72),
+('role:update', '修改角色', 'role', '角色管理', 'update', '编辑角色信息和权限配置', 73),
+('role:delete', '删除角色', 'role', '角色管理', 'delete', '删除角色', 74);
+
+-- 公告管理模块
+INSERT INTO t_data_permission (permission_code, permission_name, module_code, module_name, operation_type, description, sort_order) VALUES
+('announcement:create', '发布公告', 'announcement', '公告管理', 'create', '发布新公告', 81),
+('announcement:read', '查询公告', 'announcement', '公告管理', 'read', '查看公告列表和详情', 82),
+('announcement:update', '修改公告', 'announcement', '公告管理', 'update', '编辑公告内容', 83),
+('announcement:delete', '删除公告', 'announcement', '公告管理', 'delete', '删除公告', 84);
+
+-- 数据同步模块
+INSERT INTO t_data_permission (permission_code, permission_name, module_code, module_name, operation_type, description, sort_order) VALUES
+('sync:read', '查询同步记录', 'sync', '数据同步', 'read', '查看数据同步记录', 91),
+('sync:execute', '执行同步', 'sync', '数据同步', 'execute', '执行数据同步操作', 92);
+
+-- 仪表盘模块
+INSERT INTO t_data_permission (permission_code, permission_name, module_code, module_name, operation_type, description, sort_order) VALUES
+('dashboard:read', '查看仪表盘', 'dashboard', '仪表盘', 'read', '查看首页仪表盘数据', 101);
+
+-- 操作日志模块
+INSERT INTO t_data_permission (permission_code, permission_name, module_code, module_name, operation_type, description, sort_order) VALUES
+('operation-log:read', '查询操作日志', 'operation-log', '操作日志', 'read', '查看操作日志记录', 111),
+('operation-log:delete', '删除操作日志', 'operation-log', '操作日志', 'delete', '删除或清空操作日志', 112);
+
+-- 客户管理模块
+INSERT INTO t_data_permission (permission_code, permission_name, module_code, module_name, operation_type, description, sort_order) VALUES
+('customer:read', '查询客户', 'customer', '客户管理', 'read', '查看客户列表和详情', 121),
+('customer:update', '修改客户', 'customer', '客户管理', 'update', '编辑客户信息', 123);
+
+-- =====================================================
+-- 为超级管理员角色(role.id=1)分配所有权限
+-- =====================================================
+INSERT INTO t_role_permission (role_id, permission_id)
+SELECT 1, id FROM t_data_permission WHERE status = 1;

+ 73 - 0
haha-entity/src/main/java/com/haha/entity/DataPermission.java

@@ -0,0 +1,73 @@
+package com.haha.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 数据权限实体类
+ */
+@Data
+@TableName("t_data_permission")
+public class DataPermission implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 权限编码(如: product:create)
+     */
+    private String permissionCode;
+
+    /**
+     * 权限名称(如: 商品创建)
+     */
+    private String permissionName;
+
+    /**
+     * 模块编码(如: product)
+     */
+    private String moduleCode;
+
+    /**
+     * 模块名称(如: 商品管理)
+     */
+    private String moduleName;
+
+    /**
+     * 操作类型: create/read/update/delete/execute
+     */
+    private String operationType;
+
+    /**
+     * 权限描述
+     */
+    private String description;
+
+    /**
+     * 排序
+     */
+    private Integer sortOrder;
+
+    /**
+     * 状态: 1-启用, 0-禁用
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 38 - 0
haha-entity/src/main/java/com/haha/entity/RolePermission.java

@@ -0,0 +1,38 @@
+package com.haha.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 角色权限关联实体类
+ */
+@Data
+@TableName("t_role_permission")
+public class RolePermission implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 角色ID
+     */
+    private Long roleId;
+
+    /**
+     * 权限ID
+     */
+    private Long permissionId;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+}

+ 55 - 0
haha-mapper/src/main/java/com/haha/mapper/DataPermissionMapper.java

@@ -0,0 +1,55 @@
+package com.haha.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.haha.entity.DataPermission;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 数据权限Mapper接口
+ */
+@Mapper
+public interface DataPermissionMapper extends BaseMapper<DataPermission> {
+
+    /**
+     * 根据模块编码查询权限列表
+     * @param moduleCode 模块编码
+     * @return 权限列表
+     */
+    List<DataPermission> selectByModuleCode(@Param("moduleCode") String moduleCode);
+
+    /**
+     * 查询所有启用的权限
+     * @return 权限列表
+     */
+    List<DataPermission> selectAllEnabled();
+
+    /**
+     * 根据权限编码查询权限
+     * @param permissionCode 权限编码
+     * @return 权限信息
+     */
+    DataPermission selectByPermissionCode(@Param("permissionCode") String permissionCode);
+
+    /**
+     * 按模块分组查询所有权限
+     * @return 权限列表(按模块分组)
+     */
+    List<DataPermission> selectAllGroupByModule();
+
+    /**
+     * 根据角色ID查询权限列表
+     * @param roleId 角色ID
+     * @return 权限列表
+     */
+    List<DataPermission> selectByRoleId(@Param("roleId") Long roleId);
+
+    /**
+     * 根据角色ID列表查询权限编码列表
+     * @param roleIds 角色ID列表
+     * @return 权限编码列表
+     */
+    List<String> selectPermissionCodesByRoleIds(@Param("roleIds") List<Long> roleIds);
+}

+ 45 - 0
haha-mapper/src/main/java/com/haha/mapper/RolePermissionMapper.java

@@ -0,0 +1,45 @@
+package com.haha.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.haha.entity.RolePermission;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 角色权限关联Mapper接口
+ */
+@Mapper
+public interface RolePermissionMapper extends BaseMapper<RolePermission> {
+
+    /**
+     * 根据角色ID删除权限关联
+     * @param roleId 角色ID
+     * @return 删除数量
+     */
+    int deleteByRoleId(@Param("roleId") Long roleId);
+
+    /**
+     * 批量插入角色权限关联
+     * @param roleId 角色ID
+     * @param permissionIds 权限ID列表
+     * @return 插入数量
+     */
+    int batchInsert(@Param("roleId") Long roleId, @Param("permissionIds") List<Long> permissionIds);
+
+    /**
+     * 根据角色ID查询权限ID列表
+     * @param roleId 角色ID
+     * @return 权限ID列表
+     */
+    List<Long> selectPermissionIdsByRoleId(@Param("roleId") Long roleId);
+
+    /**
+     * 检查角色是否拥有指定权限
+     * @param roleId 角色ID
+     * @param permissionId 权限ID
+     * @return 是否存在
+     */
+    int checkRoleHasPermission(@Param("roleId") Long roleId, @Param("permissionId") Long permissionId);
+}

+ 80 - 0
haha-mapper/src/main/resources/mapper/DataPermissionMapper.xml

@@ -0,0 +1,80 @@
+<?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.haha.mapper.DataPermissionMapper">
+
+    <!-- 结果映射 -->
+    <resultMap id="BaseResultMap" type="com.haha.entity.DataPermission">
+        <id column="id" property="id"/>
+        <result column="permission_code" property="permissionCode"/>
+        <result column="permission_name" property="permissionName"/>
+        <result column="module_code" property="moduleCode"/>
+        <result column="module_name" property="moduleName"/>
+        <result column="operation_type" property="operationType"/>
+        <result column="description" property="description"/>
+        <result column="sort_order" property="sortOrder"/>
+        <result column="status" property="status"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_time" property="updateTime"/>
+    </resultMap>
+
+    <!-- 基础列 -->
+    <sql id="Base_Column_List">
+        id, permission_code, permission_name, module_code, module_name, operation_type,
+        description, sort_order, status, create_time, update_time
+    </sql>
+
+    <!-- 根据模块编码查询权限列表 -->
+    <select id="selectByModuleCode" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM t_data_permission
+        WHERE module_code = #{moduleCode}
+        AND status = 1
+        ORDER BY sort_order
+    </select>
+
+    <!-- 查询所有启用的权限 -->
+    <select id="selectAllEnabled" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM t_data_permission
+        WHERE status = 1
+        ORDER BY sort_order
+    </select>
+
+    <!-- 根据权限编码查询权限 -->
+    <select id="selectByPermissionCode" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM t_data_permission
+        WHERE permission_code = #{permissionCode}
+    </select>
+
+    <!-- 按模块分组查询所有权限 -->
+    <select id="selectAllGroupByModule" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM t_data_permission
+        WHERE status = 1
+        ORDER BY module_code, sort_order
+    </select>
+
+    <!-- 根据角色ID查询权限列表 -->
+    <select id="selectByRoleId" resultMap="BaseResultMap">
+        SELECT dp.*
+        FROM t_data_permission dp
+        INNER JOIN t_role_permission rp ON dp.id = rp.permission_id
+        WHERE rp.role_id = #{roleId}
+        AND dp.status = 1
+        ORDER BY dp.sort_order
+    </select>
+
+    <!-- 根据角色ID列表查询权限编码列表 -->
+    <select id="selectPermissionCodesByRoleIds" resultType="java.lang.String">
+        SELECT DISTINCT dp.permission_code
+        FROM t_data_permission dp
+        INNER JOIN t_role_permission rp ON dp.id = rp.permission_id
+        WHERE rp.role_id IN
+        <foreach collection="roleIds" item="roleId" open="(" separator="," close=")">
+            #{roleId}
+        </foreach>
+        AND dp.status = 1
+    </select>
+
+</mapper>

+ 43 - 0
haha-mapper/src/main/resources/mapper/RolePermissionMapper.xml

@@ -0,0 +1,43 @@
+<?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.haha.mapper.RolePermissionMapper">
+
+    <!-- 结果映射 -->
+    <resultMap id="BaseResultMap" type="com.haha.entity.RolePermission">
+        <id column="id" property="id"/>
+        <result column="role_id" property="roleId"/>
+        <result column="permission_id" property="permissionId"/>
+        <result column="create_time" property="createTime"/>
+    </resultMap>
+
+    <!-- 根据角色ID删除权限关联 -->
+    <delete id="deleteByRoleId">
+        DELETE FROM t_role_permission
+        WHERE role_id = #{roleId}
+    </delete>
+
+    <!-- 批量插入角色权限关联 -->
+    <insert id="batchInsert">
+        INSERT INTO t_role_permission (role_id, permission_id, create_time)
+        VALUES
+        <foreach collection="permissionIds" item="permissionId" separator=",">
+            (#{roleId}, #{permissionId}, NOW())
+        </foreach>
+    </insert>
+
+    <!-- 根据角色ID查询权限ID列表 -->
+    <select id="selectPermissionIdsByRoleId" resultType="java.lang.Long">
+        SELECT permission_id
+        FROM t_role_permission
+        WHERE role_id = #{roleId}
+    </select>
+
+    <!-- 检查角色是否拥有指定权限 -->
+    <select id="checkRoleHasPermission" resultType="int">
+        SELECT COUNT(*)
+        FROM t_role_permission
+        WHERE role_id = #{roleId}
+        AND permission_id = #{permissionId}
+    </select>
+
+</mapper>

+ 61 - 0
haha-service/src/main/java/com/haha/service/DataPermissionService.java

@@ -0,0 +1,61 @@
+package com.haha.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.haha.common.vo.Result;
+import com.haha.entity.DataPermission;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 数据权限服务接口
+ */
+public interface DataPermissionService extends IService<DataPermission> {
+
+    /**
+     * 获取所有权限列表(按模块分组)
+     * @return 权限列表(按模块分组)
+     */
+    Result<List<DataPermission>> getAllPermissions();
+
+    /**
+     * 获取所有权限(按模块分组返回)
+     * @return 模块->权限列表的映射
+     */
+    Result<Map<String, List<DataPermission>>> getPermissionsGroupByModule();
+
+    /**
+     * 根据模块编码获取权限列表
+     * @param moduleCode 模块编码
+     * @return 权限列表
+     */
+    Result<List<DataPermission>> getPermissionsByModule(String moduleCode);
+
+    /**
+     * 根据角色ID获取权限列表
+     * @param roleId 角色ID
+     * @return 权限列表
+     */
+    Result<List<DataPermission>> getPermissionsByRoleId(Long roleId);
+
+    /**
+     * 根据角色ID获取权限编码列表
+     * @param roleId 角色ID
+     * @return 权限编码列表
+     */
+    Result<List<String>> getPermissionCodesByRoleId(Long roleId);
+
+    /**
+     * 根据角色ID列表获取权限编码列表
+     * @param roleIds 角色ID列表
+     * @return 权限编码列表
+     */
+    List<String> getPermissionCodesByRoleIds(List<Long> roleIds);
+
+    /**
+     * 检查权限编码是否存在
+     * @param permissionCode 权限编码
+     * @return 是否存在
+     */
+    boolean existsByPermissionCode(String permissionCode);
+}

+ 15 - 0
haha-service/src/main/java/com/haha/service/RoleService.java

@@ -48,4 +48,19 @@ public interface RoleService extends IService<Role> {
      * @return 删除结果
      * @return 删除结果
      */
      */
     Result<Void> deleteRole(Long id);
     Result<Void> deleteRole(Long id);
+
+    /**
+     * 获取角色的权限ID列表
+     * @param roleId 角色ID
+     * @return 权限ID列表
+     */
+    Result<List<Long>> getRolePermissionIds(Long roleId);
+
+    /**
+     * 更新角色权限
+     * @param roleId 角色ID
+     * @param permissionIds 权限ID列表
+     * @return 更新结果
+     */
+    Result<Void> updateRolePermissions(Long roleId, List<Long> permissionIds);
 }
 }

+ 115 - 0
haha-service/src/main/java/com/haha/service/impl/DataPermissionServiceImpl.java

@@ -0,0 +1,115 @@
+package com.haha.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.haha.common.vo.Result;
+import com.haha.entity.DataPermission;
+import com.haha.mapper.DataPermissionMapper;
+import com.haha.service.DataPermissionService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 数据权限服务实现类
+ */
+@Slf4j
+@Service
+public class DataPermissionServiceImpl extends ServiceImpl<DataPermissionMapper, DataPermission> implements DataPermissionService {
+
+    @Autowired
+    private DataPermissionMapper dataPermissionMapper;
+
+    @Override
+    public Result<List<DataPermission>> getAllPermissions() {
+        try {
+            List<DataPermission> permissions = dataPermissionMapper.selectAllEnabled();
+            return Result.success("查询成功", permissions);
+        } catch (Exception e) {
+            log.error("查询所有权限失败", e);
+            return Result.error(500, "查询失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public Result<Map<String, List<DataPermission>>> getPermissionsGroupByModule() {
+        try {
+            List<DataPermission> permissions = dataPermissionMapper.selectAllGroupByModule();
+            
+            // 按模块分组
+            Map<String, List<DataPermission>> groupedPermissions = new LinkedHashMap<>();
+            for (DataPermission permission : permissions) {
+                String moduleName = permission.getModuleName();
+                if (!groupedPermissions.containsKey(moduleName)) {
+                    groupedPermissions.put(moduleName, new ArrayList<>());
+                }
+                groupedPermissions.get(moduleName).add(permission);
+            }
+            
+            return Result.success("查询成功", groupedPermissions);
+        } catch (Exception e) {
+            log.error("查询分组权限失败", e);
+            return Result.error(500, "查询失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public Result<List<DataPermission>> getPermissionsByModule(String moduleCode) {
+        try {
+            List<DataPermission> permissions = dataPermissionMapper.selectByModuleCode(moduleCode);
+            return Result.success("查询成功", permissions);
+        } catch (Exception e) {
+            log.error("查询模块权限失败, moduleCode={}", moduleCode, e);
+            return Result.error(500, "查询失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public Result<List<DataPermission>> getPermissionsByRoleId(Long roleId) {
+        try {
+            List<DataPermission> permissions = dataPermissionMapper.selectByRoleId(roleId);
+            return Result.success("查询成功", permissions);
+        } catch (Exception e) {
+            log.error("查询角色权限失败, roleId={}", roleId, e);
+            return Result.error(500, "查询失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public Result<List<String>> getPermissionCodesByRoleId(Long roleId) {
+        try {
+            List<DataPermission> permissions = dataPermissionMapper.selectByRoleId(roleId);
+            List<String> codes = new ArrayList<>();
+            for (DataPermission permission : permissions) {
+                codes.add(permission.getPermissionCode());
+            }
+            return Result.success("查询成功", codes);
+        } catch (Exception e) {
+            log.error("查询角色权限编码失败, roleId={}", roleId, e);
+            return Result.error(500, "查询失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public List<String> getPermissionCodesByRoleIds(List<Long> roleIds) {
+        if (roleIds == null || roleIds.isEmpty()) {
+            return new ArrayList<>();
+        }
+        try {
+            return dataPermissionMapper.selectPermissionCodesByRoleIds(roleIds);
+        } catch (Exception e) {
+            log.error("查询角色权限编码失败, roleIds={}", roleIds, e);
+            return new ArrayList<>();
+        }
+    }
+
+    @Override
+    public boolean existsByPermissionCode(String permissionCode) {
+        DataPermission permission = dataPermissionMapper.selectByPermissionCode(permissionCode);
+        return permission != null && permission.getStatus() == 1;
+    }
+}

+ 50 - 0
haha-service/src/main/java/com/haha/service/impl/RoleServiceImpl.java

@@ -7,9 +7,12 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.haha.common.vo.Result;
 import com.haha.common.vo.Result;
 import com.haha.entity.Role;
 import com.haha.entity.Role;
 import com.haha.mapper.RoleMapper;
 import com.haha.mapper.RoleMapper;
+import com.haha.mapper.RolePermissionMapper;
 import com.haha.service.RoleService;
 import com.haha.service.RoleService;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
 
 
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
@@ -22,6 +25,9 @@ import java.util.List;
 @Service
 @Service
 public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
 public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
     
     
+    @Autowired
+    private RolePermissionMapper rolePermissionMapper;
+    
     @Override
     @Override
     public Result<IPage<Role>> getRoleList(int page, int pageSize, String name, String code) {
     public Result<IPage<Role>> getRoleList(int page, int pageSize, String name, String code) {
         try {
         try {
@@ -139,4 +145,48 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
             return Result.error(500, "删除失败: " + e.getMessage());
             return Result.error(500, "删除失败: " + e.getMessage());
         }
         }
     }
     }
+
+    @Override
+    public Result<List<Long>> getRolePermissionIds(Long roleId) {
+        try {
+            // 检查角色是否存在
+            Role role = this.getById(roleId);
+            if (role == null) {
+                return Result.error(404, "角色不存在");
+            }
+            
+            List<Long> permissionIds = rolePermissionMapper.selectPermissionIdsByRoleId(roleId);
+            return Result.success("查询成功", permissionIds);
+            
+        } catch (Exception e) {
+            log.error("获取角色权限失败, roleId={}", roleId, e);
+            return Result.error(500, "查询失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result<Void> updateRolePermissions(Long roleId, List<Long> permissionIds) {
+        try {
+            // 检查角色是否存在
+            Role role = this.getById(roleId);
+            if (role == null) {
+                return Result.error(404, "角色不存在");
+            }
+            
+            // 先删除该角色的所有权限
+            rolePermissionMapper.deleteByRoleId(roleId);
+            
+            // 如果有新权限,批量插入
+            if (permissionIds != null && !permissionIds.isEmpty()) {
+                rolePermissionMapper.batchInsert(roleId, permissionIds);
+            }
+            
+            return Result.success("权限配置成功", null);
+            
+        } catch (Exception e) {
+            log.error("更新角色权限失败, roleId={}", roleId, e);
+            return Result.error(500, "权限配置失败: " + e.getMessage());
+        }
+    }
 }
 }