李学强 6 месяцев назад
Родитель
Сommit
9f1348c373
100 измененных файлов с 6519 добавлено и 7 удалено
  1. 7 7
      AGENTS.md
  2. 60 0
      kxs-admin/pom.xml
  3. 25 0
      kxs-admin/src/main/java/com/kxs/admin/biz/KxsAdminApplication.java
  4. 146 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysClientController.java
  5. 40 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysCommController.java
  6. 109 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysDeptController.java
  7. 224 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysDictController.java
  8. 102 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysFileController.java
  9. 61 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysImageCodeController.java
  10. 86 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysLogController.java
  11. 118 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysMenuController.java
  12. 123 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysPostController.java
  13. 149 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysPublicParamController.java
  14. 160 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysRoleController.java
  15. 88 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysRuleMakingController.java
  16. 188 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysUserController.java
  17. 216 0
      kxs-admin/src/main/java/com/kxs/admin/biz/controller/TokenController.java
  18. 123 0
      kxs-admin/src/main/java/com/kxs/admin/biz/security/LxqRemoteRegisteredClientRepository.java
  19. 103 0
      kxs-admin/src/main/java/com/kxs/admin/biz/security/LxqUserDetailsServiceImpl.java
  20. 95 0
      kxs-common/lxq-common-core/pom.xml
  21. 6 0
      kxs-common/lxq-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  22. 9 0
      kxs-common/lxq-common-core/src/main/resources/banner.txt
  23. 128 0
      kxs-common/lxq-common-core/src/main/resources/logback-spring.xml
  24. 99 0
      kxs-common/lxq-common-excel/pom.xml
  25. 1 0
      kxs-common/lxq-common-excel/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  26. 55 0
      kxs-common/lxq-common-idempotent/pom.xml
  27. 1 0
      kxs-common/lxq-common-idempotent/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  28. 54 0
      kxs-common/lxq-common-log/pom.xml
  29. 30 0
      kxs-common/lxq-common-log/src/main/resources/META-INF/spring-configuration-metadata.json
  30. 1 0
      kxs-common/lxq-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  31. 30 0
      kxs-common/lxq-common-mq/pom.xml
  32. 3 0
      kxs-common/lxq-common-mq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  33. 79 0
      kxs-common/lxq-common-mybatis/pom.xml
  34. 1 0
      kxs-common/lxq-common-mybatis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  35. 43 0
      kxs-common/lxq-common-oss/pom.xml
  36. 1 0
      kxs-common/lxq-common-oss/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  37. 57 0
      kxs-common/lxq-common-pay/pom.xml
  38. 1 0
      kxs-common/lxq-common-pay/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  39. 73 0
      kxs-common/lxq-common-security/pom.xml
  40. 4 0
      kxs-common/lxq-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  41. 40 0
      kxs-common/lxq-common-swagger/pom.xml
  42. 7 0
      kxs-common/lxq-common-swagger/src/main/resources/openapi-config.yaml
  43. 42 0
      kxs-common/pom.xml
  44. 13 0
      kxs-quartz/Dockerfile
  45. 146 0
      kxs-quartz/pom.xml
  46. 7 0
      kxs-quartz/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  47. 81 0
      kxs-system/pom.xml
  48. 35 0
      kxs-system/src/main/java/com/kxs/system/biz/config/AesConfigProperties.java
  49. 24 0
      kxs-system/src/main/java/com/kxs/system/biz/config/GatewayConfigProperties.java
  50. 80 0
      kxs-system/src/main/java/com/kxs/system/biz/config/SysConfigAutoConfiguration.java
  51. 29 0
      kxs-system/src/main/java/com/kxs/system/biz/constant/enums/SysErrorTypeEnum.java
  52. 91 0
      kxs-system/src/main/java/com/kxs/system/biz/domain/dto/SysLogDTO.java
  53. 16 0
      kxs-system/src/main/java/com/kxs/system/biz/domain/dto/SysRuleMakingDTO.java
  54. 42 0
      kxs-system/src/main/java/com/kxs/system/biz/domain/dto/UserDTO.java
  55. 35 0
      kxs-system/src/main/java/com/kxs/system/biz/domain/dto/UserInfo.java
  56. 20 0
      kxs-system/src/main/java/com/kxs/system/biz/domain/vo/RoleEditVO.java
  57. 65 0
      kxs-system/src/main/java/com/kxs/system/biz/domain/vo/RoleExcelVO.java
  58. 28 0
      kxs-system/src/main/java/com/kxs/system/biz/domain/vo/RoleVO.java
  59. 17 0
      kxs-system/src/main/java/com/kxs/system/biz/domain/vo/SysFeignInterfaceConfigVO.java
  60. 28 0
      kxs-system/src/main/java/com/kxs/system/biz/domain/vo/TokenVo.java
  61. 108 0
      kxs-system/src/main/java/com/kxs/system/biz/domain/vo/UserExcelVO.java
  62. 151 0
      kxs-system/src/main/java/com/kxs/system/biz/domain/vo/UserVO.java
  63. 77 0
      kxs-system/src/main/java/com/kxs/system/biz/event/SysLogListener.java
  64. 249 0
      kxs-system/src/main/java/com/kxs/system/biz/filter/RequestDecoderFilter.java
  65. 105 0
      kxs-system/src/main/java/com/kxs/system/biz/filter/ValidateCodeGatewayFilter.java
  66. 16 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysDeptMapper.java
  67. 16 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysDictItemMapper.java
  68. 18 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysDictMapper.java
  69. 17 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysFileMapper.java
  70. 16 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysLogMapper.java
  71. 25 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysMenuMapper.java
  72. 16 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysOauthClientDetailsMapper.java
  73. 25 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysPostMapper.java
  74. 16 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysPublicParamMapper.java
  75. 25 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysRoleMapper.java
  76. 16 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysRoleMenuMapper.java
  77. 17 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysRuleMakingMapper.java
  78. 52 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysUserMapper.java
  79. 19 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysUserPostMapper.java
  80. 16 0
      kxs-system/src/main/java/com/kxs/system/biz/mapper/SysUserRoleMapper.java
  81. 95 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysDept.java
  82. 96 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysDict.java
  83. 121 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysDictItem.java
  84. 107 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysFile.java
  85. 129 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysInterfaceConfig.java
  86. 149 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysLog.java
  87. 140 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysMenu.java
  88. 142 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysOauthClientDetails.java
  89. 98 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysPost.java
  90. 114 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysPublicParam.java
  91. 79 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysRole.java
  92. 40 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysRoleMenu.java
  93. 84 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysRulemaking.java
  94. 164 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysUser.java
  95. 34 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysUserPost.java
  96. 38 0
      kxs-system/src/main/java/com/kxs/system/biz/model/SysUserRole.java
  97. 38 0
      kxs-system/src/main/java/com/kxs/system/biz/service/SysDeptService.java
  98. 29 0
      kxs-system/src/main/java/com/kxs/system/biz/service/SysDictItemService.java
  99. 35 0
      kxs-system/src/main/java/com/kxs/system/biz/service/SysDictService.java
  100. 42 0
      kxs-system/src/main/java/com/kxs/system/biz/service/SysFileService.java

+ 7 - 7
AGENTS.md

@@ -40,16 +40,16 @@ mvn clean package -Pprod       # Production
 | Class/Interface | PascalCase | `SysUserController`, `UserDTO` |
 | Method/Variable | camelCase | `getUserById`, `saveUser()` |
 | Constant | UPPER_SNAKE_CASE | `DEFAULT_PAGE_SIZE`, `COMMON_STATUS` |
-| Package | `com.lxq.{module}.biz.{layer}` | `com.lxq.admin.biz.controller` |
+| Package | `com.kxs.{module}.biz.{layer}` | `com.kxs.admin.biz.controller` |
 
 ## Architecture Layers
 ```
-com.lxq.{module}.biz.controller/   # REST endpoints
-com.lxq.{module}.biz.service/       # Business logic
-com.lxq.{module}.biz.mapper/        # Data access
-com.lxq.{module}.biz.model/         # Entities
-com.lxq.{module}.biz.domain.dto/    # Input DTOs
-com.lxq.{module}.biz.domain.vo/     # Response VOs
+com.kxs.{module}.biz.controller/   # REST endpoints
+com.kxs.{module}.biz.service/       # Business logic
+com.kxs.{module}.biz.mapper/        # Data access
+com.kxs.{module}.biz.model/         # Entities
+com.kxs.{module}.biz.domain.dto/    # Input DTOs
+com.kxs.{module}.biz.domain.vo/     # Response VOs
 ```
 
 ## Layer Patterns

+ 60 - 0
kxs-admin/pom.xml

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>kxs</artifactId>
+        <groupId>com.kxs</groupId>
+        <version>3.5.9</version>
+    </parent>
+
+    <packaging>jar</packaging>
+    <artifactId>kxs-admin</artifactId>
+    <description>管理后台</description>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-captcha</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>kxs-system</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>kxs-quartz</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tomcat.embed</groupId>
+            <artifactId>tomcat-embed-core</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+            <!--打包java路径下的静态文件-->
+            <resource>
+                <directory>src/main/java</directory>
+                <filtering>false</filtering>
+                <includes>
+                    <include>**/*.xml</include>
+                </includes>
+            </resource>
+        </resources>
+        <plugins>
+            <!-- 该插件的作用是复制依赖的jar包到指定的文件夹里 -->
+            <plugin>
+                <!--该插件主要用途:构建可执行的JAR -->
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 25 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/KxsAdminApplication.java

@@ -0,0 +1,25 @@
+package com.kxs.admin.biz;
+
+import com.kxs.common.security.annotation.EnableAuthResourceServer;
+import com.kxs.common.security.annotation.EnableLoginResourceServer;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+/**
+ * @author 没秃顶的码农
+ * @date 2022年06月21日
+ * <p>
+ * 用户统一管理系统
+ */
+@SpringBootApplication
+@EnableLoginResourceServer
+@EnableAuthResourceServer
+@EnableAsync
+public class KxsAdminApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(KxsAdminApplication.class, args);
+	}
+
+}

+ 146 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysClientController.java

@@ -0,0 +1,146 @@
+package com.kxs.admin.biz.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.common.core.util.R;
+import com.kxs.common.excel.annotation.ResponseExcel;
+import com.kxs.common.log.annotation.SysLog;
+import com.kxs.common.security.annotation.Inner;
+import com.kxs.system.biz.model.SysOauthClientDetails;
+import com.kxs.system.biz.service.SysOauthClientDetailsService;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.AllArgsConstructor;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 前端控制器
+ * </p>
+ *
+ * @author 没秃顶的码农
+ * @date 2023/11/03
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/client")
+@Tag(description = "client", name = "客户端管理模块")
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class SysClientController {
+
+	private final SysOauthClientDetailsService clientDetailsService;
+
+	/**
+	 * 通过ID查询
+	 * @param clientId clientId
+	 * @return SysOauthClientDetails
+	 */
+	@GetMapping("getById")
+	public R getByClientId(@RequestParam("clientId") String clientId) {
+		SysOauthClientDetails details = clientDetailsService
+			.getOne(Wrappers.<SysOauthClientDetails>lambdaQuery().eq(SysOauthClientDetails::getClientId, clientId));
+		return R.ok(details);
+	}
+
+	/**
+	 * 简单分页查询
+	 * @param page 分页对象
+	 * @param sysOauthClientDetails 系统终端
+	 * @return
+	 */
+	@GetMapping("/page")
+	public R getOauthClientDetailsPage(@ParameterObject Page page,
+			@ParameterObject SysOauthClientDetails sysOauthClientDetails) {
+		LambdaQueryWrapper<SysOauthClientDetails> wrapper = Wrappers.<SysOauthClientDetails>lambdaQuery()
+			.like(StrUtil.isNotBlank(sysOauthClientDetails.getClientId()), SysOauthClientDetails::getClientId,
+					sysOauthClientDetails.getClientId())
+			.like(StrUtil.isNotBlank(sysOauthClientDetails.getClientSecret()), SysOauthClientDetails::getClientSecret,
+					sysOauthClientDetails.getClientSecret());
+		return R.ok(clientDetailsService.page(page, wrapper));
+	}
+
+	/**
+	 * 添加
+	 * @param clientDetails 实体
+	 * @return success/false
+	 */
+	@SysLog("添加终端")
+	@PostMapping("add")
+	@PreAuthorize("@pms.hasPermission('sys_client_add')")
+	public R add(@Valid @RequestBody SysOauthClientDetails clientDetails) {
+		return R.ok(clientDetailsService.saveClient(clientDetails));
+	}
+
+	/**
+	 * 删除
+	 * @param id ID
+	 * @return success/false
+	 */
+	@SysLog("删除终端")
+	@DeleteMapping("removeById/{id}")
+	@PreAuthorize("@pms.hasPermission('sys_client_del')")
+	public R removeById(@PathVariable Long id) {
+		clientDetailsService.removeBatchByIds(CollUtil.toList(id));
+		return R.ok();
+	}
+
+	/**
+	 * 编辑
+	 * @param clientDetails 实体
+	 * @return success/false
+	 */
+	@SysLog("编辑终端")
+	@PutMapping("update")
+	@PreAuthorize("@pms.hasPermission('sys_client_edit')")
+	public R update(@Valid @RequestBody SysOauthClientDetails clientDetails) {
+		return R.ok(clientDetailsService.updateClientById(clientDetails));
+	}
+
+	@Inner
+	@GetMapping("/getClientDetailsById/{clientId}")
+	public R getClientDetailsById(@PathVariable String clientId) {
+		return R.ok(clientDetailsService.getOne(
+				Wrappers.<SysOauthClientDetails>lambdaQuery().eq(SysOauthClientDetails::getClientId, clientId), false));
+	}
+
+	/**
+	 * 查询全部客户端
+	 * @return
+	 */
+	@Inner
+	@GetMapping("/list")
+	public R listClients() {
+		return R.ok(clientDetailsService.list());
+	}
+
+	/**
+	 * 同步缓存字典
+	 * @return R
+	 */
+	@SysLog("同步终端")
+	@PutMapping("/sync")
+	public R sync() {
+		return clientDetailsService.syncClientCache();
+	}
+
+	/**
+	 * 导出所有客户端
+	 * @return excel
+	 */
+	@ResponseExcel
+	@SysLog("导出excel")
+	@GetMapping("/export")
+	public List<SysOauthClientDetails> export(SysOauthClientDetails sysOauthClientDetails) {
+		return clientDetailsService.list(Wrappers.query(sysOauthClientDetails));
+	}
+
+}

+ 40 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysCommController.java

@@ -0,0 +1,40 @@
+package com.kxs.admin.biz.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.kxs.common.core.util.R;
+import com.kxs.common.excel.converters.ImportAsyncInfo;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * SYS 通信控制器
+ *
+ * @author 没秃顶的码农
+ * @date 2024-07-26
+ */
+@RestController
+@RequestMapping("sysComm")
+@RequiredArgsConstructor
+public class SysCommController {
+
+    private final RedisTemplate<String, Object> redisTemplate;
+
+
+    /**
+     * 获取进度条
+     *
+     * @param key 钥匙
+     * @return {@link R}
+     */
+    @GetMapping("/getProgress")
+    public R getProgress(@RequestParam("key") String key){
+        Object obj = redisTemplate.opsForValue().get(key);
+
+        return R.ok(obj != null ? JSON.parseObject(obj.toString(), ImportAsyncInfo.class) : null);
+    }
+
+}

+ 109 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysDeptController.java

@@ -0,0 +1,109 @@
+
+package com.kxs.admin.biz.controller;
+
+import com.kxs.common.core.util.R;
+import com.kxs.common.log.annotation.SysLog;
+import com.kxs.system.biz.model.SysDept;
+import com.kxs.system.biz.service.SysDeptService;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.AllArgsConstructor;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 部门管理 前端控制器
+ * </p>
+ *
+ * @author LXQ
+ * @since 2021-01-20
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/dept")
+@Tag(description = "dept", name = "部门管理模块")
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class SysDeptController {
+
+	private final SysDeptService sysDeptService;
+
+	/**
+	 * 通过ID查询
+	 * @param id ID
+	 * @return SysDept
+	 */
+	@GetMapping("getById")
+	public R getById(@RequestParam("id") Long id) {
+		return R.ok(sysDeptService.getById(id));
+	}
+
+	/**
+	 * 查询全部部门
+	 */
+	@GetMapping("/list")
+	public R list() {
+		return R.ok(sysDeptService.list());
+	}
+
+	/**
+	 * 返回树形菜单集合
+	 * @param deptName 部门名称
+	 * @return 树形菜单
+	 */
+	@GetMapping(value = "/tree")
+	public R getTree(String deptName) {
+		return R.ok(sysDeptService.selectTree(deptName));
+	}
+
+	/**
+	 * 添加
+	 * @param sysDept 实体
+	 * @return success/false
+	 */
+	@SysLog("添加部门")
+	@PostMapping("add")
+	@PreAuthorize("@pms.hasPermission('sys_dept_add')")
+	public R save(@Valid @RequestBody SysDept sysDept) {
+		return R.ok(sysDeptService.save(sysDept));
+	}
+
+	/**
+	 * 删除
+	 * @param id ID
+	 * @return success/false
+	 */
+	@SysLog("删除部门")
+	@DeleteMapping("removeById/{id}")
+	@PreAuthorize("@pms.hasPermission('sys_dept_del')")
+	public R removeById(@PathVariable Long id) {
+		return R.ok(sysDeptService.removeDeptById(id));
+	}
+
+	/**
+	 * 编辑
+	 * @param sysDept 实体
+	 * @return success/false
+	 */
+	@SysLog("编辑部门")
+	@PutMapping("update")
+	@PreAuthorize("@pms.hasPermission('sys_dept_edit')")
+	public R update(@Valid @RequestBody SysDept sysDept) {
+		sysDept.setUpdateTime(LocalDateTime.now());
+		return R.ok(sysDeptService.updateById(sysDept));
+	}
+
+	/**
+	 * 查收子级列表
+	 * @return 返回子级
+	 */
+	@GetMapping(value = "/getDescendantList")
+	public R getDescendantList(@RequestParam("deptId") Long deptId) {
+		return R.ok(sysDeptService.listDescendant(deptId));
+	}
+
+}

+ 224 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysDictController.java

@@ -0,0 +1,224 @@
+package com.kxs.admin.biz.controller;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.common.core.constant.CacheConstants;
+import com.kxs.common.core.util.R;
+import com.kxs.common.excel.annotation.ResponseExcel;
+import com.kxs.common.log.annotation.SysLog;
+import com.kxs.common.security.annotation.Inner;
+import com.kxs.system.biz.model.SysDict;
+import com.kxs.system.biz.model.SysDictItem;
+import com.kxs.system.biz.service.SysDictItemService;
+import com.kxs.system.biz.service.SysDictService;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.AllArgsConstructor;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 字典表 前端控制器
+ * </p>
+ *
+ * @author 没秃顶的码农
+ * @date 2023/11/03
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/dict")
+@Tag(description = "dict", name = "字典管理模块")
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class SysDictController {
+
+	private final SysDictService sysDictService;
+
+	private final SysDictItemService sysDictItemService;
+
+	/**
+	 * 通过ID查询字典信息
+	 * @param id ID
+	 * @return 字典信息
+	 */
+	@GetMapping("/getById")
+	public R getById(@RequestParam("id") Long id) {
+		return R.ok(sysDictService.getById(id));
+	}
+
+	/**
+	 * 查询字典信息
+	 * @param query 查询信息
+	 * @return 字典信息
+	 */
+	@GetMapping("/details")
+	public R getDetails(@ParameterObject SysDict query) {
+		return R.ok(sysDictService.getOne(Wrappers.query(query), false));
+	}
+
+	/**
+	 * 分页查询字典信息
+	 * @param page 分页对象
+	 * @return 分页对象
+	 */
+	@GetMapping("/page")
+	public R<IPage> getDictPage(@ParameterObject Page page, @ParameterObject SysDict sysDict) {
+		return R.ok(sysDictService.page(page,
+				Wrappers.<SysDict>lambdaQuery()
+					.eq(StrUtil.isNotBlank(sysDict.getSystemFlag()), SysDict::getSystemFlag, sysDict.getSystemFlag())
+					.like(StrUtil.isNotBlank(sysDict.getDictType()), SysDict::getDictType, sysDict.getDictType())));
+	}
+
+	/**
+	 * 通过字典类型查找字典
+	 * @param type 类型
+	 * @return 同类型字典
+	 */
+	@Inner(value = false)
+	@GetMapping("type")
+	@Cacheable(value = CacheConstants.DICT_DETAILS, key = "#type", unless = "#result.data.isEmpty()")
+	public R<List<SysDictItem>> getDictByType(@RequestParam("type") String type) {
+		return R.ok(sysDictItemService.list(Wrappers.<SysDictItem>query().lambda().eq(SysDictItem::getDictType, type)));
+	}
+
+	/**
+	 * 添加字典
+	 * @param sysDict 字典信息
+	 * @return success、false
+	 */
+	@SysLog("添加字典")
+	@PostMapping("add")
+	@PreAuthorize("@pms.hasPermission('sys_dict_add')")
+	public R save(@Valid @RequestBody SysDict sysDict) {
+		sysDictService.save(sysDict);
+		return R.ok(sysDict);
+	}
+
+	/**
+	 * 删除字典,并且清除字典缓存
+	 * @param id ID
+	 * @return R
+	 */
+	@SysLog("删除字典")
+	@DeleteMapping("removeById/{id}")
+	@PreAuthorize("@pms.hasPermission('sys_dict_del')")
+	@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
+	public R removeById(@PathVariable Long id) {
+
+		return R.ok(sysDictService.removeDictByIds(new Long[]{id}));
+	}
+
+	/**
+	 * 修改字典
+	 * @param sysDict 字典信息
+	 * @return success/false
+	 */
+	@PutMapping("update")
+	@SysLog("修改字典")
+	@PreAuthorize("@pms.hasPermission('sys_dict_edit')")
+	public R updateById(@Valid @RequestBody SysDict sysDict) {
+		return sysDictService.updateDict(sysDict);
+	}
+
+	/**
+	 * 查询
+	 * @param name 名称或者字典项
+	 */
+	@GetMapping("/list")
+	public R getDictList(@RequestParam("name") String name) {
+		return R.ok(sysDictService.list(Wrappers.<SysDict>lambdaQuery()
+			.like(StrUtil.isNotBlank(name), SysDict::getDictType, name)
+			.or()
+			.like(StrUtil.isNotBlank(name), SysDict::getDescription, name)));
+	}
+
+	/**
+	 * 分页查询
+	 * @param page 分页对象
+	 * @param sysDictItem 字典项
+	 */
+	@GetMapping("/pageItem")
+	public R getSysDictItemPage(Page<SysDictItem> page, @ParameterObject SysDictItem sysDictItem) {
+		return R.ok(sysDictItemService.page(page, Wrappers.query(sysDictItem)));
+	}
+
+	/**
+	 * 通过id查询字典项
+	 * @param id id
+	 * @return R
+	 */
+	@GetMapping("/getItemById")
+	public R getDictItemById(@RequestParam("id") Long id) {
+		return R.ok(sysDictItemService.getById(id));
+	}
+
+	/**
+	 * 查询字典项详情
+	 * @param query 查询条件
+	 * @return R
+	 */
+	@GetMapping("/detailsItem")
+	public R getDictItemDetails(@ParameterObject SysDictItem query) {
+		return R.ok(sysDictItemService.getOne(Wrappers.query(query), false));
+	}
+
+	/**
+	 * 新增字典项
+	 * @param sysDictItem 字典项
+	 * @return R
+	 */
+	@SysLog("新增字典项")
+	@PostMapping("/addItem")
+	@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
+	public R save(@RequestBody SysDictItem sysDictItem) {
+		return R.ok(sysDictItemService.save(sysDictItem));
+	}
+
+	/**
+	 * 修改字典项
+	 * @param sysDictItem 字典项
+	 * @return R
+	 */
+	@SysLog("修改字典项")
+	@PutMapping("/updateItem")
+	public R updateById(@RequestBody SysDictItem sysDictItem) {
+		return sysDictItemService.updateDictItem(sysDictItem);
+	}
+
+	/**
+	 * 通过id删除字典项
+	 * @param id id
+	 * @return R
+	 */
+	@SysLog("删除字典项")
+	@DeleteMapping("/removeItemById/{id}")
+	public R removeDictItemById(@PathVariable Long id) {
+		return sysDictItemService.removeDictItem(id);
+	}
+
+	/**
+	 * 同步缓存字典
+	 * @return R
+	 */
+	@SysLog("同步字典")
+	@PutMapping("/sync")
+	public R sync() {
+		return sysDictService.syncDictCache();
+	}
+
+	@ResponseExcel
+	@GetMapping("/export")
+	public List<SysDictItem> export(SysDictItem sysDictItem) {
+		return sysDictItemService.list(Wrappers.query(sysDictItem));
+	}
+
+}

+ 102 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysFileController.java

@@ -0,0 +1,102 @@
+
+package com.kxs.admin.biz.controller;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.common.core.util.R;
+import com.kxs.common.log.annotation.SysLog;
+import com.kxs.common.security.annotation.Inner;
+import com.kxs.system.biz.model.SysFile;
+import com.kxs.system.biz.service.SysFileService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
+import lombok.AllArgsConstructor;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 文件管理
+ *
+ * @author 没秃顶的码农
+ * @date 2019-06-18 17:18:42
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/sysFile")
+@Tag(description = "sysFile", name = "文件管理")
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class SysFileController {
+
+    private final SysFileService sysFileService;
+
+    /**
+     * 分页查询
+     *
+     * @param page    分页对象
+     * @param sysFile 文件管理
+     * @return 分页
+     */
+    @Operation(summary = "分页查询", description = "分页查询")
+    @GetMapping("/page")
+    public R getSysFilePage(@ParameterObject Page<SysFile> page, @ParameterObject SysFile sysFile) {
+        LambdaQueryWrapper<SysFile> wrapper = Wrappers.<SysFile>lambdaQuery()
+				.eq(sysFile.getType() != null, SysFile::getType, sysFile.getType())
+                .like(CharSequenceUtil.isNotBlank(sysFile.getFileName()), SysFile::getFileName, sysFile.getFileName())
+                .like(CharSequenceUtil.isNotBlank(sysFile.getTitle()), SysFile::getTitle, sysFile.getTitle())
+                .orderByDesc(SysFile::getId);
+        return R.ok(sysFileService.page(page, wrapper));
+    }
+
+    /**
+     * 通过id删除文件管理
+     *
+     * @param ids id 列表
+     * @return R
+     */
+    @Operation(summary = "通过id删除文件管理", description = "通过id删除文件管理")
+    @SysLog("删除文件管理")
+    @PostMapping("/removeByIds")
+    @PreAuthorize("@pms.hasPermission('sys_file_del')")
+    public R removeById(@RequestBody List<Long> ids) {
+
+        return R.ok(sysFileService.deleteFile(ids));
+    }
+
+    /**
+     * 保存文件
+     *
+     * @param file 资源
+     * @return R
+     */
+    @PostMapping(value = "/save")
+    @PreAuthorize("@pms.hasPermission('sys_file_save')")
+    public R save(@Valid @RequestBody SysFile file) {
+
+        return R.ok(sysFileService.save(file));
+    }
+
+    /**
+     * 获取文件
+     *
+     * @param bucket   桶名称
+     * @param fileName 文件空间/名称
+     */
+    @Inner(false)
+    @GetMapping("/file")
+    public R file(@RequestParam("bucketName") String bucket, @RequestParam("fileName") String fileName, HttpServletResponse response) {
+
+        return R.ok(sysFileService.getFile(bucket, fileName, response));
+    }
+
+
+}

+ 61 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysImageCodeController.java

@@ -0,0 +1,61 @@
+package com.kxs.admin.biz.controller;
+
+import cn.hutool.captcha.CaptchaUtil;
+import cn.hutool.captcha.LineCaptcha;
+import cn.hutool.captcha.generator.RandomGenerator;
+import com.kxs.common.core.constant.CacheConstants;
+import com.kxs.common.core.constant.SecurityConstants;
+import com.kxs.common.core.exception.GlobalCustomerException;
+import com.kxs.common.security.annotation.Inner;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.http.MediaType;
+import org.springframework.util.FastByteArrayOutputStream;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * 图形验证码
+ * @author lixueqiang
+ */
+
+@RestController
+@RequestMapping("/code")
+@RequiredArgsConstructor
+public class SysImageCodeController {
+
+    private final RedisTemplate<String, Object> redisTemplate;
+
+    private static final int DEFAULT_IMAGE_WIDTH = 100;
+    private static final int DEFAULT_IMAGE_HEIGHT = 40;
+    private static final String CAPTCHA_CHARS = "0123456789";
+    private static final int CAPTCHA_LENGTH = 4;
+
+    @Inner(false)
+    @GetMapping
+    public void getImageCode(@RequestParam String randomStr, HttpServletResponse response) {
+        RandomGenerator randomGenerator = new RandomGenerator(CAPTCHA_CHARS, CAPTCHA_LENGTH);
+        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT);
+        lineCaptcha.setGenerator(randomGenerator);
+
+        redisTemplate.opsForValue()
+                .set(CacheConstants.DEFAULT_CODE_KEY + randomStr, lineCaptcha.getCode(),
+                        SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
+
+        try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {
+            response.setContentType(MediaType.IMAGE_PNG_VALUE);
+            lineCaptcha.write(os);
+            response.getOutputStream().write(os.toByteArray());
+            response.getOutputStream().flush();
+        } catch (IOException e) {
+            throw new GlobalCustomerException("生成验证码失败");
+        }
+    }
+}

+ 86 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysLogController.java

@@ -0,0 +1,86 @@
+package com.kxs.admin.biz.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.common.core.util.R;
+import com.kxs.common.excel.annotation.ResponseExcel;
+import com.kxs.common.security.annotation.Inner;
+import com.kxs.system.biz.domain.dto.SysLogDTO;
+import com.kxs.system.biz.model.SysLog;
+import com.kxs.system.biz.service.SysLogService;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.AllArgsConstructor;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 日志表 前端控制器
+ * </p>
+ *
+ * @author 没秃顶的码农
+ * @date 2023/11/03
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/log")
+@Tag(description = "log", name = "日志管理模块")
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class SysLogController {
+
+	private final SysLogService sysLogService;
+
+	/**
+	 * 简单分页查询
+	 * @param page 分页对象
+	 * @param sysLog 系统日志
+	 * @return
+	 */
+	@GetMapping("/page")
+	public R getLogPage(@ParameterObject Page page, @ParameterObject SysLogDTO sysLog) {
+		return R.ok(sysLogService.getLogByPage(page, sysLog));
+	}
+
+	/**
+	 * 批量删除日志
+	 * @param ids ID
+	 * @return success/false
+	 */
+	@PostMapping("remove")
+	@PreAuthorize("@pms.hasPermission('sys_log_del')")
+	public R removeByIds(@RequestBody Long[] ids) {
+		return R.ok(sysLogService.removeBatchByIds(CollUtil.toList(ids)));
+	}
+
+	/**
+	 * 插入日志
+	 * @param sysLog 日志实体
+	 * @return success/false
+	 */
+	@Inner
+	@PostMapping("/save")
+	public R save(@Valid @RequestBody SysLog sysLog) {
+
+		return R.ok(sysLogService.saveLog(sysLog));
+	}
+
+	/**
+	 * 导出excel 表格
+	 * @param sysLog 查询条件
+	 * @return
+	 */
+	@ResponseExcel
+	@GetMapping("/export")
+	@PreAuthorize("@pms.hasPermission('sys_log_export')")
+	public List<SysLog> export(SysLog sysLog) {
+		return sysLogService.list(Wrappers.query(sysLog));
+	}
+
+}

+ 118 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysMenuController.java

@@ -0,0 +1,118 @@
+package com.kxs.admin.biz.controller;
+
+import com.kxs.common.core.util.R;
+import com.kxs.common.log.annotation.SysLog;
+import com.kxs.common.security.util.SecurityUtils;
+import com.kxs.system.biz.model.SysMenu;
+import com.kxs.system.biz.service.SysMenuService;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.AllArgsConstructor;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * sys菜单控制器
+ *
+ * @author 没秃顶的码农
+ * @date 2023/11/03
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/menu")
+@Tag(description = "menu", name = "菜单管理模块")
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class SysMenuController {
+
+	private final SysMenuService sysMenuService;
+
+	/**
+	 * 返回当前用户的树形菜单集合
+	 * @param type 类型
+	 * @param parentId 父节点ID
+	 * @return 当前用户的树形菜单
+	 */
+	@GetMapping("/getUserMenu")
+	public R getUserMenu(String type, Long parentId) {
+		// 获取符合条件的菜单
+		Set<SysMenu> all = new HashSet<>();
+		SecurityUtils.getRoles().forEach(roleId -> all.addAll(sysMenuService.findMenuByRoleId(roleId)));
+		return R.ok(sysMenuService.filterMenu(all, type, parentId));
+	}
+
+	/**
+	 * 返回树形菜单集合
+	 * @param parentId 父节点ID
+	 * @param menuName 菜单名称
+	 * @return 树形菜单
+	 */
+	@GetMapping(value = "/tree")
+	public R getTree(Long parentId, String menuName, String type) {
+		return R.ok(sysMenuService.treeMenu(parentId, menuName, type));
+	}
+
+	/**
+	 * 返回角色的菜单集合
+	 * @param roleId 角色ID
+	 * @return 属性集合
+	 */
+	@GetMapping("/getRoleTree")
+	public R getRoleTree(@RequestParam("roleId") Long roleId) {
+		return R
+			.ok(sysMenuService.findMenuByRoleId(roleId).stream().map(SysMenu::getMenuId).collect(Collectors.toList()));
+	}
+
+	/**
+	 * 通过ID查询菜单的详细信息
+	 * @param id 菜单ID
+	 * @return 菜单详细信息
+	 */
+	@GetMapping("getById")
+	public R getById(@RequestParam("id") Long id) {
+		return R.ok(sysMenuService.getById(id));
+	}
+
+	/**
+	 * 新增菜单
+	 * @param sysMenu 菜单信息
+	 * @return success/false
+	 */
+	@SysLog("新增菜单")
+	@PostMapping("add")
+	@PreAuthorize("@pms.hasPermission('sys_menu_add')")
+	public R save(@Valid @RequestBody SysMenu sysMenu) {
+		sysMenuService.save(sysMenu);
+		return R.ok(sysMenu);
+	}
+
+	/**
+	 * 删除菜单
+	 * @param id 菜单ID
+	 * @return success/false
+	 */
+	@SysLog("删除菜单")
+	@DeleteMapping("removeById/{id}")
+	@PreAuthorize("@pms.hasPermission('sys_menu_del')")
+	public R removeById(@PathVariable Long id) {
+		return sysMenuService.removeMenuById(id);
+	}
+
+	/**
+	 * 更新菜单
+	 * @param sysMenu
+	 * @return
+	 */
+	@SysLog("更新菜单")
+	@PutMapping("update")
+	@PreAuthorize("@pms.hasPermission('sys_menu_edit')")
+	public R update(@Valid @RequestBody SysMenu sysMenu) {
+		return R.ok(sysMenuService.updateMenuById(sysMenu));
+	}
+
+}

+ 123 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysPostController.java

@@ -0,0 +1,123 @@
+package com.kxs.admin.biz.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.common.core.util.R;
+import com.kxs.common.log.annotation.SysLog;
+import com.kxs.system.biz.model.SysPost;
+import com.kxs.system.biz.service.SysPostService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 岗位信息表
+ *
+ * @author 没秃顶的码农
+ * @date 2023/11/06
+ */
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/post")
+@Tag(description = "post", name = "岗位信息表管理")
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class SysPostController {
+
+	private final SysPostService sysPostService;
+
+	/**
+	 * 获取岗位列表
+	 * @return 岗位列表
+	 */
+	@GetMapping("/list")
+	public R<List<SysPost>> listPosts() {
+		return R.ok(sysPostService.list(Wrappers.emptyWrapper()));
+	}
+
+	/**
+	 * 分页查询
+	 * @param page 分页对象
+	 * @param sysPost 岗位信息表
+	 * @return
+	 */
+	@Operation(description = "分页查询", summary = "分页查询")
+	@GetMapping("/page")
+	@PreAuthorize("@pms.hasPermission('sys_post_view')")
+	public R getSysPostPage(@ParameterObject Page<SysPost> page, @ParameterObject SysPost sysPost) {
+		return R.ok(sysPostService.page(page, Wrappers.<SysPost>lambdaQuery()
+			.like(StrUtil.isNotBlank(sysPost.getPostName()), SysPost::getPostName, sysPost.getPostName())));
+	}
+
+	/**
+	 * 通过id查询岗位信息表
+	 * @param postId id
+	 * @return R
+	 */
+	@Operation(description = "通过id查询", summary = "通过id查询")
+	@GetMapping("/getById")
+	@PreAuthorize("@pms.hasPermission('sys_post_view')")
+	public R getById(@RequestParam("postId") Long postId) {
+		return R.ok(sysPostService.getById(postId));
+	}
+
+	/**
+	 * 查询岗位信息信息
+	 * @param query 查询条件
+	 * @return R
+	 */
+	@Operation(description = "查询角色信息", summary = "查询角色信息")
+	@GetMapping("/details")
+	@PreAuthorize("@pms.hasPermission('sys_post_view')")
+	public R getDetails(SysPost query) {
+		return R.ok(sysPostService.getOne(Wrappers.query(query), false));
+	}
+
+	/**
+	 * 新增岗位信息表
+	 * @param sysPost 岗位信息表
+	 * @return R
+	 */
+	@Operation(description = "新增岗位信息表", summary = "新增岗位信息表")
+	@SysLog("新增岗位信息表")
+	@PostMapping("add")
+	@PreAuthorize("@pms.hasPermission('sys_post_add')")
+	public R save(@RequestBody SysPost sysPost) {
+		return R.ok(sysPostService.save(sysPost));
+	}
+
+	/**
+	 * 修改岗位信息表
+	 * @param sysPost 岗位信息表
+	 * @return R
+	 */
+	@Operation(description = "修改岗位信息表", summary = "修改岗位信息表")
+	@SysLog("修改岗位信息表")
+	@PutMapping("update")
+	@PreAuthorize("@pms.hasPermission('sys_post_edit')")
+	public R updateById(@RequestBody SysPost sysPost) {
+		return R.ok(sysPostService.updateById(sysPost));
+	}
+
+	/**
+	 * 通过id删除岗位信息表
+	 * @param id id
+	 * @return R
+	 */
+	@Operation(description = "通过id删除岗位信息表", summary = "通过id删除岗位信息表")
+	@SysLog("通过id删除岗位信息表")
+	@DeleteMapping("removeById/{id}")
+	@PreAuthorize("@pms.hasPermission('sys_post_del')")
+	public R removeById(@PathVariable Long id) {
+		return R.ok(sysPostService.removeBatchByIds(CollUtil.toList(id)));
+	}
+
+}

+ 149 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysPublicParamController.java

@@ -0,0 +1,149 @@
+package com.kxs.admin.biz.controller;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.common.core.util.R;
+import com.kxs.common.excel.annotation.ResponseExcel;
+import com.kxs.common.log.annotation.SysLog;
+import com.kxs.common.security.annotation.Inner;
+import com.kxs.system.biz.model.SysPublicParam;
+import com.kxs.system.biz.service.SysPublicParamService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.AllArgsConstructor;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 公共参数
+ *
+ * @author 没秃顶的码农
+ * @date 2023/11/03
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/param")
+@Tag(description = "param", name = "公共参数配置")
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class SysPublicParamController {
+
+	private final SysPublicParamService sysPublicParamService;
+
+	/**
+	 * 通过key查询公共参数值
+	 *
+	 * @param publicKey 公钥
+	 * @return {@link R}
+	 */
+	@Inner(value = false)
+	@Operation(description = "查询公共参数值", summary = "根据key查询公共参数值")
+	@GetMapping("/publicValue")
+	public R publicKey(@RequestParam("publicKey") String publicKey) {
+		return R.ok(sysPublicParamService.getSysPublicParamKeyToValue(publicKey));
+	}
+
+	/**
+	 * 分页查询
+	 * @param page 分页对象
+	 * @param sysPublicParam 公共参数
+	 */
+	@Operation(description = "分页查询", summary = "分页查询")
+	@GetMapping("/page")
+	public R getSysPublicParamPage(@ParameterObject Page<SysPublicParam> page, @ParameterObject SysPublicParam sysPublicParam) {
+		LambdaUpdateWrapper<SysPublicParam> wrapper = Wrappers.<SysPublicParam>lambdaUpdate()
+			.like(StrUtil.isNotBlank(sysPublicParam.getPublicName()), SysPublicParam::getPublicName,
+					sysPublicParam.getPublicName())
+			.like(StrUtil.isNotBlank(sysPublicParam.getPublicKey()), SysPublicParam::getPublicKey,
+					sysPublicParam.getPublicKey())
+			.eq(StrUtil.isNotBlank(sysPublicParam.getSystemFlag()), SysPublicParam::getSystemFlag,
+					sysPublicParam.getSystemFlag());
+
+		return R.ok(sysPublicParamService.page(page, wrapper));
+	}
+
+	/**
+	 * 通过id查询公共参数
+	 * @param publicId id
+	 * @return R
+	 */
+	@Operation(description = "通过id查询公共参数", summary = "通过id查询公共参数")
+	@GetMapping("/getById")
+	public R getById(@RequestParam("publicId") Long publicId) {
+		return R.ok(sysPublicParamService.getById(publicId));
+	}
+
+	@GetMapping("/details")
+	public R getDetail(@ParameterObject SysPublicParam param) {
+		return R.ok(sysPublicParamService.getOne(Wrappers.query(param), false));
+	}
+
+	/**
+	 * 新增公共参数
+	 * @param sysPublicParam 公共参数
+	 * @return R
+	 */
+	@Operation(description = "新增公共参数", summary = "新增公共参数")
+	@SysLog("新增公共参数")
+	@PostMapping("add")
+	@PreAuthorize("@pms.hasPermission('sys_syspublicparam_add')")
+	public R save(@RequestBody SysPublicParam sysPublicParam) {
+		return R.ok(sysPublicParamService.save(sysPublicParam));
+	}
+
+	/**
+	 * 修改公共参数
+	 * @param sysPublicParam 公共参数
+	 * @return R
+	 */
+	@Operation(description = "修改公共参数", summary = "修改公共参数")
+	@SysLog("修改公共参数")
+	@PutMapping("update")
+	@PreAuthorize("@pms.hasPermission('sys_syspublicparam_edit')")
+	public R updateById(@RequestBody SysPublicParam sysPublicParam) {
+		return sysPublicParamService.updateParam(sysPublicParam);
+	}
+
+
+	/**
+	 * 通过id删除公共参数
+	 * @param id id
+	 * @return R
+	 */
+	@Operation(description = "删除公共参数", summary = "删除公共参数")
+	@SysLog("删除公共参数")
+	@DeleteMapping("removeById/{id}")
+	@PreAuthorize("@pms.hasPermission('sys_syspublicparam_del')")
+	public R removeById(@PathVariable Long id) {
+		return R.ok(sysPublicParamService.removeParamByIds(new Long[]{id}));
+	}
+
+	/**
+	 * 导出excel 表格
+	 * @return
+	 */
+	@ResponseExcel
+	@GetMapping("/export")
+	@PreAuthorize("@pms.hasPermission('sys_syspublicparam_edit')")
+	public List<SysPublicParam> export() {
+		return sysPublicParamService.list();
+	}
+
+	/**
+	 * 同步参数
+	 * @return R
+	 */
+	@SysLog("同步参数")
+	@PutMapping("/sync")
+	@PreAuthorize("@pms.hasPermission('sys_syspublicparam_edit')")
+	public R sync() {
+		return sysPublicParamService.syncParamCache();
+	}
+
+}

+ 160 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysRoleController.java

@@ -0,0 +1,160 @@
+package com.kxs.admin.biz.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.common.core.constant.CacheConstants;
+import com.kxs.common.core.util.R;
+import com.kxs.common.log.annotation.SysLog;
+import com.kxs.system.biz.domain.vo.RoleEditVO;
+import com.kxs.system.biz.domain.vo.RoleVO;
+import com.kxs.system.biz.model.SysRole;
+import com.kxs.system.biz.service.SysRoleService;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.AllArgsConstructor;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * sys角色控制器
+ *
+ * @author 没秃顶的码农
+ * @date 2023/11/03
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/role")
+@Tag(description = "role", name = "角色管理模块")
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class SysRoleController {
+
+	private final SysRoleService sysRoleService;
+
+	/**
+	 * 通过ID查询角色信息
+	 * @param id ID
+	 * @return 角色信息
+	 */
+	@GetMapping("/getById")
+	public R getById(@RequestParam("id") Long id) {
+		return R.ok(sysRoleService.getById(id));
+	}
+
+	/**
+	 * 查询角色信息
+	 * @param query 查询条件
+	 * @return 角色信息
+	 */
+	@GetMapping("/details")
+	public R getDetails(@ParameterObject SysRole query) {
+		return R.ok(sysRoleService.getOne(Wrappers.query(query), false));
+	}
+
+	/**
+	 * 添加角色
+	 * @param sysRole 角色信息
+	 * @return success、false
+	 */
+	@SysLog("添加角色")
+	@PostMapping("add")
+	@PreAuthorize("@pms.hasPermission('sys_role_add')")
+	@CacheEvict(value = CacheConstants.ROLE_DETAILS, allEntries = true)
+	public R save(@Valid @RequestBody SysRole sysRole) {
+		return R.ok(sysRoleService.save(sysRole));
+	}
+
+	/**
+	 * 修改角色
+	 * @param sysRole 角色信息
+	 * @return success/false
+	 */
+	@SysLog("修改角色")
+	@PutMapping("update")
+	@PreAuthorize("@pms.hasPermission('sys_role_edit')")
+	@CacheEvict(value = CacheConstants.ROLE_DETAILS, allEntries = true)
+	public R update(@Valid @RequestBody RoleEditVO sysRole) {
+		return R.ok(sysRoleService.updateByRole(sysRole));
+	}
+
+	/**
+	 * 批量删除角色
+	 *
+	 * @param ids id
+	 * @return {@link R}
+	 */
+	@SysLog("删除角色")
+	@PostMapping("remove")
+	@PreAuthorize("@pms.hasPermission('sys_role_del')")
+	@CacheEvict(value = CacheConstants.ROLE_DETAILS, allEntries = true)
+	public R remove(@RequestBody Long[] ids) {
+		return R.ok(sysRoleService.removeRoleByIds(ids));
+	}
+
+	/**
+	 * 删除角色
+	 *
+	 * @param id id
+	 * @return {@link R}
+	 */
+	@SysLog("删除角色")
+	@DeleteMapping("removeById/{id}")
+	@PreAuthorize("@pms.hasPermission('sys_role_del')")
+	@CacheEvict(value = CacheConstants.ROLE_DETAILS, allEntries = true)
+	public R removeById(@PathVariable Long id) {
+
+		return R.ok(sysRoleService.removeRoleByIds(new Long[]{id}));
+	}
+
+	/**
+	 * 获取角色列表
+	 * @return 角色列表
+	 */
+	@GetMapping("/list")
+	public R listRoles() {
+		return R.ok(sysRoleService.list(Wrappers.emptyWrapper()));
+	}
+
+	/**
+	 * 分页查询角色信息
+	 * @param page 分页对象
+	 * @param role 查询条件
+	 * @return 分页对象
+	 */
+	@GetMapping("/page")
+	public R getRolePage(Page<SysRole> page, SysRole role) {
+		return R.ok(sysRoleService.page(page, Wrappers.<SysRole>lambdaQuery()
+			.like(CharSequenceUtil.isNotBlank(role.getRoleName()), SysRole::getRoleName, role.getRoleName())));
+	}
+
+	/**
+	 * 更新角色菜单
+	 * @param roleVo 角色对象
+	 * @return success、false
+	 */
+	@SysLog("更新角色菜单")
+	@PutMapping("/menu")
+	@PreAuthorize("@pms.hasPermission('sys_role_perm')")
+	public R saveRoleMenus(@RequestBody RoleVO roleVo) {
+		return R.ok(sysRoleService.updateRoleMenus(roleVo));
+	}
+
+	/**
+	 * 通过角色ID 查询角色列表
+	 * @param roleIdList 角色ID
+	 * @return 响应信息主体
+	 */
+	@PostMapping("/getRoleList")
+	public R getRoleList(@RequestBody List<Long> roleIdList) {
+		return R.ok(sysRoleService.findRolesByRoleIds(roleIdList, CollUtil.join(roleIdList, StrUtil.UNDERLINE)));
+	}
+
+}

+ 88 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysRuleMakingController.java

@@ -0,0 +1,88 @@
+package com.kxs.admin.biz.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.common.core.util.R;
+import com.kxs.common.log.annotation.SysLog;
+import com.kxs.system.biz.domain.dto.SysRuleMakingDTO;
+import com.kxs.system.biz.model.SysRulemaking;
+import com.kxs.system.biz.service.SysRuleMakingService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 协议管理(SysRulemaking)控制层
+ *
+ * @author 系统
+ * @since 2024-08-27 14:12:41
+ */
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("sysRuleMaking")
+public class SysRuleMakingController {
+
+    /**
+     * 服务对象
+     */
+    private final SysRuleMakingService sysRuleMakingService;
+
+
+
+    /**
+     * 协议管理-列表
+     *
+     * @param page 分页对象
+     * @return 协议管理-列表
+     */
+    @GetMapping("/page")
+    public R ruleMakingPage(Page<SysRulemaking> page, SysRuleMakingDTO param) {
+        sysRuleMakingService.ruleMakingPage(page,param);
+        return R.ok(page);
+    }
+
+
+    /**
+     * 协议管理-新增或修改
+     *
+     * @return 协议管理-新增或修改
+     */
+    @SysLog("协议管理-新增或修改")
+    @PostMapping("/addOrUpdate")
+    @PreAuthorize("@pms.hasPermission('sys_ruleMaking_addOrUpdate')")
+    public R addOrUpdate(@RequestBody SysRulemaking param) {
+
+        return R.ok(sysRuleMakingService.saveOrUpdate(param));
+    }
+
+
+    /**
+     * 协议管理-删除
+     *
+     * @return 协议管理-删除
+     */
+    @SysLog("协议管理-删除")
+    @DeleteMapping("/deleteById/{id}")
+    @PreAuthorize("@pms.hasPermission('sys_ruleMaking_delete')")
+    public R deleteById(@PathVariable("id")Integer id) {
+
+        return R.ok(sysRuleMakingService.removeById(id));
+    }
+
+
+    /**
+     * 查询协议信息
+     * @param id
+     * @return
+     */
+    @GetMapping("/getById")
+    public R getById(@RequestParam Integer id){
+
+        return R.ok(sysRuleMakingService.getById(id));
+    }
+
+
+
+
+
+}
+

+ 188 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/SysUserController.java

@@ -0,0 +1,188 @@
+
+package com.kxs.admin.biz.controller;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.common.core.constant.CommonConstants;
+import com.kxs.common.core.util.R;
+import com.kxs.common.log.annotation.SysLog;
+import com.kxs.common.security.annotation.Inner;
+import com.kxs.common.security.util.SecurityUtils;
+import com.kxs.system.biz.constant.enums.SysErrorTypeEnum;
+import com.kxs.system.biz.domain.dto.UserDTO;
+import com.kxs.system.biz.domain.vo.UserVO;
+import com.kxs.system.biz.model.SysUser;
+import com.kxs.system.biz.service.SysUserService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.AllArgsConstructor;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * sys用户控制器
+ *
+ * @author 没秃顶的码农
+ * @date 2023/11/03
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/sysUSer")
+@Tag(description = "user", name = "用户管理模块")
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class SysUserController {
+
+	private final SysUserService userService;
+
+	/**
+	 * 获取指定用户全部信息
+	 * @return 用户信息
+	 */
+	@Inner
+	@GetMapping(value = { "/info/query" })
+	public R info(@RequestParam("username") String username) {
+		SysUser user = userService.getOne(Wrappers.<SysUser>query()
+			.lambda()
+			.eq(SysUser::getUsername, username));
+		if (user == null) {
+			return R.failed(SysErrorTypeEnum.USER_EMPTY.getDescription());
+		}
+		return R.ok(userService.findUserInfo(user));
+	}
+
+	/**
+	 * 获取当前用户全部信息
+	 * @return 用户信息
+	 */
+	@GetMapping(value = { "/info" })
+	public R info() {
+		String username = SecurityUtils.getUser().getUsername();
+		SysUser user = userService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));
+		if (user == null) {
+			return R.failed(SysErrorTypeEnum.USER_EMPTY);
+		}
+		return R.ok(userService.findUserInfo(user));
+	}
+
+	/**
+	 * 通过ID查询用户信息
+	 * @param id ID
+	 * @return 用户信息
+	 */
+	@GetMapping("/getById")
+	public R getById(@RequestParam("id") Long id) {
+		return R.ok(userService.selectUserVoById(id));
+	}
+
+	/**
+	 * 查询用户信息
+	 * @param query 查询条件
+	 * @return 不为空返回用户名
+	 */
+	@Inner
+	@GetMapping("/details")
+	public R getDetails(@ParameterObject SysUser query) {
+		SysUser sysUser = userService.getOne(Wrappers.query(query), false);
+		return R.ok(sysUser == null ? null : CommonConstants.SUCCESS);
+	}
+
+	/**
+	 * 批量删除用户信息
+	 * @param ids ID
+	 * @return R
+	 */
+	@SysLog("批量删除用户信息")
+	@PostMapping("remove")
+	@PreAuthorize("@pms.hasPermission('sys_user_del')")
+	@Operation(summary = "删除用户", description = "批量删除用户信息")
+	public R userDel(@RequestBody Long[] ids) {
+		return R.ok(userService.deleteUserByIds(ids));
+	}
+
+	/**
+	 * 删除用户信息
+	 * @param id ID
+	 * @return R
+	 */
+	@SysLog("删除用户信息")
+	@DeleteMapping("removeById/{id}")
+	@PreAuthorize("@pms.hasPermission('sys_user_del')")
+	@Operation(summary = "删除用户", description = "根据ID删除用户")
+	public R removeById(@PathVariable Long id) {
+		return R.ok(userService.deleteUserByIds(new Long[]{id}));
+	}
+
+	/**
+	 * 添加用户
+	 * @param userDto 用户信息
+	 * @return success/false
+	 */
+	@SysLog("添加用户")
+	@PostMapping("add")
+	@PreAuthorize("@pms.hasPermission('sys_user_add')")
+	public R user(@RequestBody UserDTO userDto) {
+		return R.ok(userService.saveUser(userDto));
+	}
+
+	/**
+	 * 更新用户信息
+	 * @param userDto 用户信息
+	 * @return R
+	 */
+	@SysLog("更新用户信息")
+	@PutMapping("update")
+	@PreAuthorize("@pms.hasPermission('sys_user_edit')")
+	public R updateUser(@Valid @RequestBody UserDTO userDto) {
+		return R.ok(userService.updateUser(userDto));
+	}
+
+	/**
+	 * 分页查询用户
+	 * @param page 参数集
+	 * @param userDTO 查询参数列表
+	 * @return 用户集合
+	 */
+	@GetMapping("/page")
+	public R getUserPage(@ParameterObject Page<UserVO> page, @ParameterObject UserDTO userDTO) {
+		return R.ok(userService.getUsersWithRolePage(page, userDTO));
+	}
+
+	/**
+	 * 修改个人信息
+	 * @param userDto userDto
+	 * @return success/false
+	 */
+	@SysLog("修改个人信息")
+	@PutMapping("/edit")
+	public R updateUserInfo(@Valid @RequestBody UserDTO userDto) {
+		return userService.updateUserInfo(userDto);
+	}
+
+	/**
+	 * 锁定指定用户
+	 * @param user 用户
+	 * @return R
+	 */
+	@PutMapping("/lock")
+	@PreAuthorize("@pms.hasPermission('sys_user_edit')")
+	public R lockUser(@RequestBody SysUser user) {
+		return userService.lockUser(user);
+	}
+
+	@PutMapping("/password")
+	public R password(@RequestBody UserDTO userDto) {
+		String username = SecurityUtils.getUser().getUsername();
+		userDto.setUsername(username);
+		return userService.changePassword(userDto);
+	}
+
+	@PostMapping("/check")
+	public R check(String password) {
+		return userService.checkPassword(password);
+	}
+
+}

+ 216 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/controller/TokenController.java

@@ -0,0 +1,216 @@
+
+package com.kxs.admin.biz.controller;
+
+import cn.hutool.core.date.DatePattern;
+import cn.hutool.core.date.TemporalAccessorUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.common.core.constant.CacheConstants;
+import com.kxs.common.core.constant.CommonConstants;
+import com.kxs.common.core.constant.enums.ErrorTypeEnum;
+import com.kxs.common.core.util.R;
+import com.kxs.common.core.util.SpringContextHolder;
+import com.kxs.common.log.annotation.SysLog;
+import com.kxs.common.security.annotation.Inner;
+import com.kxs.common.security.util.OAuth2EndpointUtils;
+import com.kxs.common.security.util.OAuthClientException;
+import com.kxs.system.biz.model.SysOauthClientDetails;
+import com.kxs.system.biz.service.SysOauthClientDetailsService;
+import com.kxs.system.biz.domain.vo.TokenVo;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cache.CacheManager;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.authentication.event.LogoutSuccessEvent;
+import org.springframework.security.oauth2.core.OAuth2AccessToken;
+import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
+import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
+import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
+import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
+import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
+import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+
+import java.security.Principal;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author LXQ
+ * @date 2021/2/1 删除token端点
+ */
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/token")
+@Tag(description = "token", name = "令牌管理模块")
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class TokenController {
+
+	private final OAuth2AuthorizationService authorizationService;
+
+	private final SysOauthClientDetailsService clientDetailsService;
+
+	private final RedisTemplate<String, Object> redisTemplate;
+
+	private final CacheManager cacheManager;
+
+	/**
+	 * 认证页面
+	 *
+	 * @param error        表单登录失败处理回调的错误信息
+	 * @param modelAndView 模型和视图
+	 * @return ModelAndView
+	 */
+	@GetMapping("/login")
+	public ModelAndView require(ModelAndView modelAndView, @RequestParam(required = false) String error) {
+		modelAndView.setViewName("ftl/login");
+		modelAndView.addObject("error", error);
+		return modelAndView;
+	}
+
+	@GetMapping("/confirm_access")
+	public ModelAndView confirm(Principal principal, ModelAndView modelAndView,
+			@RequestParam(OAuth2ParameterNames.CLIENT_ID) String clientId,
+			@RequestParam(OAuth2ParameterNames.SCOPE) String scope,
+			@RequestParam(OAuth2ParameterNames.STATE) String state) {
+
+		SysOauthClientDetails clientDetails = clientDetailsService.getClientDetailsById(clientId);
+		if (clientDetails == null) {
+			throw new OAuthClientException("clientId 不合法");
+		}
+
+		Set<String> authorizedScopes = StringUtils.commaDelimitedListToSet(clientDetails.getScope());
+		modelAndView.addObject("clientId", clientId);
+		modelAndView.addObject("state", state);
+		modelAndView.addObject("scopeList", authorizedScopes);
+		modelAndView.addObject("principalName", principal.getName());
+		modelAndView.setViewName("ftl/confirm");
+		return modelAndView;
+	}
+
+	/**
+	 * 退出并删除token
+	 *
+	 * @param authHeader Authorization
+	 */
+	@Inner(value = false)
+	@DeleteMapping("/logout")
+	public R logout(@RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authHeader) {
+		if (CharSequenceUtil.isBlank(authHeader)) {
+			return R.ok();
+		}
+
+		String tokenValue = authHeader.replace(OAuth2AccessToken.TokenType.BEARER.getValue(), StrUtil.EMPTY).trim();
+		return removeToken(new String[]{tokenValue});
+	}
+
+	/**
+	 * 校验token
+	 * @param token 令牌
+	 */
+	@SneakyThrows
+	@GetMapping("/checkToken")
+	public R<Object> checkToken(String token) {
+		if (StrUtil.isBlank(token)) {
+
+			return R.failed(ErrorTypeEnum.TOKEN_EMPTY);
+		}
+		OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
+
+		// 如果令牌不存在 返回401
+		if (authorization == null || authorization.getAccessToken() == null) {
+
+			return R.failed(ErrorTypeEnum.TOKEN_EMPTY);
+		}
+		Map<String, Object> claims = authorization.getAccessToken().getClaims();
+		OAuth2AccessTokenResponse sendAccessTokenResponse = OAuth2EndpointUtils.sendAccessTokenResponse(authorization,
+				claims);
+
+		return R.ok(sendAccessTokenResponse.getAccessToken());
+
+	}
+
+	/**
+	 * 删除
+	 * @param tokens tokens
+	 * @return success/false
+	 */
+	@SysLog("删除用户token")
+	@PostMapping("/remove")
+	@PreAuthorize("@pms.hasPermission('sys_token_del')")
+	public R removeToken(@RequestBody String[] tokens) {
+		for (String token : tokens) {
+			OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
+			if (authorization == null) {
+				return R.ok();
+			}
+
+			OAuth2Authorization.Token<OAuth2AccessToken> accessToken = authorization.getAccessToken();
+			if (accessToken == null || StrUtil.isBlank(accessToken.getToken().getTokenValue())) {
+				return R.ok();
+			}
+			// 清空用户信息(立即删除)
+			Objects.requireNonNull(cacheManager.getCache(CacheConstants.USER_DETAILS)).evictIfPresent(authorization.getPrincipalName());
+			// 清空access token
+			authorizationService.remove(authorization);
+			// 处理自定义退出事件,保存相关日志
+			SpringContextHolder.publishEvent(new LogoutSuccessEvent(new PreAuthenticatedAuthenticationToken(
+					authorization.getPrincipalName(), authorization.getRegisteredClientId())));
+		}
+		return R.ok();
+	}
+
+	/**
+	 * 令牌列表
+	 *
+	 * @param params 分页参数
+	 * @return r<page>
+	 */
+	@PostMapping("/page")
+	public R<Page> tokenList(@RequestBody Map<String, Object> params) {
+		// 根据分页参数获取对应数据
+		String key = String.format("%s::*", CacheConstants.PROJECT_OAUTH_ACCESS);
+		int current = MapUtil.getInt(params, CommonConstants.CURRENT);
+		int size = MapUtil.getInt(params, CommonConstants.SIZE);
+		Set<String> keys = redisTemplate.keys(key);
+		assert keys != null;
+		List<String> pages = keys.stream().skip((long) (current - 1) * size).limit(size).collect(Collectors.toList());
+		Page result = new Page(current, size);
+
+		List<TokenVo> tokenVoList = redisTemplate.opsForValue().multiGet(pages).stream().map(obj -> {
+			OAuth2Authorization authorization = (OAuth2Authorization) obj;
+			TokenVo tokenVo = new TokenVo();
+			tokenVo.setClientId(authorization.getRegisteredClientId());
+			tokenVo.setId(authorization.getId());
+			tokenVo.setUsername(authorization.getPrincipalName());
+			OAuth2Authorization.Token<OAuth2AccessToken> accessToken = authorization.getAccessToken();
+			tokenVo.setAccessToken(accessToken.getToken().getTokenValue());
+
+			String expiresAt = TemporalAccessorUtil.format(accessToken.getToken().getExpiresAt(),
+					DatePattern.NORM_DATETIME_PATTERN);
+			tokenVo.setExpiresAt(expiresAt);
+
+			String issuedAt = TemporalAccessorUtil.format(accessToken.getToken().getIssuedAt(),
+					DatePattern.NORM_DATETIME_PATTERN);
+			tokenVo.setIssuedAt(issuedAt);
+			return tokenVo;
+		}).collect(Collectors.toList());
+		result.setRecords(tokenVoList);
+		result.setTotal(keys.size());
+		return R.ok(result);
+	}
+
+}

+ 123 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/security/LxqRemoteRegisteredClientRepository.java

@@ -0,0 +1,123 @@
+package com.kxs.admin.biz.security;
+
+import cn.hutool.core.util.BooleanUtil;
+import cn.hutool.core.util.StrUtil;
+import com.kxs.common.core.constant.CacheConstants;
+import com.kxs.common.core.constant.SecurityConstants;
+import com.kxs.system.biz.model.SysOauthClientDetails;
+import com.kxs.system.biz.service.SysOauthClientDetailsService;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.security.oauth2.core.AuthorizationGrantType;
+import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
+import org.springframework.security.oauth2.core.OAuth2Error;
+import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationException;
+import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
+import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
+import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
+import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat;
+import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
+import org.springframework.stereotype.Component;
+
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.Optional;
+
+/**
+ * 查询客户端相关信息实现
+ *
+ * @author 没秃顶的码农
+ * @date 2022/5/29
+ */
+@RequiredArgsConstructor
+@Component
+public class LxqRemoteRegisteredClientRepository implements RegisteredClientRepository {
+
+	/**
+	 * 刷新令牌有效期默认 30 天
+	 */
+	private static final int REFRESH_TOKEN_VALIDITY_SECONDS = 60 * 60 * 24 * 30;
+
+	/**
+	 * 请求令牌有效期默认 12 小时
+	 */
+	private static final int ACCESS_TOKEN_VALIDITY_SECONDS = 60 * 60 * 12;
+
+	private final SysOauthClientDetailsService clientDetailsService;
+
+	/**
+	 * Saves the registered client.
+	 *
+	 * <p>
+	 * IMPORTANT: Sensitive information should be encoded externally from the
+	 * implementation, e.g. {@link RegisteredClient#getClientSecret()}
+	 * @param registeredClient the {@link RegisteredClient}
+	 */
+	@Override
+	public void save(RegisteredClient registeredClient) {
+		// TODO document why this method is empty
+	}
+
+	/**
+	 * Returns the registered client identified by the provided {@code id}, or
+	 * {@code null} if not found.
+	 * @param id the registration identifier
+	 * @return the {@link RegisteredClient} if found, otherwise {@code null}
+	 */
+	@Override
+	public RegisteredClient findById(String id) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * 重写原生方法支持redis缓存
+	 * @param clientId 客戶端
+	 * @return 注册客户
+	 */
+	@Override
+	@SneakyThrows
+	@Cacheable(value = CacheConstants.CLIENT_DETAILS_KEY, key = "#clientId", unless = "#result == null")
+	public RegisteredClient findByClientId(String clientId) {
+
+		SysOauthClientDetails clientDetails = clientDetailsService.getClientDetailsById(clientId);
+		Optional.ofNullable(clientDetails).orElseThrow(() -> new OAuth2AuthorizationCodeRequestAuthenticationException(
+				new OAuth2Error("客户端查询异常"), null));
+
+		RegisteredClient.Builder builder = RegisteredClient.withId(clientDetails.getClientId())
+			.clientId(clientDetails.getClientId())
+			.clientSecret(SecurityConstants.NOOP + clientDetails.getClientSecret())
+			.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
+
+		for (String authorizedGrantType : clientDetails.getAuthorizedGrantTypes()) {
+			builder.authorizationGrantType(new AuthorizationGrantType(authorizedGrantType));
+
+		}
+		// 回调地址
+		Optional.ofNullable(clientDetails.getWebServerRedirectUri())
+			.ifPresent(redirectUri -> Arrays.stream(redirectUri.split(StrUtil.COMMA))
+				.filter(StrUtil::isNotBlank)
+				.forEach(builder::redirectUri));
+
+		// scope
+		Optional.ofNullable(clientDetails.getScope())
+			.ifPresent(scope -> Arrays.stream(scope.split(StrUtil.COMMA))
+				.filter(StrUtil::isNotBlank)
+				.forEach(builder::scope));
+
+		return builder
+			.tokenSettings(TokenSettings.builder()
+				.accessTokenFormat(OAuth2TokenFormat.REFERENCE)
+				.accessTokenTimeToLive(Duration.ofSeconds(Optional.ofNullable(clientDetails.getAccessTokenValidity())
+					.orElse(ACCESS_TOKEN_VALIDITY_SECONDS)))
+				.refreshTokenTimeToLive(Duration.ofSeconds(Optional.ofNullable(clientDetails.getRefreshTokenValidity())
+					.orElse(REFRESH_TOKEN_VALIDITY_SECONDS)))
+				.build())
+			.clientSettings(ClientSettings.builder()
+				.requireAuthorizationConsent(!BooleanUtil.toBoolean(clientDetails.getAutoapprove()))
+				.build())
+			.build();
+
+	}
+
+}

+ 103 - 0
kxs-admin/src/main/java/com/kxs/admin/biz/security/LxqUserDetailsServiceImpl.java

@@ -0,0 +1,103 @@
+package com.kxs.admin.biz.security;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ArrayUtil;
+import com.kxs.common.core.constant.CacheConstants;
+import com.kxs.common.core.constant.CommonConstants;
+import com.kxs.common.core.constant.SecurityConstants;
+import com.kxs.common.core.constant.enums.ErrorTypeEnum;
+import com.kxs.common.security.model.LxqSecurityUser;
+import com.kxs.common.security.service.LxqUserDetailsService;
+import com.kxs.system.biz.domain.dto.UserInfo;
+import com.kxs.system.biz.model.SysUser;
+import com.kxs.system.biz.service.SysUserService;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cache.Cache;
+import org.springframework.cache.CacheManager;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * <p>
+ * 继承 oauth2 security实现类登录
+ * </p>
+ *
+ * @author 没秃顶的码农 没秃顶的码农
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class LxqUserDetailsServiceImpl implements LxqUserDetailsService {
+
+	private final SysUserService sysUserService;
+
+	private final CacheManager cacheManager;
+
+	/**
+	 * 用户名密码登录
+	 * @param username 用户名
+	 * @return 用户详细信息
+	 */
+	@Override
+	@SneakyThrows
+	public UserDetails loadUserByUsername(String username) {
+		Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
+		if (cache != null && cache.get(username) != null) {
+			return (LxqSecurityUser) Objects.requireNonNull(cache.get(username)).get();
+		}
+
+		UserInfo info = sysUserService.loadUserByUsername(username);
+
+		Optional.ofNullable(info).orElseThrow(() -> new UsernameNotFoundException(ErrorTypeEnum.USER_NOT_FOUND.getDescription()));
+
+		UserDetails userDetails = getUserDetails(info);
+
+		if (cache != null) {
+			cache.put(username, userDetails);
+		}
+		return userDetails;
+	}
+
+	@Override
+	public int getOrder() {
+		return Integer.MIN_VALUE;
+	}
+
+	/**
+	 * 获取用户详细信息
+	 * @param info 用户信息
+	 * @return UserDetails
+	 */
+	private UserDetails getUserDetails(UserInfo info) {
+		if (info == null) {
+			throw new UsernameNotFoundException("用户不存在");
+		}
+
+		Set<String> dbAuthsSet = new HashSet<>();
+
+		if (ArrayUtil.isNotEmpty(info.getRoles())) {
+			// 获取角色
+			Arrays.stream(info.getRoles()).forEach(role -> dbAuthsSet.add(SecurityConstants.ROLE + role));
+			// 获取资源
+			dbAuthsSet.addAll(Arrays.asList(info.getPermissions()));
+
+		}
+
+		Collection<GrantedAuthority> authorities = AuthorityUtils
+			.createAuthorityList(dbAuthsSet.toArray(new String[0]));
+		SysUser user = info.getSysUser();
+
+		// 构造security用户
+		return new LxqSecurityUser(user.getUserId(), user.getUsername(), SecurityConstants.BCRYPT + user.getPassword(),
+				user.getPhone(), null, true, true, true, CharSequenceUtil.equals(user.getLockFlag(), CommonConstants.STATUS_NORMAL),
+				authorities);
+	}
+
+}

+ 95 - 0
kxs-common/lxq-common-core/pom.xml

@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.kxs</groupId>
+        <artifactId>kxs-common</artifactId>
+        <version>3.5.9</version>
+    </parent>
+
+    <artifactId>lxq-common-core</artifactId>
+    <packaging>jar</packaging>
+
+    <description>lxq 公共工具类核心包</description>
+
+    <properties>
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <!--hutool-->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-core</artifactId>
+        </dependency>
+        <!--redis-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <!--server-api-->
+        <dependency>
+            <groupId>jakarta.servlet</groupId>
+            <artifactId>jakarta.servlet-api</artifactId>
+        </dependency>
+        <!--hibernate-validator-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+        <!--json模块-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-json</artifactId>
+        </dependency>
+        <!--oauth server 依赖-->
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-core</artifactId>
+        </dependency>
+
+        <!--阿里云SLS日志包-->
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+            <version>2.5.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun.openservices</groupId>
+            <artifactId>aliyun-log-logback-appender</artifactId>
+            <version>0.1.18</version>
+        </dependency>
+        <!--spring-webmvc-->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <!--redisson-->
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson-spring-boot-starter</artifactId>
+            <version>3.24.3</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>14</source>
+                    <target>14</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 6 - 0
kxs-common/lxq-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1,6 @@
+com.kxs.common.core.config.RedisTemplateConfiguration
+com.kxs.common.core.config.RestTemplateConfiguration
+com.kxs.common.core.util.SpringContextHolder
+com.kxs.common.core.config.WebMvcConfiguration
+com.kxs.common.core.config.JacksonConfiguration
+com.kxs.common.core.exception.GlobalBizExceptionHandler

+ 9 - 0
kxs-common/lxq-common-core/src/main/resources/banner.txt

@@ -0,0 +1,9 @@
+${AnsiColor.BRIGHT_YELLOW}
+
+   _      _  __    ___
+  | |    | |/ /   | _ )
+  | |__  | ' <    | _ \
+  |____| |_|\_\   |___/
+_|"""""|_|"""""|_|"""""|
+"`-0-0-'"`-0-0-'"`-0-0-'
+

+ 128 - 0
kxs-common/lxq-common-core/src/main/resources/logback-spring.xml

@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<configuration debug="false" scan="false">
+	<springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/>
+	<property name="log.path" value="logs/${spring.application.name}"/>
+	<!-- 彩色日志格式 -->
+	<property name="CONSOLE_LOG_PATTERN"
+			  value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
+	<property name="FILE_LOG_PATTERN" value=":%d{yyyy-MM-dd HH:mm:ss.SSS} %5p %t %c{1}: %m%n"/>
+	<!-- 彩色日志依赖的渲染类 -->
+	<conversionRule conversionWord="clr" class="org.springframework.boot.logging.logback.ColorConverter"/>
+	<conversionRule conversionWord="wex"
+					class="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
+	<conversionRule conversionWord="wEx"
+					class="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
+	<!-- Console log output -->
+	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+
+	<!-- Log file debug output -->
+	<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>${log.path}/debug.log</file>
+		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+			<fileNamePattern>${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+			<maxFileSize>50MB</maxFileSize>
+			<maxHistory>30</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${FILE_LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+
+	<!-- Log file error output -->
+	<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>${log.path}/error.log</file>
+		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+			<fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+			<maxFileSize>50MB</maxFileSize>
+			<maxHistory>30</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${FILE_LOG_PATTERN}</pattern>
+		</encoder>
+		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+			<level>ERROR</level>
+		</filter>
+	</appender>
+	<appender name="aliyun" class="com.aliyun.openservices.log.logback.LoghubAppender">
+		<!-- Configure account and network  -->
+		<endpoint>cn-chengdu.log.aliyuncs.com</endpoint>
+		<!-- 填写sls key密钥 -->
+		<accessKeyId>LTAI5tFQDZmc4ybRYembzVMb</accessKeyId>
+		<accessKeySecret>c7rEI6VrokQ3KtgMnDTS0ltjG47BEx</accessKeySecret>
+
+		<project>lxq-store</project>
+		<!--logStore名称 -->
+		<logStore>lxq-logs</logStore>
+
+		<!-- Optional parameters -->
+		<!-- 主题名称 -->
+		<topic>${spring.application.name}</topic>
+		<!--		#单个 producer 实例能缓存的日志大小上限,默认为 100MB。-->
+		<totalSizeInBytes>104857600</totalSizeInBytes>
+		<maxBlockMs>0</maxBlockMs>
+		<!--		执行日志发送任务的线程池大小,默认为可用处理器个数。-->
+		<ioThreadCount>8</ioThreadCount>
+		<batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes>
+		<batchCountThreshold>4096</batchCountThreshold>
+		<lingerMs>2000</lingerMs>
+		<retries>10</retries>
+		<baseRetryBackoffMs>100</baseRetryBackoffMs>
+		<maxRetryBackoffMs>50000</maxRetryBackoffMs>
+
+		<!-- 可选项 通过配置 encoder 的 pattern 自定义 log 的格式 -->
+		<encoder>
+			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
+		</encoder>
+
+		<!--  Optional parameters -->
+		<timeFormat>yyyy-MM-dd'T'HH:mmZ</timeFormat>
+		<!-- 可选项 设置时区 -->
+		<timeZone>Asia/Shanghai</timeZone>
+		<mdcFields>
+			TraceId,#####
+		</mdcFields>
+		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+			<level>ERROR</level>
+			<level>INFO</level>
+		</filter>
+
+	</appender>
+	<!--为了防止进程退出时,内存中的数据丢失,请加上此选项-->
+	<shutdownHook class="ch.qos.logback.core.hook.DefaultShutdownHook"/>
+	<!-- 可用来获取StatusManager中的状态 -->
+	<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener"/>
+
+	<!-- 解决debug模式下循环发送的问题 -->
+	<logger name="org.apache.http.impl.conn.Wire" level="WARN" />
+
+	<!-- 引入sls日志 -->
+	<springProfile name="dev">
+		<root level="INFO">
+			<appender-ref ref="console"/>
+			<appender-ref ref="debug"/>
+			<appender-ref ref="error"/>
+		</root>
+	</springProfile>
+
+	<!-- Level: FATAL 0  ERROR 3  WARN 4  INFO 6  DEBUG 7 -->
+
+	<springProfile name="test">
+		<root level="INFO">
+			<appender-ref ref="console"/>
+			<appender-ref ref="debug"/>
+			<appender-ref ref="error"/>
+		</root>
+	</springProfile>
+	<springProfile name="prod">
+		<root level="INFO">
+			<appender-ref ref="console"/>
+			<appender-ref ref="aliyun" />
+		</root>
+	</springProfile>
+
+</configuration>

+ 99 - 0
kxs-common/lxq-common-excel/pom.xml

@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.kxs</groupId>
+        <artifactId>kxs-common</artifactId>
+        <version>3.5.9</version>
+    </parent>
+    <artifactId>lxq-common-excel</artifactId>
+    <description>lxq 导入导出功能</description>
+
+    <developers>
+        <developer>
+            <name>没秃顶的码农</name>
+            <email>609827073@qq.com</email>
+        </developer>
+    </developers>
+    <properties>
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <easyexcel.version>3.3.2</easyexcel.version>
+        <mica.version>3.0.0</mica.version>
+        <spring.checkstyle.plugin>0.0.39</spring.checkstyle.plugin>
+        <commons-compress>1.21</commons-compress>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.servlet</groupId>
+            <artifactId>jakarta.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-core</artifactId>
+        </dependency>
+        <!--caffeine 替换LB 默认缓存实现-->
+        <dependency>
+            <groupId>com.github.ben-manes.caffeine</groupId>
+            <artifactId>caffeine</artifactId>
+        </dependency>
+        <!--引入AOP依赖-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>${easyexcel.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.commons</groupId>
+                    <artifactId>commons-compress</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-compress</artifactId>
+            <version>${commons-compress}</version>
+        </dependency>
+        <!-- lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <!-- mica-auto -->
+        <dependency>
+            <groupId>net.dreamlu</groupId>
+            <artifactId>mica-auto</artifactId>
+            <version>${mica.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <!-- test -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>

+ 1 - 0
kxs-common/lxq-common-excel/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+com.kxs.common.excel.ResponseExcelAutoConfiguration

+ 55 - 0
kxs-common/lxq-common-idempotent/pom.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.kxs</groupId>
+        <artifactId>kxs-common</artifactId>
+        <version>3.5.9</version>
+    </parent>
+
+    <artifactId>lxq-common-idempotent</artifactId>
+
+    <properties>
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <mica.version>3.0.0</mica.version>
+        <redisson.version>3.16.2</redisson.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <!--aop-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <!--redisson-->
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson-spring-boot-starter</artifactId>
+            <version>${redisson.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>net.dreamlu</groupId>
+            <artifactId>mica-auto</artifactId>
+            <version>${mica.version}</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>

+ 1 - 0
kxs-common/lxq-common-idempotent/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+com.kxs.common.idempotent.IdempotentAutoConfiguration

+ 54 - 0
kxs-common/lxq-common-log/pom.xml

@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.kxs</groupId>
+        <artifactId>kxs-common</artifactId>
+        <version>3.5.9</version>
+    </parent>
+
+    <artifactId>lxq-common-log</artifactId>
+    <packaging>jar</packaging>
+
+    <description>lxq 日志服务</description>
+
+    <properties>
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <!--工具类核心包-->
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-core</artifactId>
+        </dependency>
+        <!--引入AOP依赖-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-extra</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-http</artifactId>
+        </dependency>
+        <!--安全依赖获取上下文信息-->
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-oauth2-core</artifactId>
+        </dependency>
+
+    </dependencies>
+
+</project>

+ 30 - 0
kxs-common/lxq-common-log/src/main/resources/META-INF/spring-configuration-metadata.json

@@ -0,0 +1,30 @@
+{
+  "groups": [
+    {
+      "name": "security.log",
+      "type": "com.kxs.common.log.config.LxqLogProperties",
+      "sourceType": "com.kxs.common.log.config.LxqLogProperties"
+    }
+  ],
+  "properties": [
+    {
+      "name": "security.log.enabled",
+      "type": "java.lang.Boolean",
+      "description": "开启日志记录",
+      "sourceType": "com.kxs.common.log.config.LxqLogProperties"
+    },
+    {
+      "name": "security.log.exclude-fields",
+      "type": "java.util.List<java.lang.String>",
+      "description": "放行字段,password,mobile,idcard,phone",
+      "sourceType": "com.kxs.common.log.config.LxqLogProperties"
+    },
+    {
+      "name": "security.log.max-length",
+      "type": "java.lang.Integer",
+      "description": "请求报文最大存储长度",
+      "sourceType": "com.kxs.common.log.config.LxqLogProperties"
+    }
+  ],
+  "hints": []
+}

+ 1 - 0
kxs-common/lxq-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+com.kxs.common.log.LogAutoConfiguration

+ 30 - 0
kxs-common/lxq-common-mq/pom.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.kxs</groupId>
+        <artifactId>kxs-common</artifactId>
+        <version>3.5.9</version>
+    </parent>
+
+    <artifactId>lxq-common-mq</artifactId>
+    <packaging>jar</packaging>
+
+    <properties>
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-amqp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-core</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 3 - 0
kxs-common/lxq-common-mq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1,3 @@
+com.kxs.common.mq.config.RabbitConfiguration
+com.kxs.common.mq.config.RabbitMQBeanProcessor
+com.kxs.common.mq.handlers.rabbit.RabbitMQSender

+ 79 - 0
kxs-common/lxq-common-mybatis/pom.xml

@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.kxs</groupId>
+        <artifactId>kxs-common</artifactId>
+        <version>3.5.9</version>
+    </parent>
+
+    <artifactId>lxq-common-mybatis</artifactId>
+    <packaging>jar</packaging>
+
+    <properties>
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <!--mybatis-->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-annotation</artifactId>
+        </dependency>
+        <!-- mybatis-plus 3.5.9 需要单独引入此依赖-->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-jsqlparser</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-extension</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.yulichang</groupId>
+            <artifactId>mybatis-plus-join-boot-starter</artifactId>
+        </dependency>
+        <!--swagger  注解-->
+        <dependency>
+            <groupId>io.swagger.core.v3</groupId>
+            <artifactId>swagger-annotations-jakarta</artifactId>
+        </dependency>
+        <!--server-api-->
+        <dependency>
+            <groupId>jakarta.servlet</groupId>
+            <artifactId>jakarta.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <!--security 依赖-->
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-core</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-core</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>16</source>
+                    <target>16</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 1 - 0
kxs-common/lxq-common-mybatis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+com.kxs.common.mybatis.MybatisAutoConfiguration

+ 43 - 0
kxs-common/lxq-common-oss/pom.xml

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.kxs</groupId>
+        <artifactId>kxs-common</artifactId>
+        <version>3.5.9</version>
+    </parent>
+
+    <artifactId>lxq-common-oss</artifactId>
+    <packaging>jar</packaging>
+
+    <properties>
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>14</source>
+                    <target>14</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 1 - 0
kxs-common/lxq-common-oss/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+com.kxs.common.file.oss.OssAutoConfiguration

+ 57 - 0
kxs-common/lxq-common-pay/pom.xml

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.kxs</groupId>
+        <artifactId>kxs-common</artifactId>
+        <version>3.5.9</version>
+    </parent>
+
+    <artifactId>lxq-common-pay</artifactId>
+    <description>三方支付插件</description>
+
+    <properties>
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-extra</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alipay.sdk</groupId>
+            <artifactId>alipay-sdk-java</artifactId>
+            <version>4.39.48.ALL</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.springboot</groupId>
+            <artifactId>best-pay-sdk</artifactId>
+            <version>1.3.7</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-pay</artifactId>
+            <version>4.7.0</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>16</source>
+                    <target>16</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 1 - 0
kxs-common/lxq-common-pay/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+com.kxs.common.pay.PayConfiguration

+ 73 - 0
kxs-common/lxq-common-security/pom.xml

@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.kxs</groupId>
+        <artifactId>kxs-common</artifactId>
+        <version>3.5.9</version>
+    </parent>
+
+    <artifactId>lxq-common-security</artifactId>
+    <packaging>jar</packaging>
+
+    <description>lxq 安全工具类</description>
+
+
+    <properties>
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <!--工具类核心包-->
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-extra</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-oauth2-jose</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-oauth2-authorization-server</artifactId>
+            <version>${spring.authorization.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+        <!-- log -->
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-log</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>16</source>
+                    <target>16</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 4 - 0
kxs-common/lxq-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1,4 @@
+com.kxs.common.security.service.LxqRedisOAuth2AuthorizationService
+com.kxs.common.security.service.LxqRedisOAuth2AuthorizationConsentService
+com.kxs.common.security.component.LxqSecurityInnerAspect
+com.kxs.common.security.component.LxqSecurityMessageSourceConfiguration

+ 40 - 0
kxs-common/lxq-common-swagger/pom.xml

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.kxs</groupId>
+        <artifactId>kxs-common</artifactId>
+        <version>3.5.9</version>
+    </parent>
+
+    <artifactId>lxq-common-swagger</artifactId>
+    <packaging>jar</packaging>
+
+    <description>lxq 接口文档</description>
+
+    <properties>
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <!--接口文档-->
+        <dependency>
+            <groupId>org.springdoc</groupId>
+            <artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
+        </dependency>
+        <!--webflux 相关包-->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webflux</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>

+ 7 - 0
kxs-common/lxq-common-swagger/src/main/resources/openapi-config.yaml

@@ -0,0 +1,7 @@
+# swagger 配置
+swagger:
+  enabled: true
+  title: lxq Swagger API
+  gateway: http://${GATEWAY-HOST:127.0.0.1}:${GATEWAY-PORT:9999}
+  token-url: ${swagger.gateway}/auth/oauth2/token
+  scope: server

+ 42 - 0
kxs-common/pom.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>com.kxs</groupId>
+        <artifactId>kxs</artifactId>
+        <version>3.5.9</version>
+    </parent>
+
+    <artifactId>kxs-common</artifactId>
+    <packaging>pom</packaging>
+
+    <description>lxq 公共聚合模块</description>
+
+
+    <modules>
+        <module>lxq-common-core</module>
+        <module>lxq-common-security</module>
+        <module>lxq-common-log</module>
+        <module>lxq-common-pay</module>
+        <module>lxq-common-mybatis</module>
+        <module>lxq-common-swagger</module>
+        <module>lxq-common-oss</module>
+        <module>lxq-common-mq</module>
+        <module>lxq-common-idempotent</module>
+        <module>lxq-common-excel</module>
+    </modules>
+    <dependencyManagement>
+        <dependencies>
+            <!--lxq 公共版本定义-->
+            <dependency>
+                <groupId>com.kxs</groupId>
+                <artifactId>lxq-common-core</artifactId>
+                <version>${kxs.common.version}</version>
+            </dependency>
+
+        </dependencies>
+    </dependencyManagement>
+</project>

+ 13 - 0
kxs-quartz/Dockerfile

@@ -0,0 +1,13 @@
+FROM alibabadragonwell/dragonwell:17-anolis
+
+WORKDIR /sky-quartz
+
+ARG JAR_FILE=target/sky-quartz.jar
+
+COPY ${JAR_FILE} app.jar
+
+EXPOSE 4000
+
+ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom"
+
+CMD sleep 60; java $JAVA_OPTS -jar app.jar

+ 146 - 0
kxs-quartz/pom.xml

@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>com.kxs</groupId>
+        <artifactId>kxs</artifactId>
+        <version>3.5.9</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>kxs-quartz</artifactId>
+    <packaging>jar</packaging>
+
+    <description>基于quartz后台定时任务模块</description>
+
+    <dependencies>
+        <!--日志处理-->
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-log</artifactId>
+        </dependency>
+        <!--mybatis-->
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-mybatis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
+        </dependency>
+        <!--数据库-->
+        <dependency>
+            <groupId>com.mysql</groupId>
+            <artifactId>mysql-connector-j</artifactId>
+        </dependency>
+        <!-- quartz 模块 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-quartz</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>kxs-system</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+            <!--打包java路径下的静态文件-->
+            <resource>
+                <directory>src/main/java</directory>
+                <filtering>false</filtering>
+                <includes>
+                    <include>**/*.xml</include>
+                </includes>
+            </resource>
+        </resources>
+        <plugins>
+            <!--该插件的作用是打包spring-boot的jar包-->
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <!--不排除的话,systemScope的依赖包会自动被此插件打包进xxx.jar\BOOT-INF\lib,和外部依赖产生冲突 -->
+                    <includeSystemScope>false</includeSystemScope>
+                    <skip>false</skip>
+                    <!--分离Jar包-->
+                    <layout>ZIP</layout>
+                    <includes>
+                        <include>
+                            <groupId>nothing</groupId>
+                            <artifactId>nothing</artifactId>
+                        </include>
+                    </includes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- 该插件的作用是复制依赖的jar包到指定的文件夹里 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-dependencies</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/lib/</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- 该插件的作用是复制指定的文件 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <!-- 复制配置文件 -->
+                    <execution>
+                        <id>copy-resources</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <resources>
+                                <!--复制资源文件到外部,注意这里先不做filtering处理,防止某些静态文件损坏-->
+                                <resource>
+                                    <filtering>false</filtering>
+                                    <directory>src/main/resources</directory>
+                                    <includes>
+                                        <include>**/*</include>
+                                    </includes>
+                                </resource>
+                                <!--仅针对配置文件filtering处理(占位符@@等)-->
+                                <resource>
+                                    <directory>src/main/resources</directory>
+                                    <filtering>true</filtering>
+                                    <includes>
+                                        <include>*.xml</include>
+                                        <include>*.yml</include>
+                                        <include>*.properties</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                            <outputDirectory>${project.build.directory}/config</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 7 - 0
kxs-quartz/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1,7 @@
+com.kxs.daemon.quartz.config.LxqQuartzAutoConfiguration
+com.kxs.daemon.quartz.config.LxqQuartzConfig
+com.kxs.daemon.quartz.config.LxqInitQuartzJob
+com.kxs.daemon.quartz.config.LxqQuartzCustomizerConfig
+com.kxs.daemon.quartz.config.QuartzInvokeFactory
+com.kxs.daemon.quartz.config.AutowireCapableBeanJobFactory
+com.kxs.daemon.quartz.config.LxqQuartzFactory

+ 81 - 0
kxs-system/pom.xml

@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>kxs</artifactId>
+        <groupId>com.kxs</groupId>
+        <version>3.5.9</version>
+    </parent>
+
+    <packaging>jar</packaging>
+    <artifactId>kxs-system</artifactId>
+
+    <description>system系统模块</description>
+
+    <dependencies>
+
+        <!--日志处理-->
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-log</artifactId>
+        </dependency>
+        <!-- orm 模块-->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.mysql</groupId>
+            <artifactId>mysql-connector-j</artifactId>
+        </dependency>
+        <!--多数据源-->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
+        </dependency>
+        <!--接口文档-->
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-swagger</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-poi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-json</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-oss</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-idempotent</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-excel</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>lxq-common-mybatis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-crypto</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15to18</artifactId>
+            <version>1.68</version>
+        </dependency>
+    </dependencies>
+</project>

+ 35 - 0
kxs-system/src/main/java/com/kxs/system/biz/config/AesConfigProperties.java

@@ -0,0 +1,35 @@
+package com.kxs.system.biz.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.List;
+
+
+/**
+ * @author LXQ
+ * @date 2021/10/4
+ * <p>
+ * 网关配置文件
+ */
+@Data
+@ConfigurationProperties("gateway.aes")
+public class AesConfigProperties {
+
+	private Boolean enabled = true;
+
+	private String encodeKey;
+
+	private String encodeIv;
+
+	private String encodeMode;
+
+	private String encodePadding;
+
+
+	/**
+	 * 需要过滤不解密的接口
+	 */
+	private List<String> filterUrl;
+
+}

+ 24 - 0
kxs-system/src/main/java/com/kxs/system/biz/config/GatewayConfigProperties.java

@@ -0,0 +1,24 @@
+package com.kxs.system.biz.config;
+
+import com.kxs.system.biz.filter.ValidateCodeGatewayFilter;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.List;
+
+/**
+ * @author LXQ
+ * @date 2021/10/4
+ * <p>
+ * 网关配置文件
+ */
+@Data
+@ConfigurationProperties("gateway")
+public class GatewayConfigProperties {
+
+	/**
+	 * 网关不需要校验验证码的客户端 {@link ValidateCodeGatewayFilter}
+	 */
+	private List<String> ignoreClients;
+
+}

+ 80 - 0
kxs-system/src/main/java/com/kxs/system/biz/config/SysConfigAutoConfiguration.java

@@ -0,0 +1,80 @@
+package com.kxs.system.biz.config;
+
+import cn.hutool.crypto.symmetric.AES;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kxs.system.biz.event.SysLogListener;
+import com.kxs.system.biz.filter.RequestDecoderFilter;
+import com.kxs.common.core.constant.SecurityConstants;
+import com.kxs.common.log.config.LxqLogProperties;
+import com.kxs.system.biz.filter.ValidateCodeGatewayFilter;
+import com.kxs.system.biz.service.SysLogService;
+import lombok.RequiredArgsConstructor;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.data.redis.core.RedisTemplate;
+
+
+/**
+ * @author lixueqiang
+ */
+@ComponentScan(basePackages = "com.kxs.system")
+@MapperScan(basePackages = "com.kxs.system.biz.mapper")
+@EnableConfigurationProperties({AesConfigProperties.class, GatewayConfigProperties.class})
+@RequiredArgsConstructor
+public class SysConfigAutoConfiguration {
+
+    private final AesConfigProperties aesConfigProperties;
+
+    private final GatewayConfigProperties gatewayConfigProperties;
+
+
+    @Bean
+    public SysLogListener sysLogListener(SysLogService sysLogService, LxqLogProperties logProperties) {
+        return new SysLogListener(sysLogService, logProperties);
+    }
+
+    @Bean
+    public FilterRegistrationBean<ValidateCodeGatewayFilter> imageCodeFilterRegistration(RedisTemplate<String, Object> redisTemplate, ObjectMapper objectMapper) {
+
+        FilterRegistrationBean<ValidateCodeGatewayFilter> registration = new FilterRegistrationBean<>();
+        registration.setFilter(new ValidateCodeGatewayFilter(redisTemplate, objectMapper, gatewayConfigProperties));
+        registration.addUrlPatterns(SecurityConstants.OAUTH_TOKEN_URL);
+        registration.setOrder(Integer.MIN_VALUE);
+        return registration;
+    }
+
+    /**
+     * 加解密过滤器
+     */
+    @Bean
+    @ConditionalOnProperty(name = "gateway.aes.enabled", matchIfMissing = true)
+    @DependsOn("cryptoAes")
+    public FilterRegistrationBean<RequestDecoderFilter> requestDecoderFilterRegistration(AES cryptoAes, ObjectMapper objectMapper) {
+
+        FilterRegistrationBean<RequestDecoderFilter> registration = new FilterRegistrationBean<>();
+        registration.setFilter(new RequestDecoderFilter(cryptoAes, objectMapper, aesConfigProperties));
+        registration.addUrlPatterns("/*");
+        registration.setOrder(Integer.MIN_VALUE + 1);
+        return registration;
+    }
+
+    /**
+     * <p>
+     * aes加密配置 此处设在配置类可以避免每次请求都去创建加密类,以此节约性能
+     * </p>
+     * @return {@link AES}
+     */
+    @Bean
+    public AES cryptoAes() {
+        return new AES(aesConfigProperties.getEncodeMode(), aesConfigProperties.getEncodePadding(),
+                // 密钥,可以自定义
+                aesConfigProperties.getEncodeKey().getBytes(),
+                // iv加盐,按照实际需求添加
+                aesConfigProperties.getEncodeIv().getBytes());
+    }
+}

+ 29 - 0
kxs-system/src/main/java/com/kxs/system/biz/constant/enums/SysErrorTypeEnum.java

@@ -0,0 +1,29 @@
+package com.kxs.system.biz.constant.enums;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 错误类型枚举
+ *
+ * @author 没秃顶的码农
+ * @date 2023/10/29
+ */
+@Getter
+@RequiredArgsConstructor
+public enum SysErrorTypeEnum {
+
+	USER_EMPTY(-1, "用户信息为空"), CLIENT_NULL(-1, "客户端查询异常,请检查数据库链接"),
+	NOT_DATA(0, "数据为空"),
+	IMPORT_EMPTY(-1, "导入数据为空"),
+	PARAM_ERROR(0, "参数异常"),
+
+	SYS_PARAM_DELETE_SYSTEM(-1, "系统内置参数不能删除"), SYS_DICT_DELETE_SYSTEM(-1, "系统内置字典不允许删除"),
+	SYS_MENU_DELETE_EXISTING(-1, "菜单存在下级节点 删除失败"), SYS_USER_USERNAME_EXISTING(-1, "用户名已存在"),
+	SYS_USER_UPDATE_PASSWORD_ERROR(-1, "用户原密码错误"), SYS_DICT_UPDATE_SYSTEM(-1, "系统内置字典不能修改");
+
+	private final int code;
+
+	private final String description;
+
+}

+ 91 - 0
kxs-system/src/main/java/com/kxs/system/biz/domain/dto/SysLogDTO.java

@@ -0,0 +1,91 @@
+package com.kxs.system.biz.domain.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author 没秃顶的码农
+ * @date 2021/10/9
+ * <p>
+ * 日志查询传输对象
+ */
+@Data
+@Schema(description = "日志查询对象")
+public class SysLogDTO {
+
+	/**
+	 * 编号
+	 */
+	private Long id;
+
+	/**
+	 * 日志类型
+	 */
+	@NotBlank(message = "日志类型不能为空")
+	private String logType;
+
+	/**
+	 * 日志标题
+	 */
+	@NotBlank(message = "日志标题不能为空")
+	private String title;
+
+	/**
+	 * 创建者
+	 */
+	private String createBy;
+
+	/**
+	 * 更新时间
+	 */
+	private LocalDateTime updateTime;
+
+	/**
+	 * 操作IP地址
+	 */
+	private String remoteAddr;
+
+	/**
+	 * 用户代理
+	 */
+	private String userAgent;
+
+	/**
+	 * 请求URI
+	 */
+	private String requestUri;
+
+	/**
+	 * 操作方式
+	 */
+	private String method;
+
+	/**
+	 * 操作提交的数据
+	 */
+	private String params;
+
+	/**
+	 * 执行时间
+	 */
+	private Long time;
+
+	/**
+	 * 异常信息
+	 */
+	private String exception;
+
+	/**
+	 * 服务ID
+	 */
+	private String serviceId;
+
+	/**
+	 * 创建时间区间 [开始时间,结束时间]
+	 */
+	private LocalDateTime[] createTime;
+
+}

+ 16 - 0
kxs-system/src/main/java/com/kxs/system/biz/domain/dto/SysRuleMakingDTO.java

@@ -0,0 +1,16 @@
+package com.kxs.system.biz.domain.dto;
+
+import lombok.Data;
+
+/**
+ * @author debao.yang
+ * @createTime 2024-08-27 14:20
+ */
+@Data
+public class SysRuleMakingDTO {
+
+    /**
+     * 标题
+     */
+    private String title;
+}

+ 42 - 0
kxs-system/src/main/java/com/kxs/system/biz/domain/dto/UserDTO.java

@@ -0,0 +1,42 @@
+package com.kxs.system.biz.domain.dto;
+
+import com.kxs.system.biz.model.SysUser;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * @author 没秃顶的码农
+ * @date 2023/11/5
+ */
+@Data
+@Schema(description = "系统用户传输对象")
+@EqualsAndHashCode(callSuper = true)
+public class UserDTO extends SysUser {
+
+	/**
+	 * 角色ID
+	 */
+	@Schema(description = "角色id集合")
+	private List<Long> role;
+
+	/**
+	 * 部门id
+	 */
+	@Schema(description = "部门id")
+	private Long deptId;
+
+	/**
+	 * 岗位ID
+	 */
+	private List<Long> post;
+
+	/**
+	 * 新密码
+	 */
+	@Schema(description = "新密码")
+	private String newPwd;
+
+}

+ 35 - 0
kxs-system/src/main/java/com/kxs/system/biz/domain/dto/UserInfo.java

@@ -0,0 +1,35 @@
+package com.kxs.system.biz.domain.dto;
+
+import com.kxs.system.biz.model.SysUser;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author 没秃顶的码农
+ * @date 2023/11/11
+ */
+@Data
+@Schema(description = "用户信息")
+public class UserInfo implements Serializable {
+
+	/**
+	 * 用户基本信息
+	 */
+	@Schema(description = "用户基本信息")
+	private SysUser sysUser;
+
+	/**
+	 * 权限标识集合
+	 */
+	@Schema(description = "权限标识集合")
+	private String[] permissions;
+
+	/**
+	 * 角色集合
+	 */
+	@Schema(description = "角色标识集合")
+	private Long[] roles;
+
+}

+ 20 - 0
kxs-system/src/main/java/com/kxs/system/biz/domain/vo/RoleEditVO.java

@@ -0,0 +1,20 @@
+package com.kxs.system.biz.domain.vo;
+
+import com.kxs.system.biz.model.SysRole;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author 没秃顶的码农
+ * @date 2021/2/10
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class RoleEditVO extends SysRole {
+
+	/**
+	 * 菜单列表
+	 */
+	private String[] permissions;
+
+}

+ 65 - 0
kxs-system/src/main/java/com/kxs/system/biz/domain/vo/RoleExcelVO.java

@@ -0,0 +1,65 @@
+package com.kxs.system.biz.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.kxs.common.excel.annotation.ExcelLine;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 角色excel 对应的实体
+ *
+ * @author 没秃顶的码农
+ * @date 2022/3/21
+ */
+@Data
+@ColumnWidth(30)
+public class RoleExcelVO implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 导入时候回显行号
+	 */
+	@ExcelLine
+	@ExcelIgnore
+	private Long lineNum;
+
+	/**
+	 * 主键ID
+	 */
+	@ExcelProperty("角色编号")
+	private Long roleId;
+
+	/**
+	 * 角色名称
+	 */
+	@NotBlank(message = "角色名称不能为空")
+	@ExcelProperty("角色名称")
+	private String roleName;
+
+	/**
+	 * 角色标识
+	 */
+	@NotBlank(message = "角色标识不能为空")
+	@ExcelProperty("角色标识")
+	private String roleCode;
+
+	/**
+	 * 角色描述
+	 */
+	@NotBlank(message = "角色描述不能为空")
+	@ExcelProperty("角色描述")
+	private String roleDesc;
+
+	/**
+	 * 创建时间
+	 */
+	@ExcelProperty(value = "创建时间")
+	private LocalDateTime createTime;
+
+}

+ 28 - 0
kxs-system/src/main/java/com/kxs/system/biz/domain/vo/RoleVO.java

@@ -0,0 +1,28 @@
+package com.kxs.system.biz.domain.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * @author 没秃顶的码农
+ * @date 2021/2/10
+ */
+@Data
+@Schema(description = "前端角色展示对象")
+public class RoleVO {
+
+	/**
+	 * 角色id
+	 */
+	@NotNull(message = "角色id不能为空")
+	private Long roleId;
+
+	/**
+	 * 菜单列表
+	 */
+	@NotBlank(message = "菜单列表不能为空")
+	private String menuIds;
+
+}

+ 17 - 0
kxs-system/src/main/java/com/kxs/system/biz/domain/vo/SysFeignInterfaceConfigVO.java

@@ -0,0 +1,17 @@
+package com.kxs.system.biz.domain.vo;
+
+import lombok.Data;
+
+/**
+ * @author debao.yang
+ * @createTime 2024-11-28 10:00
+ */
+@Data
+public class SysFeignInterfaceConfigVO {
+
+    private Integer paramType;
+
+    private String ifCode;
+
+    private String name;
+}

+ 28 - 0
kxs-system/src/main/java/com/kxs/system/biz/domain/vo/TokenVo.java

@@ -0,0 +1,28 @@
+package com.kxs.system.biz.domain.vo;
+
+import lombok.Data;
+
+/**
+ * 前端展示令牌管理
+ *
+ * @author 没秃顶的码农
+ * @date 2022/6/2
+ */
+@Data
+public class TokenVo {
+
+	private String id;
+
+	private Long userId;
+
+	private String clientId;
+
+	private String username;
+
+	private String accessToken;
+
+	private String issuedAt;
+
+	private String expiresAt;
+
+}

+ 108 - 0
kxs-system/src/main/java/com/kxs/system/biz/domain/vo/UserExcelVO.java

@@ -0,0 +1,108 @@
+package com.kxs.system.biz.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.kxs.common.excel.annotation.ExcelLine;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 用户excel 对应的实体
+ *
+ * @author 没秃顶的码农
+ * @date 2021/8/4
+ */
+@Data
+@ColumnWidth(30)
+public class UserExcelVO implements Serializable {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 导入时候回显行号
+	 */
+	@ExcelLine
+	@ExcelIgnore
+	private Long lineNum;
+
+	/**
+	 * 主键ID
+	 */
+	@ExcelProperty("用户编号")
+	private Long userId;
+
+	/**
+	 * 用户名
+	 */
+	@NotBlank(message = "用户名不能为空")
+	@ExcelProperty("用户名")
+	private String username;
+
+	/**
+	 * 手机号
+	 */
+	@NotBlank(message = "手机号不能为空")
+	@ExcelProperty("手机号")
+	private String phone;
+
+	/**
+	 * 手机号
+	 */
+	@NotBlank(message = "昵称不能为空")
+	@ExcelProperty("昵称")
+	private String nickname;
+
+	/**
+	 * 手机号
+	 */
+	@NotBlank(message = "姓名不能为空")
+	@ExcelProperty("姓名")
+	private String name;
+
+	/**
+	 * 手机号
+	 */
+	@NotBlank(message = "邮箱不能为空")
+	@ExcelProperty("邮箱")
+	private String email;
+
+	/**
+	 * 部门名称
+	 */
+	@NotBlank(message = "部门名称不能为空")
+	@ExcelProperty("部门名称")
+	private String deptName;
+
+	/**
+	 * 角色列表
+	 */
+	@NotBlank(message = "角色不能为空")
+	@ExcelProperty("角色")
+	private String roleNameList;
+
+	/**
+	 * 角色列表
+	 */
+	@NotBlank(message = "岗位不能为空")
+	@ExcelProperty("岗位名称")
+	private String postNameList;
+
+	/**
+	 * 锁定标记
+	 */
+	@ExcelProperty("锁定标记,0:正常,9:已锁定")
+	private String lockFlag;
+
+	/**
+	 * 创建时间
+	 */
+	@ExcelProperty(value = "创建时间")
+	private LocalDateTime createTime;
+
+}

+ 151 - 0
kxs-system/src/main/java/com/kxs/system/biz/domain/vo/UserVO.java

@@ -0,0 +1,151 @@
+package com.kxs.system.biz.domain.vo;
+
+import com.kxs.system.biz.model.SysRole;
+import com.kxs.system.biz.model.SysPost;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 用户vo
+ *
+ * @author 没秃顶的码农
+ * @date 2023/10/29
+ */
+@Data
+@Schema(description = "前端用户展示对象")
+public class UserVO implements Serializable {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 主键ID
+	 */
+	@Schema(description = "主键")
+	private Long userId;
+
+	/**
+	 * 用户名
+	 */
+	@Schema(description = "用户名")
+	private String username;
+
+	/**
+	 * 密码
+	 */
+	@Schema(description = "密码")
+	private String password;
+
+	/**
+	 * 随机盐
+	 */
+	@Schema(description = "随机盐")
+	private String salt;
+
+	/**
+	 * 微信openid
+	 */
+	@Schema(description = "微信open id")
+	private String wxOpenid;
+
+	/**
+	 * QQ openid
+	 */
+	@Schema(description = "qq open id")
+	private String qqOpenid;
+
+	/**
+	 * gitee openid
+	 */
+	@Schema(description = "gitee open id")
+	private String giteeOpenId;
+
+	/**
+	 * 开源中国 openid
+	 */
+	@Schema(description = "开源中国 open id")
+	private String oscOpenId;
+
+	/**
+	 * 创建时间
+	 */
+	@Schema(description = "创建时间")
+	private LocalDateTime createTime;
+
+	/**
+	 * 修改时间
+	 */
+	@Schema(description = "修改时间")
+	private LocalDateTime updateTime;
+
+	/**
+	 * 0-正常,1-删除
+	 */
+	@Schema(description = "删除标记,1:已删除,0:正常")
+	private String delFlag;
+
+	/**
+	 * 锁定标记
+	 */
+	@Schema(description = "锁定标记,0:正常,9:已锁定")
+	private String lockFlag;
+
+	/**
+	 * 手机号
+	 */
+	@Schema(description = "手机号")
+	private String phone;
+
+	/**
+	 * 头像
+	 */
+	@Schema(description = "头像")
+	private String avatar;
+
+	/**
+	 * 部门ID
+	 */
+	@Schema(description = "所属部门")
+	private Long deptId;
+
+	/**
+	 * 部门名称
+	 */
+	@Schema(description = "所属部门名称")
+	private String deptName;
+
+	/**
+	 * 角色列表
+	 */
+	@Schema(description = "拥有的角色列表")
+	private List<SysRole> roleList;
+
+	/**
+	 * 岗位列表
+	 */
+	private List<SysPost> postList;
+
+	/**
+	 * 昵称
+	 */
+	@Schema(description = "昵称")
+	private String nickname;
+
+	/**
+	 * 姓名
+	 */
+	@Schema(description = "姓名")
+	private String name;
+
+	/**
+	 * 邮箱
+	 */
+	@Schema(description = "邮箱")
+	private String email;
+
+}

+ 77 - 0
kxs-system/src/main/java/com/kxs/system/biz/event/SysLogListener.java

@@ -0,0 +1,77 @@
+package com.kxs.system.biz.event;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import com.fasterxml.jackson.annotation.JsonFilter;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ser.FilterProvider;
+import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
+import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
+import com.kxs.system.biz.model.SysLog;
+import com.kxs.common.core.jackson.SkyJavaTimeModule;
+import com.kxs.common.log.config.LxqLogProperties;
+import com.kxs.common.log.event.SysLogEvent;
+import com.kxs.common.log.event.SysLogEventSource;
+import com.kxs.system.biz.service.SysLogService;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.event.EventListener;
+import org.springframework.core.annotation.Order;
+import org.springframework.scheduling.annotation.Async;
+
+import java.util.Objects;
+
+/**
+ * 异步监听日志事件
+ *
+ * @author 没秃顶的码农
+ * @date 2023/10/28
+ */
+@Slf4j
+@RequiredArgsConstructor
+public class SysLogListener implements InitializingBean {
+
+	// new 一个 避免日志脱敏策略影响全局ObjectMapper
+	private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+	private final SysLogService sysLogService;
+
+	private final LxqLogProperties logProperties;
+
+	@SneakyThrows
+	@Async
+	@Order
+	@EventListener(SysLogEvent.class)
+	public void saveSysLog(SysLogEvent event) {
+		SysLogEventSource source = (SysLogEventSource) event.getSource();
+		SysLog sysLog = new SysLog();
+		BeanUtils.copyProperties(source, sysLog);
+
+		// json 格式刷参数放在异步中处理,提升性能
+		if (Objects.nonNull(source.getBody())) {
+			String params = OBJECT_MAPPER.writeValueAsString(source.getBody());
+			sysLog.setParams(CharSequenceUtil.subPre(params, logProperties.getMaxLength()));
+		}
+		log.info("保存日志:{}", sysLog);
+		sysLogService.saveLog(sysLog);
+	}
+
+	@Override
+	public void afterPropertiesSet() {
+		OBJECT_MAPPER.addMixIn(Object.class, PropertyFilterMixIn.class);
+		String[] ignorableFieldNames = logProperties.getExcludeFields().toArray(new String[0]);
+
+		FilterProvider filters = new SimpleFilterProvider().addFilter("filter properties by name",
+				SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
+		OBJECT_MAPPER.setFilterProvider(filters);
+		OBJECT_MAPPER.registerModule(new SkyJavaTimeModule());
+	}
+
+	@JsonFilter("filter properties by name")
+	static class PropertyFilterMixIn {
+
+	}
+
+}

+ 249 - 0
kxs-system/src/main/java/com/kxs/system/biz/filter/RequestDecoderFilter.java

@@ -0,0 +1,249 @@
+package com.kxs.system.biz.filter;
+
+import cn.hutool.crypto.symmetric.AES;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kxs.system.biz.config.AesConfigProperties;
+import com.kxs.common.core.constant.CommonConstants;
+import com.kxs.common.core.exception.AesDecodeException;
+import com.kxs.common.core.util.R;
+import jakarta.servlet.*;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequestWrapper;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.IOUtils;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.PathMatcher;
+import org.springframework.util.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 请求解密过滤器
+ *
+ * @author lixueqiang
+ * @date 2026/01/09
+ */
+@Slf4j
+@RequiredArgsConstructor
+public class RequestDecoderFilter implements Filter {
+
+    private final AES cryptoAes;
+
+    private final ObjectMapper objectMapper;
+
+    private final AesConfigProperties aesConfigProperties;
+
+    private static final PathMatcher PATH_MATCHER = new AntPathMatcher();
+
+    private static final Pattern DELETE_PATH_PATTERN = Pattern.compile("(.+/)[^/]+$");
+
+    private static final List<String> FILE_TYPES = List.of("multipart/form-data");
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        HttpServletRequest httpRequest = (HttpServletRequest) request;
+        HttpServletResponse httpResponse = (HttpServletResponse) response;
+        String method = httpRequest.getMethod();
+
+
+        String requestURI = httpRequest.getServletPath();
+        //过滤接口不解密
+        if (!aesConfigProperties.getFilterUrl().isEmpty() && aesConfigProperties.getFilterUrl().contains(requestURI)) {
+            chain.doFilter(request, response);
+            return;
+        }
+        boolean match = aesConfigProperties.getFilterUrl().stream().anyMatch(url -> PATH_MATCHER.match(url, requestURI));
+        if (match) {
+            chain.doFilter(request, response);
+            return;
+        }
+
+        String contentType = httpRequest.getContentType();
+        if (StringUtils.hasText(contentType) && FILE_TYPES.stream().anyMatch(contentType::startsWith)) {
+            // 这是一个文件请求
+            chain.doFilter(request, response);
+            return;
+        }
+        try {
+            if ("GET".equalsIgnoreCase(method)) {
+                request = decryptGetRequest(httpRequest);
+            } else if ("DELETE".equalsIgnoreCase(method)) {
+                request = decryptDeleteRequest(httpRequest);
+            } else if ("POST".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) {
+                request = decryptJsonBody(httpRequest);
+            }
+            chain.doFilter(request, response);
+        } catch (AesDecodeException e) {
+            log.error("AES解密失败: {}", e.getMessage(), e);
+            handleException("解密失败", httpResponse);
+        }
+    }
+
+    private HttpServletRequest decryptGetRequest(HttpServletRequest request) {
+
+        try {
+            String encryptedValue = request.getParameter("value");
+            if (encryptedValue != null) {
+                byte[] decode = Base64.getMimeDecoder().decode(encryptedValue);
+                String decryptedValue = cryptoAes.decryptStr(new String(decode));
+                request = new ParameterDecodedRequest(request, decryptedValue);
+            }
+            return request;
+        } catch (Exception e) {
+            throw new AesDecodeException(e.getMessage());
+        }
+    }
+
+    private HttpServletRequest decryptDeleteRequest(HttpServletRequest request) {
+        try {
+            String requestURI = request.getRequestURI();
+            String[] pathSegments = requestURI.split("/");
+            String encryptedValue = pathSegments[pathSegments.length - 1];
+
+            byte[] decode = Base64.getMimeDecoder().decode(encryptedValue);
+            String decryptedValue = cryptoAes.decryptStr(new String(decode));
+
+            Matcher matcher = DELETE_PATH_PATTERN.matcher(requestURI);
+            if (matcher.find()) {
+                String lastSegment = matcher.group(1);
+                String newURI = lastSegment + decryptedValue;
+                request = new PathDecodedRequest(request, newURI, decryptedValue);
+            }
+
+
+//            Matcher matcher = DELETE_PATH_PATTERN.matcher(requestURI);
+//            if (matcher.find()) {
+//                String encryptedValue = matcher.group(2);
+//                String newURI = requestURI.replace("{" + encryptedValue + "}", decryptedValue);
+//                request = new PathDecodedRequest(request, newURI, decryptedValue);
+//            }
+            return request;
+        } catch (Exception e) {
+            throw new AesDecodeException(e.getMessage());
+        }
+    }
+
+    private HttpServletRequest decryptJsonBody(HttpServletRequest request) {
+        try {
+            byte[] rawData = IOUtils.toByteArray(request.getInputStream());
+            String encryptedJson = new String(rawData, StandardCharsets.UTF_8);
+            byte[] decode = Base64.getMimeDecoder().decode(encryptedJson);
+            String decryptedJson = cryptoAes.decryptStr(new String(decode));
+            byte[] decryptedBody = decryptedJson.getBytes(StandardCharsets.UTF_8);
+            return new CachedBodyHttpServletRequestWrapper(request, decryptedBody);
+        } catch (Exception e) {
+            throw new AesDecodeException(e.getMessage());
+        }
+    }
+
+    static class CachedBodyHttpServletRequestWrapper extends HttpServletRequestWrapper {
+        private final byte[] cachedBody;
+
+        public CachedBodyHttpServletRequestWrapper(HttpServletRequest request, byte[] cachedBody) {
+            super(request);
+            this.cachedBody = cachedBody;
+        }
+
+        @Override
+        public ServletInputStream getInputStream() {
+            return new CachedBodyServletInputStream(cachedBody);
+        }
+
+        @Override
+        public BufferedReader getReader() {
+            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(cachedBody);
+            return new BufferedReader(new InputStreamReader(byteArrayInputStream, StandardCharsets.UTF_8));
+        }
+    }
+
+    static class CachedBodyServletInputStream extends ServletInputStream {
+        private final ByteArrayInputStream inputStream;
+
+        public CachedBodyServletInputStream(byte[] cachedBody) {
+            this.inputStream = new ByteArrayInputStream(cachedBody);
+        }
+
+        @Override
+        public boolean isFinished() {
+            return inputStream.available() == 0;
+        }
+
+        @Override
+        public boolean isReady() {
+            return true;
+        }
+
+        @Override
+        public void setReadListener(ReadListener listener) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int read() {
+            return inputStream.read();
+        }
+    }
+
+    static class ParameterDecodedRequest extends HttpServletRequestWrapper {
+        private final String decryptedValue;
+
+        public ParameterDecodedRequest(HttpServletRequest request, String decryptedValue) {
+            super(request);
+            this.decryptedValue = decryptedValue;
+        }
+
+        @Override
+        public String getParameter(String name) {
+            if ("value".equals(name)) {
+                return decryptedValue;
+            }
+            return super.getParameter(name);
+        }
+    }
+
+    static class PathDecodedRequest extends HttpServletRequestWrapper {
+        private final String newURI;
+        private final String decryptedValue;
+
+        public PathDecodedRequest(HttpServletRequest request, String newURI, String decryptedValue) {
+            super(request);
+            this.newURI = newURI;
+            this.decryptedValue = decryptedValue;
+        }
+
+        @Override
+        public String getRequestURI() {
+            return newURI;
+        }
+
+        @Override
+        public String getServletPath() {
+            return newURI;
+        }
+
+        @Override
+        public String getParameter(String name) {
+            if ("value".equals(name)) {
+                return decryptedValue;
+            }
+            return super.getParameter(name);
+        }
+    }
+
+    private void handleException(String ex, HttpServletResponse response) throws IOException {
+
+        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+        response.setContentType(CommonConstants.CONTENT_TYPE);
+        response.getWriter().write(objectMapper.writeValueAsString(R.failed(ex)));
+    }
+}

+ 105 - 0
kxs-system/src/main/java/com/kxs/system/biz/filter/ValidateCodeGatewayFilter.java

@@ -0,0 +1,105 @@
+package com.kxs.system.biz.filter;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kxs.system.biz.config.GatewayConfigProperties;
+import com.kxs.common.core.constant.CacheConstants;
+import com.kxs.common.core.constant.CommonConstants;
+import com.kxs.common.core.constant.SecurityConstants;
+import com.kxs.common.core.constant.enums.ErrorTypeEnum;
+import com.kxs.common.core.exception.CheckedException;
+import com.kxs.common.core.util.R;
+import com.kxs.common.core.util.WebUtils;
+import jakarta.servlet.*;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * 验证码过滤器
+ * @author lixueqiang
+ */
+@Slf4j
+@RequiredArgsConstructor
+public class ValidateCodeGatewayFilter implements Filter {
+
+    private final RedisTemplate<String, Object> redisTemplate;
+
+    private final ObjectMapper objectMapper;
+
+    private final GatewayConfigProperties configProperties;
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+            throws IOException, ServletException {
+        HttpServletRequest httpRequest = (HttpServletRequest) request;
+        HttpServletResponse httpResponse = (HttpServletResponse) response;
+
+        if (isRefreshTokenRequest(httpRequest)) {
+            chain.doFilter(request, response);
+            return;
+        }
+        try {
+            boolean isIgnoreClient = configProperties.getIgnoreClients().contains(WebUtils.getClientId(httpRequest));
+            if (!isIgnoreClient) {
+                checkCode(httpRequest);
+            }
+        }catch (CheckedException e){
+            handleException(e.getMessage(), httpResponse);
+            return;
+        }
+        chain.doFilter(request, response);
+    }
+
+    /**
+     * 判断是否为刷新令牌请求
+     * @param request HTTP请求
+     * @return 是否为刷新令牌请求
+     */
+    private boolean isRefreshTokenRequest(HttpServletRequest request) {
+        return CharSequenceUtil.equals(SecurityConstants.REFRESH_TOKEN,
+                request.getParameter("grant_type"));
+    }
+
+    /**
+     * 检查验证码
+     *
+     * @param request HTTP请求
+     * @throws CheckedException 验证码异常
+     */
+    @SneakyThrows
+    private void checkCode(HttpServletRequest request) {
+        String code = request.getParameter("code");
+
+        if (CharSequenceUtil.isBlank(code)) {
+            throw new CheckedException(ErrorTypeEnum.VERIFICATION_CODE_IS_EMPTY.getDescription());
+        }
+
+        String randomStr = CharSequenceUtil.blankToDefault(request.getParameter("randomStr"),
+                request.getParameter(SecurityConstants.SMS_PARAMETER_NAME));
+
+        String key = CacheConstants.DEFAULT_CODE_KEY + randomStr;
+
+        Object codeObj = redisTemplate.opsForValue().get(key);
+
+        if (ObjectUtil.isEmpty(codeObj) || !Objects.equals(code, codeObj)) {
+            throw new CheckedException(ErrorTypeEnum.VERIFICATION_CODE_IS_ILLEGAL.getDescription());
+        }
+
+        redisTemplate.delete(key);
+    }
+
+    private void handleException(String ex, HttpServletResponse response) throws IOException {
+
+        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+        response.setContentType(CommonConstants.CONTENT_TYPE);
+        response.getWriter().write(objectMapper.writeValueAsString(R.failed(ex)));
+    }
+}

+ 16 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysDeptMapper.java

@@ -0,0 +1,16 @@
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysDept;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 部门管理 服务类
+ *
+ * @author 没秃顶的码农
+ * @date 2023/11/06
+ */
+@Mapper
+public interface SysDeptMapper extends BaseMapper<SysDept> {
+
+}

+ 16 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysDictItemMapper.java

@@ -0,0 +1,16 @@
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysDictItem;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 字典项
+ *
+ * @author 没秃顶的码农
+ * @date 2023/10/28
+ */
+@Mapper
+public interface SysDictItemMapper extends BaseMapper<SysDictItem> {
+
+}

+ 18 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysDictMapper.java

@@ -0,0 +1,18 @@
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysDict;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 字典表 Mapper 接口
+ * </p>
+ *
+ * @author 没秃顶的码农
+ * @date 2023/10/29
+ */
+@Mapper
+public interface SysDictMapper extends BaseMapper<SysDict> {
+
+}

+ 17 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysFileMapper.java

@@ -0,0 +1,17 @@
+
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysFile;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 文件管理
+ *
+ * @author 没秃顶的码农
+ * @date 2019-06-18 17:18:42
+ */
+@Mapper
+public interface SysFileMapper extends BaseMapper<SysFile> {
+
+}

+ 16 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysLogMapper.java

@@ -0,0 +1,16 @@
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysLog;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 日志表
+ *
+ * @author 没秃顶的码农
+ * @date 2023/10/28
+ */
+@Mapper
+public interface SysLogMapper extends BaseMapper<SysLog> {
+
+}

+ 25 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysMenuMapper.java

@@ -0,0 +1,25 @@
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysMenu;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 菜单权限表
+ *
+ * @author 没秃顶的码农
+ * @date 2023/10/28
+ */
+@Mapper
+public interface SysMenuMapper extends BaseMapper<SysMenu> {
+
+	/**
+	 * 通过角色编号查询菜单
+	 * @param roleId 角色ID
+	 * @return
+	 */
+	List<SysMenu> listMenusByRoleId(Long roleId);
+
+}

+ 16 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysOauthClientDetailsMapper.java

@@ -0,0 +1,16 @@
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysOauthClientDetails;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 客户端
+ *
+ * @author 没秃顶的码农
+ * @date 2023/10/28
+ */
+@Mapper
+public interface SysOauthClientDetailsMapper extends BaseMapper<SysOauthClientDetails> {
+
+}

+ 25 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysPostMapper.java

@@ -0,0 +1,25 @@
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysPost;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 岗位信息表
+ *
+ * @author 没秃顶的码农
+ * @date 2023/11/06
+ */
+@Mapper
+public interface SysPostMapper extends BaseMapper<SysPost> {
+
+	/**
+	 * 通过用户ID,查询岗位信息
+	 * @param userId 用户id
+	 * @return 岗位信息
+	 */
+	List<SysPost> listPostsByUserId(Long userId);
+
+}

+ 16 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysPublicParamMapper.java

@@ -0,0 +1,16 @@
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysPublicParam;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 公共参数配置
+ *
+ * @author 没秃顶的码农
+ * @date 2023/10/28
+ */
+@Mapper
+public interface SysPublicParamMapper extends BaseMapper<SysPublicParam> {
+
+}

+ 25 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysRoleMapper.java

@@ -0,0 +1,25 @@
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysRole;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 基本系统角色
+ *
+ * @author 没秃顶的码农
+ * @date 2023/10/28
+ */
+@Mapper
+public interface SysRoleMapper extends BaseMapper<SysRole> {
+
+	/**
+	 * 通过用户ID,查询角色信息
+	 * @param userId
+	 * @return
+	 */
+	List<SysRole> listRolesByUserId(Long userId);
+
+}

+ 16 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysRoleMenuMapper.java

@@ -0,0 +1,16 @@
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysRoleMenu;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 角色菜单表
+ *
+ * @author 没秃顶的码农
+ * @date 2023/10/28
+ */
+@Mapper
+public interface SysRoleMenuMapper extends BaseMapper<SysRoleMenu> {
+
+}

+ 17 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysRuleMakingMapper.java

@@ -0,0 +1,17 @@
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysRulemaking;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 客小爽协议规则表(LkbRuleMaking)表数据库访问层
+ *
+ * @author 系统
+ * @since 2023-12-15 12:16:31
+ */
+@Mapper
+public interface SysRuleMakingMapper extends BaseMapper<SysRulemaking> {
+
+}
+

+ 52 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysUserMapper.java

@@ -0,0 +1,52 @@
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.system.biz.domain.dto.UserDTO;
+import com.kxs.system.biz.domain.vo.UserVO;
+import com.kxs.system.biz.model.SysUser;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 后台用户表
+ *
+ * @author 没秃顶的码农
+ * @date 2023/10/28
+ */
+@Mapper
+public interface SysUserMapper extends BaseMapper<SysUser> {
+
+	/**
+	 * 通过用户名查询用户信息(含有角色信息)
+	 * @param username 用户名
+	 * @return userVo
+	 */
+	UserVO getUserVoByUsername(String username);
+
+	/**
+	 * 分页查询用户信息(含角色)
+	 * @param page 分页
+	 * @param userDTO 查询参数
+	 * @return list
+	 */
+	IPage<UserVO> getUserVosPage(Page page, @Param("query") UserDTO userDTO);
+
+	/**
+	 * 通过ID查询用户信息
+	 * @param id 用户ID
+	 * @return userVo
+	 */
+	UserVO getUserVoById(Long id);
+
+	/**
+	 * 查询用户列表
+	 * @param userDTO 查询条件
+	 * @return
+	 */
+	List<UserVO> selectVoList(@Param("query") UserDTO userDTO);
+
+}

+ 19 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysUserPostMapper.java

@@ -0,0 +1,19 @@
+
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysUserPost;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 用户岗位 Mapper 接口
+ * </p>
+ *
+ * @author fxz
+ * @since 2022/3/19
+ */
+@Mapper
+public interface SysUserPostMapper extends BaseMapper<SysUserPost> {
+
+}

+ 16 - 0
kxs-system/src/main/java/com/kxs/system/biz/mapper/SysUserRoleMapper.java

@@ -0,0 +1,16 @@
+package com.kxs.system.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kxs.system.biz.model.SysUserRole;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户角色表
+ *
+ * @author 没秃顶的码农
+ * @date 2023/10/28
+ */
+@Mapper
+public interface SysUserRoleMapper extends BaseMapper<SysUserRole> {
+
+}

+ 95 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysDept.java

@@ -0,0 +1,95 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 部门管理
+ * </p>
+ *
+ * @author LXQ
+ * @since 2021-01-22
+ */
+@Data
+@Schema(description = "部门")
+@EqualsAndHashCode(callSuper = true)
+public class SysDept extends Model<SysDept> {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	@TableId(value = "dept_id", type = IdType.AUTO)
+	@Schema(description = "部门id")
+	private Long deptId;
+
+	/**
+	 * 部门名称
+	 */
+	@NotBlank(message = "部门名称不能为空")
+	@Schema(description = "部门名称")
+	private String name;
+
+	/**
+	 * 排序
+	 */
+	@NotNull(message = "排序值不能为空")
+	@Schema(description = "排序值")
+	private Integer sortOrder;
+
+	/**
+	 * 创建人
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建人")
+	private String createBy;
+
+	/**
+	 * 修改人
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "修改人")
+	private String updateBy;
+
+	/**
+	 * 创建时间
+	 */
+	@Schema(description = "创建时间")
+	@TableField(fill = FieldFill.INSERT)
+	private LocalDateTime createTime;
+
+	/**
+	 * 修改时间
+	 */
+	@Schema(description = "修改时间")
+	@TableField(fill = FieldFill.UPDATE)
+	private LocalDateTime updateTime;
+
+	/**
+	 * 父级部门id
+	 */
+	@Schema(description = "父级部门id")
+	private Long parentId;
+
+	/**
+	 * 是否删除 1:已删除 0:正常
+	 */
+	@TableLogic
+	@Schema(description = "删除标记,1:已删除,0:正常")
+	@TableField(fill = FieldFill.INSERT)
+	private String delFlag;
+
+}

+ 96 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysDict.java

@@ -0,0 +1,96 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDateTime;
+
+/**
+ * 字典表
+ *
+ * @author 没秃顶的码农
+ * @date 2023/03/19
+ */
+@Data
+@Schema(description = "字典类型")
+@EqualsAndHashCode(callSuper = true)
+public class SysDict extends Model<SysDict> {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 编号
+	 */
+	@TableId(type = IdType.AUTO)
+	@Schema(description = "字典编号")
+	private Long id;
+
+	/**
+	 * 类型
+	 */
+	@Schema(description = "字典类型")
+	private String dictType;
+
+	/**
+	 * 描述
+	 */
+	@Schema(description = "字典描述")
+	private String description;
+
+	/**
+	 * 创建时间
+	 */
+	@Schema(description = "创建时间")
+	@TableField(fill = FieldFill.INSERT)
+	private LocalDateTime createTime;
+
+	/**
+	 * 更新时间
+	 */
+	@Schema(description = "更新时间")
+	@TableField(fill = FieldFill.UPDATE)
+	private LocalDateTime updateTime;
+
+	/**
+	 * 是否是系统内置
+	 */
+	@Schema(description = "是否系统内置")
+	private String systemFlag;
+
+	/**
+	 * 备注信息
+	 */
+	@Schema(description = "备注信息")
+	private String remarks;
+
+	/**
+	 * 创建人
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建人")
+	private String createBy;
+
+	/**
+	 * 修改人
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "修改人")
+	private String updateBy;
+
+	/**
+	 * 删除标记
+	 */
+	@TableLogic
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "删除标记,1:已删除,0:正常")
+	private String delFlag;
+
+}

+ 121 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysDictItem.java

@@ -0,0 +1,121 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+/**
+ * 字典项
+ *
+ * @author 没秃顶的码农
+ * @date 2023/03/19
+ */
+@Data
+@Schema(description = "字典项")
+@EqualsAndHashCode(callSuper = true)
+public class SysDictItem extends Model<SysDictItem> {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 编号
+	 */
+	@TableId(type = IdType.AUTO)
+	@Schema(description = "字典项id")
+	private Long id;
+
+	/**
+	 * 所属字典类id
+	 */
+	@Schema(description = "所属字典类id")
+	private Long dictId;
+
+	/**
+	 * 数据值
+	 */
+	@Schema(description = "数据值")
+	@JsonProperty(value = "value")
+	private String itemValue;
+
+	/**
+	 * 标签名
+	 */
+	@Schema(description = "标签名")
+	private String label;
+
+	/**
+	 * 类型
+	 */
+	@Schema(description = "类型")
+	private String dictType;
+
+	/**
+	 * 描述
+	 */
+	@Schema(description = "描述")
+	private String description;
+
+	/**
+	 * 排序(升序)
+	 */
+	@Schema(description = "排序值,默认升序")
+	private Integer sortOrder;
+
+	/**
+	 * 创建人
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建人")
+	private String createBy;
+
+	/**
+	 * 修改人
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "修改人")
+	private String updateBy;
+
+	/**
+	 * 创建时间
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建时间")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private LocalDateTime createTime;
+
+	/**
+	 * 更新时间
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "更新时间")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private LocalDateTime updateTime;
+
+	/**
+	 * 备注信息
+	 */
+	@Schema(description = "备注信息")
+	private String remarks;
+
+	/**
+	 * 删除标记
+	 */
+	@TableLogic
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "删除标记,1:已删除,0:正常")
+	private String delFlag;
+
+}

+ 107 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysFile.java

@@ -0,0 +1,107 @@
+
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+/**
+ * 文件管理
+ *
+ * @author 没秃顶的码农
+ * @date 2023-06-18 17:18:42
+ */
+@Data
+@Schema(description = "文件")
+@EqualsAndHashCode(callSuper = true)
+public class SysFile extends Model<SysFile> {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 编号
+	 */
+	@TableId(type = IdType.AUTO)
+	@Schema(description = "文件编号")
+	private Long id;
+
+	/**
+	 * 文件名
+	 */
+	@Schema(description = "文件名")
+	private String fileName;
+
+	/**
+	 * 标题
+	 */
+	@Schema(description = "标题")
+	private String title;
+
+	/**
+	 * 原文件名
+	 */
+	@Schema(description = "原始文件名")
+	private String original;
+
+	/**
+	 * 容器名称
+	 */
+	@Schema(description = "存储桶名称")
+	private String bucketName;
+
+	/**
+	 * 文件类型
+	 */
+	@Schema(description = "文件类型")
+	private String type;
+
+	/**
+	 * 文件大小
+	 */
+	@Schema(description = "文件大小")
+	private Long fileSize;
+
+	/**
+	 * 上传人
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建者")
+	private String createBy;
+
+	/**
+	 * 上传时间
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建时间")
+	private LocalDateTime createTime;
+
+	/**
+	 * 更新人
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "更新者")
+	private String updateBy;
+
+	/**
+	 * 更新时间
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "更新时间")
+	private LocalDateTime updateTime;
+
+	/**
+	 * 删除标识:1-删除,0-正常
+	 */
+	@Schema(description = "删除标记,1:已删除,0:正常")
+	private String delFlag;
+
+}

+ 129 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysInterfaceConfig.java

@@ -0,0 +1,129 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 通道参数配置表(KxsInterfaceConfig)表实体类
+ *
+ * @author 系统
+ * @since 2024-07-12 16:45:55
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class SysInterfaceConfig extends Model<SysInterfaceConfig> implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    
+    
+    /**
+     * 主键ID
+     */
+    @Schema(description = "主键ID")
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+
+    /**
+     * 新增时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    @Schema(description = "新增时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+
+    /**
+     * 更新时间
+     */
+    @TableField(fill = FieldFill.UPDATE)
+    @Schema(description = "更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+
+    /**
+     * 删除标记,0未删除,1已删除
+     */
+    @Schema(description = "删除标记,0未删除,1已删除")
+    @TableLogic
+    private String delFlag;
+
+
+    /**
+     * 版本
+     */
+    @Schema(description = "版本")
+    private Integer version;
+
+
+    /**
+     * 添加人
+     */
+    @Schema(description = "添加人")
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
+
+
+    /**
+     * 修改人
+     */
+    @Schema(description = "修改人")
+    @TableField(fill = FieldFill.UPDATE)
+    private String updateBy;
+
+
+    /**
+     * 备注
+     */
+    @Schema(description = "备注")
+    private String remark;
+
+    /**
+     * 名称
+     */
+    @Schema(description = "名称")
+    private String name;
+
+
+    /**
+     * 参数json格式
+     */
+    @Schema(description = "参数json格式")
+    private String params;
+
+
+    /**
+     * 状态: 0-停用, 1-启用
+     */
+    @Schema(description = "状态: 0-停用, 1-启用")
+    private Integer status;
+
+
+    /**
+     * 类型 0-代付平台 1-支付平台
+     */
+    @Schema(description = "类型 0-代付平台 1-支付平台")
+    private Integer paramType;
+
+    /**
+     * 标识
+     */
+    @Schema(description = "标识")
+    private String ifCode;
+
+
+
+
+}
+

+ 149 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysLog.java

@@ -0,0 +1,149 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 日志表
+ * </p>
+ *
+ * @author 没秃顶的码农
+ * @since 2023-11-20
+ */
+@Data
+@Schema(description = "日志")
+public class SysLog extends Model<SysLog> implements Serializable {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 编号
+	 */
+	@TableId(type = IdType.ASSIGN_ID)
+	@ExcelProperty("日志编号")
+	@Schema(description = "日志编号")
+	private Long id;
+
+	/**
+	 * 日志类型
+	 */
+	@NotBlank(message = "日志类型不能为空")
+	@ExcelProperty("日志类型(0-正常 9-错误)")
+	@Schema(description = "日志类型")
+	private String logType;
+
+	/**
+	 * 日志标题
+	 */
+	@NotBlank(message = "日志标题不能为空")
+	@ExcelProperty("日志标题")
+	@Schema(description = "日志标题")
+	private String title;
+
+	/**
+	 * 创建者
+	 */
+	@ExcelProperty("创建人")
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建人")
+	private String createBy;
+
+	/**
+	 * 创建时间
+	 */
+	@ExcelProperty("创建时间")
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建时间")
+	private LocalDateTime createTime;
+
+	/**
+	 * 更新时间
+	 */
+	@ExcelIgnore
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "更新时间")
+	private LocalDateTime updateTime;
+
+	/**
+	 * 操作IP地址
+	 */
+	@ExcelProperty("操作ip地址")
+	@Schema(description = "操作ip地址")
+	private String remoteAddr;
+
+	/**
+	 * 用户代理
+	 */
+	@Schema(description = "用户代理")
+	private String userAgent;
+
+	/**
+	 * 请求URI
+	 */
+	@ExcelProperty("浏览器")
+	@Schema(description = "请求uri")
+	private String requestUri;
+
+	/**
+	 * 操作方式
+	 */
+	@ExcelProperty("操作方式")
+	@Schema(description = "操作方式")
+	private String method;
+
+	/**
+	 * 操作提交的数据
+	 */
+	@ExcelProperty("提交数据")
+	@Schema(description = "提交数据")
+	private String params;
+
+	/**
+	 * 执行时间
+	 */
+	@ExcelProperty("执行时间")
+	@Schema(description = "方法执行时间")
+	private Long time;
+
+	/**
+	 * 异常信息
+	 */
+	@ExcelProperty("异常信息")
+	@Schema(description = "异常信息")
+	private String exception;
+
+	/**
+	 * 服务ID
+	 */
+	@ExcelProperty("应用标识")
+	@Schema(description = "应用标识")
+	private String serviceId;
+
+	/**
+	 * 删除标记
+	 */
+	@ExcelIgnore
+	@Schema(description = "删除标记,1:已删除,0:正常")
+	private String delFlag;
+
+	/**
+	 * 动态表名后缀
+	 */
+	@TableField(exist = false)
+	private String tableSuffix;
+
+}

+ 140 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysMenu.java

@@ -0,0 +1,140 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 菜单权限表
+ * </p>
+ *
+ * @author 没秃顶的码农
+ * @since 2023-11-08
+ */
+@Data
+@Schema(description = "菜单")
+@EqualsAndHashCode(callSuper = true)
+public class SysMenu extends Model<SysMenu> {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 菜单ID
+	 */
+	@TableId(value = "menu_id", type = IdType.AUTO)
+	@Schema(description = "菜单id")
+	private Long menuId;
+
+	/**
+	 * 菜单名称
+	 */
+	@NotBlank(message = "菜单名称不能为空")
+	@Schema(description = "菜单名称")
+	private String name;
+
+	/**
+	 * 菜单名称
+	 */
+	@Schema(description = "菜单名称")
+	private String enName;
+
+	/**
+	 * 菜单权限标识
+	 */
+	@Schema(description = "菜单权限标识")
+	private String permission;
+
+	/**
+	 * 父菜单ID
+	 */
+	@Schema(description = "菜单父id")
+	private Long parentId;
+
+	/**
+	 * 图标
+	 */
+	@Schema(description = "菜单图标")
+	private String icon;
+
+	/**
+	 * 前端路由标识路径,默认和 comment 保持一致 过期
+	 */
+	@Schema(description = "前端路由标识路径")
+	private String path;
+
+	/**
+	 * 链接地址
+	 */
+	@Schema(description = "链接地址")
+	private String linkUrl;
+
+	/**
+	 * 菜单显示隐藏控制
+	 */
+	@Schema(description = "菜单是否显示")
+	private String visible;
+
+	/**
+	 * 排序值
+	 */
+	@Schema(description = "排序值")
+	private Integer sortOrder;
+
+	/**
+	 * 菜单类型 (0菜单 1按钮)
+	 */
+	@NotNull(message = "菜单类型不能为空")
+	@Schema(description = "菜单类型,0:目录 1:菜单 1:按钮")
+	private String menuType;
+
+	/**
+	 * 路由缓冲
+	 */
+	@Schema(description = "路由缓冲")
+	private String keepAlive;
+
+	/**
+	 * 创建人
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建人")
+	private String createBy;
+
+	/**
+	 * 修改人
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "修改人")
+	private String updateBy;
+
+	/**
+	 * 创建时间
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建时间")
+	private LocalDateTime createTime;
+
+	/**
+	 * 更新时间
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "更新时间")
+	private LocalDateTime updateTime;
+
+	/**
+	 * 0--正常 1--删除
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "删除标记,1:已删除,0:正常")
+	private String delFlag;
+
+}

+ 142 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysOauthClientDetails.java

@@ -0,0 +1,142 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 客户端信息
+ * </p>
+ *
+ * @author 没秃顶的码农
+ * @since 2023-05-15
+ */
+@Data
+@Schema(description = "客户端信息")
+@EqualsAndHashCode(callSuper = true)
+public class SysOauthClientDetails extends Model<SysOauthClientDetails> implements Serializable {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	@TableId(value = "id", type = IdType.AUTO)
+	@Schema(description = "id")
+	private Long id;
+
+	/**
+	 * 客户端ID
+	 */
+	@NotBlank(message = "client_id 不能为空")
+	@Schema(description = "客户端id")
+	private String clientId;
+
+	/**
+	 * 客户端密钥
+	 */
+	@NotBlank(message = "client_secret 不能为空")
+	@Schema(description = "客户端密钥")
+	private String clientSecret;
+
+	/**
+	 * 资源ID
+	 */
+	@Schema(description = "资源id列表")
+	private String resourceIds;
+
+	/**
+	 * 作用域
+	 */
+	@NotBlank(message = "scope 不能为空")
+	@Schema(description = "作用域")
+	private String scope;
+
+	/**
+	 * 授权方式[A,B,C]
+	 */
+	@Schema(description = "授权方式")
+	private String[] authorizedGrantTypes;
+
+	/**
+	 * 回调地址
+	 */
+	@Schema(description = "回调地址")
+	private String webServerRedirectUri;
+
+	/**
+	 * 权限
+	 */
+	@Schema(description = "权限列表")
+	private String authorities;
+
+	/**
+	 * 请求令牌有效时间
+	 */
+	@Schema(description = "请求令牌有效时间")
+	private Integer accessTokenValidity;
+
+	/**
+	 * 刷新令牌有效时间
+	 */
+	@Schema(description = "刷新令牌有效时间")
+	private Integer refreshTokenValidity;
+
+	/**
+	 * 扩展信息
+	 */
+	@Schema(description = "扩展信息")
+	private String additionalInformation;
+
+	/**
+	 * 是否自动放行
+	 */
+	@Schema(description = "是否自动放行")
+	private String autoapprove;
+
+	/**
+	 * 删除标记
+	 */
+	@TableLogic
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "删除标记,1:已删除,0:正常")
+	private String delFlag;
+
+	/**
+	 * 创建人
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建人")
+	private String createBy;
+
+	/**
+	 * 修改人
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "修改人")
+	private String updateBy;
+
+	/**
+	 * 创建时间
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建时间")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private LocalDateTime createTime;
+
+	/**
+	 * 更新时间
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "更新时间")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private LocalDateTime updateTime;
+
+}

+ 98 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysPost.java

@@ -0,0 +1,98 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+/**
+ * 岗位信息表
+ *
+ * @author fxz
+ * @date 2022-03-26 12:50:43
+ */
+@Data
+@TableName("sys_post")
+@EqualsAndHashCode(callSuper = true)
+@Schema(description = "岗位信息表")
+public class SysPost extends Model<SysPost> {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 岗位ID
+	 */
+	@TableId(value = "post_id", type = IdType.AUTO)
+	@Schema(description = "岗位ID")
+	private Long postId;
+
+	/**
+	 * 岗位编码
+	 */
+	@NotBlank(message = "岗位编码不能为空")
+	@Schema(description = "岗位编码")
+	private String postCode;
+
+	/**
+	 * 岗位名称
+	 */
+	@NotBlank(message = "岗位名称不能为空")
+	@Schema(description = "岗位名称")
+	private String postName;
+
+	/**
+	 * 岗位排序
+	 */
+	@NotNull(message = "排序值不能为空")
+	@Schema(description = "岗位排序")
+	private Integer postSort;
+
+	/**
+	 * 岗位描述
+	 */
+	@Schema(description = "岗位描述")
+	private String remark;
+
+	/**
+	 * 创建人
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建人")
+	private String createBy;
+
+	/**
+	 * 修改人
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "修改人")
+	private String updateBy;
+
+	/**
+	 * 是否删除 -1:已删除 0:正常
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "是否删除  -1:已删除  0:正常")
+	private String delFlag;
+
+	/**
+	 * 创建时间
+	 */
+	@Schema(description = "创建时间")
+	@TableField(fill = FieldFill.INSERT)
+	private LocalDateTime createTime;
+
+	/**
+	 * 更新时间
+	 */
+	@Schema(description = "更新时间")
+	@TableField(fill = FieldFill.UPDATE)
+	private LocalDateTime updateTime;
+
+}

+ 114 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysPublicParam.java

@@ -0,0 +1,114 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDateTime;
+
+/**
+ * 公共参数配置
+ *
+ * @author Lucky
+ * @date 2023-04-29
+ */
+@Data
+@Schema(description = "公共参数")
+@EqualsAndHashCode(callSuper = true)
+public class SysPublicParam extends Model<SysPublicParam> {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 编号
+	 */
+	@TableId(type = IdType.AUTO)
+	@Schema(description = "公共参数编号")
+	private Long publicId;
+
+	/**
+	 * 公共参数名称
+	 */
+	@Schema(description = "公共参数名称", example = "公共参数名称")
+	private String publicName;
+
+	/**
+	 * 公共参数地址值,英文大写+下划线
+	 */
+	@Schema(description = "键[英文大写+下划线]", example = "PIGX_PUBLIC_KEY")
+	private String publicKey;
+
+	/**
+	 * 值
+	 */
+	@Schema(description = "值", example = "999")
+	private String publicValue;
+
+	/**
+	 * 状态(1有效;2无效;)
+	 */
+	@Schema(description = "标识[1有效;2无效]", example = "1")
+	private String status;
+
+	/**
+	 * 公共参数编码
+	 */
+	@Schema(description = "编码", example = "^(PIG|PIGX)$")
+	private String validateCode;
+
+	/**
+	 * 是否是系统内置
+	 */
+	@Schema(description = "是否是系统内置")
+	private String systemFlag;
+
+	/**
+	 * 配置类型:0-默认;1-检索;2-原文;3-报表;4-安全;5-文档;6-消息;9-其他
+	 */
+	@Schema(description = "类型[1-检索;2-原文...]", example = "1")
+	private String publicType;
+
+	/**
+	 * 创建人
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建人")
+	private String createBy;
+
+	/**
+	 * 修改人
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "修改人")
+	private String updateBy;
+
+	/**
+	 * 删除标记
+	 */
+	@TableLogic
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "删除标记,1:已删除,0:正常")
+	private String delFlag;
+
+	/**
+	 * 创建时间
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建时间")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private LocalDateTime createTime;
+
+	/**
+	 * 更新时间
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "更新时间")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private LocalDateTime updateTime;
+
+}

+ 79 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysRole.java

@@ -0,0 +1,79 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 角色表
+ * </p>
+ *
+ * @author 没秃顶的码农
+ * @since 2023-10-29
+ */
+@Data
+@Schema(description = "角色")
+@EqualsAndHashCode(callSuper = true)
+public class SysRole extends Model<SysRole> {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	@TableId(value = "role_id", type = IdType.AUTO)
+	@Schema(description = "角色编号")
+	private Long roleId;
+
+	@NotBlank(message = "角色名称不能为空")
+	@Schema(description = "角色名称")
+	private String roleName;
+
+	@NotBlank(message = "角色标识不能为空")
+	@Schema(description = "角色标识")
+	private String roleCode;
+
+	@Schema(description = "角色描述")
+	private String roleDesc;
+
+	/**
+	 * 创建人
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建人")
+	private String createBy;
+
+	/**
+	 * 修改人
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "修改人")
+	private String updateBy;
+
+	/**
+	 * 创建时间
+	 */
+	@Schema(description = "创建时间")
+	@TableField(fill = FieldFill.INSERT)
+	private LocalDateTime createTime;
+
+	/**
+	 * 修改时间
+	 */
+	@Schema(description = "修改时间")
+	@TableField(fill = FieldFill.UPDATE)
+	private LocalDateTime updateTime;
+
+	/**
+	 * 删除标识(0-正常,1-删除)
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "删除标记,1:已删除,0:正常")
+	private String delFlag;
+
+}

+ 40 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysRoleMenu.java

@@ -0,0 +1,40 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * <p>
+ * 角色菜单表
+ * </p>
+ *
+ * @author 没秃顶的码农
+ * @since 2023-10-29
+ */
+@Data
+@Schema(description = "角色菜单")
+@EqualsAndHashCode(callSuper = true)
+public class SysRoleMenu extends Model<SysRoleMenu> {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 角色ID
+	 */
+	@Schema(description = "角色id")
+	@TableField
+	private Long roleId;
+
+	/**
+	 * 菜单ID
+	 */
+	@Schema(description = "菜单id")
+	private Long menuId;
+
+}

+ 84 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysRulemaking.java

@@ -0,0 +1,84 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 客小爽协议规则表(SysRulemaking)表实体类
+ *
+ * @author 系统
+ * @since 2023-12-15 12:16:31
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class SysRulemaking extends Model<SysRulemaking> implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    
+    
+    /**
+     * 主键ID
+     */
+    @Schema(description = "主键ID")
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+
+    /**
+     * 新增时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    @Schema(description = "新增时间")
+    private LocalDateTime createTime;
+
+
+    /**
+     * 更新时间
+     */
+    @TableField(fill = FieldFill.UPDATE)
+    @Schema(description = "更新时间")
+    private LocalDateTime updateTime;
+
+
+    /**
+     * 删除标记,0未删除,1已删除
+     */
+    @Schema(description = "删除标记,0未删除,1已删除")
+    private String delFlag;
+
+
+    /**
+     * 版本
+     */
+    @Schema(description = "版本")
+    private Integer version;
+
+
+    /**
+     * 内容
+     */
+    @Schema(description = "内容")
+    private String contents;
+
+
+    /**
+     * 标题
+     */
+    @Schema(description = "标题")
+    private String title;
+
+}
+

+ 164 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysUser.java

@@ -0,0 +1,164 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 用户表
+ * </p>
+ *
+ * @author 没秃顶的码农
+ * @since 2023-10-29
+ */
+@Data
+@Schema(description = "用户")
+public class SysUser implements Serializable {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 主键ID
+	 */
+	@TableId(value = "user_id", type = IdType.AUTO)
+	@Schema(description = "主键id")
+	private Long userId;
+
+	/**
+	 * 用户名
+	 */
+	@Schema(description = "用户名")
+	private String username;
+
+	/**
+	 * 密码
+	 */
+	@Schema(description = "密码")
+	private String password;
+
+	/**
+	 * 随机盐
+	 */
+	@JsonIgnore
+	@Schema(description = "随机盐")
+	private String salt;
+
+	/**
+	 * 创建人
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建人")
+	private String createBy;
+
+	/**
+	 * 修改人
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "修改人")
+	private String updateBy;
+
+	/**
+	 * 创建时间
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "创建时间")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private LocalDateTime createTime;
+
+	/**
+	 * 修改时间
+	 */
+	@TableField(fill = FieldFill.UPDATE)
+	@Schema(description = "修改时间")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private LocalDateTime updateTime;
+
+	/**
+	 * 0-正常,1-删除
+	 */
+	@TableLogic
+	@TableField(fill = FieldFill.INSERT)
+	@Schema(description = "删除标记,1:已删除,0:正常")
+	private String delFlag;
+
+	/**
+	 * 锁定标记
+	 */
+	@Schema(description = "锁定标记")
+	private String lockFlag;
+
+	/**
+	 * 手机号
+	 */
+	@Schema(description = "手机号")
+	private String phone;
+
+	/**
+	 * 头像
+	 */
+	@Schema(description = "头像地址")
+	private String avatar;
+
+	/**
+	 * 部门ID
+	 */
+	@Schema(description = "用户所属部门id")
+	private Long deptId;
+
+	/**
+	 * 微信openid
+	 */
+	@Schema(description = "微信openid")
+	private String wxOpenid;
+
+	/**
+	 * 微信小程序openId
+	 */
+	@Schema(description = "微信小程序openid")
+	private String miniOpenid;
+
+	/**
+	 * QQ openid
+	 */
+	@Schema(description = "QQ openid")
+	private String qqOpenid;
+
+	/**
+	 * 码云唯一标识
+	 */
+	@Schema(description = "码云唯一标识")
+	private String giteeLogin;
+
+	/**
+	 * 开源中国唯一标识
+	 */
+	@Schema(description = "开源中国唯一标识")
+	private String oscId;
+
+	/**
+	 * 昵称
+	 */
+	@Schema(description = "昵称")
+	private String nickname;
+
+	/**
+	 * 姓名
+	 */
+	@Schema(description = "姓名")
+	private String name;
+
+	/**
+	 * 邮箱
+	 */
+	@Schema(description = "邮箱")
+	private String email;
+
+}

+ 34 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysUserPost.java

@@ -0,0 +1,34 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 用户岗位表
+ * </p>
+ *
+ * @author fxz
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SysUserPost extends Model<SysUserPost> {
+
+
+	/**
+	 * 用户ID
+	 */
+	@Schema(description = "用户id")
+	@TableField
+	private Long userId;
+
+	/**
+	 * 岗位ID
+	 */
+	@Schema(description = "岗位id")
+	private Long postId;
+
+}

+ 38 - 0
kxs-system/src/main/java/com/kxs/system/biz/model/SysUserRole.java

@@ -0,0 +1,38 @@
+package com.kxs.system.biz.model;
+
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * <p>
+ * 用户角色表
+ * </p>
+ *
+ * @author 没秃顶的码农
+ * @since 2023-10-29
+ */
+@Data
+@Schema(description = "用户角色")
+@EqualsAndHashCode(callSuper = true)
+public class SysUserRole extends Model<SysUserRole> {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 用户ID
+	 */
+	@Schema(description = "用户id")
+	private Long userId;
+
+	/**
+	 * 角色ID
+	 */
+	@Schema(description = "角色id")
+	private Long roleId;
+
+}

+ 38 - 0
kxs-system/src/main/java/com/kxs/system/biz/service/SysDeptService.java

@@ -0,0 +1,38 @@
+package com.kxs.system.biz.service;
+
+import cn.hutool.core.lang.tree.Tree;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.kxs.system.biz.model.SysDept;
+
+import java.util.List;
+
+/**
+ * 部门管理 服务类
+ *
+ * @author 没秃顶的码农
+ * @date 2023/11/06
+ */
+public interface SysDeptService extends IService<SysDept> {
+
+	/**
+	 * 查询部门树菜单
+	 * @param deptName 部门名称
+	 * @return 树
+	 */
+	List<Tree<Long>> selectTree(String deptName);
+
+	/**
+	 * 删除部门
+	 * @param id 部门 ID
+	 * @return 成功、失败
+	 */
+	Boolean removeDeptById(Long id);
+
+	/**
+	 * 获取部门的所有后代部门列表
+	 * @param deptId 部门ID
+	 * @return 后代部门列表
+	 */
+	List<SysDept> listDescendant(Long deptId);
+
+}

+ 29 - 0
kxs-system/src/main/java/com/kxs/system/biz/service/SysDictItemService.java

@@ -0,0 +1,29 @@
+package com.kxs.system.biz.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.kxs.system.biz.model.SysDictItem;
+import com.kxs.common.core.util.R;
+
+/**
+ * 字典项
+ *
+ * @author 秃顶的码农
+ * @date 2023/03/19
+ */
+public interface SysDictItemService extends IService<SysDictItem> {
+
+	/**
+	 * 删除字典项
+	 * @param id 字典项ID
+	 * @return
+	 */
+	R removeDictItem(Long id);
+
+	/**
+	 * 更新字典项
+	 * @param item 字典项
+	 * @return
+	 */
+	R updateDictItem(SysDictItem item);
+
+}

+ 35 - 0
kxs-system/src/main/java/com/kxs/system/biz/service/SysDictService.java

@@ -0,0 +1,35 @@
+package com.kxs.system.biz.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.kxs.system.biz.model.SysDict;
+import com.kxs.common.core.util.R;
+
+/**
+ * 字典表
+ *
+ * @author 秃顶的码农
+ * @date 2023/03/19
+ */
+public interface SysDictService extends IService<SysDict> {
+
+	/**
+	 * 根据ID 删除字典
+	 * @param ids ID列表
+	 * @return
+	 */
+	R removeDictByIds(Long[] ids);
+
+	/**
+	 * 更新字典
+	 * @param sysDict 字典
+	 * @return
+	 */
+	R updateDict(SysDict sysDict);
+
+	/**
+	 * 同步缓存 (清空缓存)
+	 * @return R
+	 */
+	R syncDictCache();
+
+}

+ 42 - 0
kxs-system/src/main/java/com/kxs/system/biz/service/SysFileService.java

@@ -0,0 +1,42 @@
+
+package com.kxs.system.biz.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.kxs.system.biz.model.SysFile;
+import jakarta.servlet.http.HttpServletResponse;
+
+import java.util.List;
+
+/**
+ * 文件管理
+ *
+ * @author 没秃顶的码农
+ * @date 2019-06-18 17:18:42
+ */
+public interface SysFileService extends IService<SysFile> {
+
+	/**
+	 * 读取文件
+	 *
+	 * @param bucket   桶名称
+	 * @param fileName 文件名称
+	 * @param response 输出流
+	 * @return
+	 */
+	String getFile(String bucket, String fileName, HttpServletResponse response);
+
+	/**
+	 * 删除文件
+	 * @param ids id集合
+	 */
+	Boolean deleteFile(List<Long> ids);
+
+
+	/**
+	 * 通过名称获取文件
+	 * @param fileName
+	 * @return
+	 */
+	SysFile getFileByFileName(String fileName);
+
+}

Некоторые файлы не были показаны из-за большого количества измененных файлов