adsfasdfas

This commit is contained in:
2025-12-18 11:21:31 +08:00
parent 9c47f313b7
commit 26a6152ecc
81 changed files with 6160 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip

View File

@@ -0,0 +1,114 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.rczn</groupId>
<artifactId>Rc-autoplc-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>rczn-admin</artifactId>
<name>rczn-admin</name>
<description>rczn-admin后台管理模块</description>
<packaging>jar</packaging>
<dependencies>
<!-- 依赖公共模块 -->
<dependency>
<groupId>com.rczn</groupId>
<artifactId>rczn-common</artifactId>
</dependency>
<!-- 依赖PLC模块 -->
<dependency>
<groupId>com.rczn</groupId>
<artifactId>rczn-autoplc</artifactId>
</dependency>
<!-- Spring Boot Web 依赖包含Servlet API -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 如果 spring-boot-starter-web 仍然找不到,显式添加 -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- Spring Boot 其他依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- 数据库相关 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 其他依赖 -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.rczn.RcznAdminApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,15 @@
package com.rczn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(value = "com.rczn.*")
public class RcznAdminApplication {
public static void main(String[] args) {
SpringApplication.run(RcznAdminApplication.class, args);
}
}

View File

@@ -0,0 +1,20 @@
package com.rczn.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 所有接口允许跨域
// 替换allowedOrigins为allowedOriginPatterns支持通配符*
.allowedOriginPatterns("*")
.allowedMethods("GET", "POST","PATCH", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true) // 允许携带Cookie
.maxAge(3600); // 预检请求缓存1小时
}
}

View File

@@ -0,0 +1,120 @@
package com.rczn.controller;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.system.domain.Department;
import com.rczn.system.service.DepartmentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/depart")
@Tag(name = "部门管理", description = "部门增删改查+分页查询接口")
public class DepartmentController {
@Autowired
private DepartmentService departmentService;
/**
* 分页查询部门
*/
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询部门", description = "支持部门名称、编码、父ID模糊/精准查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "deptName", description = "部门名称(可选,模糊查询)", required = false, example = "技术部", in = ParameterIn.QUERY),
@Parameter(name = "deptCode", description = "部门编码(可选,模糊查询)", required = false, example = "TECH", in = ParameterIn.QUERY),
@Parameter(name = "parentId", description = "父部门ID可选精准查询", required = false, example = "1", in = ParameterIn.QUERY)
})
public Result<PageBean<Department>> getDeptPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) String deptName,
@RequestParam(required = false) String deptCode,
@RequestParam(required = false) Integer parentId) {
PageBean<Department> pageBean = departmentService.selectPage(pageNum, pageSize, deptName, deptCode, parentId);
return Result.success(pageBean);
}
/**
* 根据ID查询部门
*/
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个部门", description = "根据部门ID查询详情")
public Result getDeptById(@PathVariable Long id) {
Department department = departmentService.selectById(id);
return department != null ? Result.success(department) : Result.error("部门不存在");
}
/**
* 新增部门
*/
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增部门", description = "部门名称和编码为必填项")
public Result addDept(@RequestBody Department department) {
try {
Long deptId = departmentService.insert(department);
return Result.success(deptId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 修改部门
*/
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改部门", description = "需传入部门ID其他字段可选非空则更新")
public Result updateDept(@RequestBody Department department) {
try {
Boolean success = departmentService.update(department);
return success ? Result.success(true) : Result.error("修改失败(部门不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 删除部门(逻辑删除)
*/
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除部门", description = "逻辑删除设置delSign=1不物理删除数据")
public Result deleteDept(@PathVariable Long id) {
try {
Boolean success = departmentService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(部门不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 新增接口:获取完整部门树(包含所有字段)
*/
@GetMapping(value = "/tree", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "获取完整部门树", description = "返回包含所有字段的部门层级结构")
public Result getDeptTree() {
List<Department> deptTree = departmentService.getDeptTree();
return Result.success(deptTree);
}
/**
* 新增接口获取简化部门树仅ID、名称、子部门用于下拉选择
*/
@GetMapping(value = "/simple-tree", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "获取简化部门树", description = "仅返回ID、名称、子部门适用于下拉选择框等场景")
public Result getSimpleDeptTree() {
List<Department> simpleDeptTree = departmentService.getSimpleDeptTree();
return Result.success(simpleDeptTree);
}
}

View File

@@ -0,0 +1,19 @@
package com.rczn.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/admin")
@Tag(name = "用户管理", description = "用户新增、查询、修改接口")
public class HellowAdminController {
@GetMapping("/hellow")
@Operation(summary = "查询用户", description = "根据ID查询用户详情") // 替代@ApiOperation
public String hellow(){
return "hellow admin!!!";
}
}

View File

@@ -0,0 +1,115 @@
package com.rczn.controller;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.system.domain.ManageLog;
import com.rczn.system.service.ManageLogService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
@RestController
@RequestMapping("/manage-log")
@Tag(name = "操作日志管理", description = "操作日志增删改查+分页查询接口")
public class ManageLogController {
@Autowired
private ManageLogService manageLogService;
/**
* 分页查询日志
*/
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询操作日志", description = "支持多条件筛选,空条件自动忽略")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "logName", description = "日志名称(可选,模糊查询)", required = false, example = "登录操作", in = ParameterIn.QUERY),
@Parameter(name = "logType", description = "日志类型(可选,精准查询)", required = false, example = "LOGIN", in = ParameterIn.QUERY),
@Parameter(name = "createId", description = "创建人ID可选", required = false, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "logWritetimeStart", description = "日志开始时间可选格式yyyy-MM-dd HH:mm:ss", required = false, example = "2025-01-01 00:00:00", in = ParameterIn.QUERY),
@Parameter(name = "logWritetimeEnd", description = "日志结束时间可选格式yyyy-MM-dd HH:mm:ss", required = false, example = "2025-12-31 23:59:59", in = ParameterIn.QUERY)
})
public Result<PageBean<ManageLog>> getLogPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) String logName,
@RequestParam(required = false) String logType,
@RequestParam(required = false) Long createId,
@RequestParam(required = false) LocalDateTime logWritetimeStart,
@RequestParam(required = false) LocalDateTime logWritetimeEnd) {
// 构建查询条件(空字段自动忽略)
ManageLog query = new ManageLog();
query.setLogName(logName);
query.setLogType(logType);
query.setCreateId(createId);
// 扩展字段用于时间范围查询实体类无需新增字段MyBatis 支持直接取参)
query.setStartTime(logWritetimeStart); // 实际用 logWritetimeStart这里仅为传递参数
query.setEndTime(logWritetimeEnd);
PageBean<ManageLog> pageBean = manageLogService.selectPage(pageNum, pageSize, query);
return Result.success(pageBean);
}
/**
* 按 ID 查询日志
*/
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个操作日志", description = "按日志ID查询详情")
public Result getLogById(@PathVariable Long id) {
ManageLog log = manageLogService.selectById(id);
return log != null ? Result.success(log) : Result.error("日志不存在或已删除");
}
/**
* 新增操作日志
*/
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增操作日志", description = "日志名称、类型为必填项,其他字段可选")
public Result addLog(@RequestBody ManageLog manageLog) {
try {
Long logId = manageLogService.insert(manageLog);
return Result.success("日志新增成功");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 更新操作日志
*/
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "更新操作日志", description = "需传入日志ID其他字段非空则更新")
public Result updateLog(@RequestBody ManageLog manageLog) {
try {
Boolean success = manageLogService.update(manageLog);
return success ? Result.success( "日志更新成功") : Result.error("更新失败(日志不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 逻辑删除操作日志
*/
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除操作日志", description = "逻辑删除设置delSign=1不物理删除")
public Result deleteLog(
@PathVariable Long id,
@RequestParam(required = false) Long updateId) {
try {
Boolean success = manageLogService.deleteById(id, updateId);
return success ? Result.success("日志删除成功") : Result.error("删除失败(日志不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,95 @@
package com.rczn.controller;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.system.domain.Position;
import com.rczn.system.service.PositionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/position")
@Tag(name = "职位管理", description = "职位增删改查+分页查询接口")
public class PositionController {
@Autowired
private PositionService positionService;
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询职位", description = "支持职位名称、编码模糊查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "posiName", description = "职位名称(可选,模糊查询)", required = false, example = "工程师", in = ParameterIn.QUERY),
@Parameter(name = "posiCode", description = "职位编码(可选,模糊查询)", required = false, example = "ENG", in = ParameterIn.QUERY)
})
public Result<PageBean<Position>> getPosiPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) String posiName,
@RequestParam(required = false) String posiCode) {
PageBean<Position> pageBean = positionService.selectPage(pageNum, pageSize, posiName, posiCode);
return Result.success(pageBean);
}
@GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "条件查询列表", description = "支持职位名称、编码模糊查询")
@Parameters({
@Parameter(name = "posiName", description = "职位名称(可选,模糊查询)", required = false, example = "工程师", in = ParameterIn.QUERY),
@Parameter(name = "posiCode", description = "职位编码(可选,模糊查询)", required = false, example = "ENG", in = ParameterIn.QUERY)
})
public Result getList(
@RequestParam(required = false) String posiName,
@RequestParam(required = false) String posiCode) {
List<Position> list = positionService.selectList( posiName, posiCode);
return Result.success(list);
}
@GetMapping(value = "/getById/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "查询单个职位", description = "根据职位ID查询详情")
public Result getPosiById(@PathVariable Long id) {
Position position = positionService.selectById(id);
return position != null ? Result.success(position) : Result.error("职位不存在");
}
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增职位", description = "职位名称和编码为必填项")
public Result addPosi(@RequestBody Position position) {
try {
Long posiId = positionService.insert(position);
return Result.success(posiId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "修改职位", description = "需传入职位ID其他字段可选非空则更新")
public Result updatePosi(@RequestBody Position position) {
try {
Boolean success = positionService.update(position);
return success ? Result.success(true) : Result.error("修改失败(职位不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "删除职位", description = "逻辑删除设置delSign=1")
public Result deletePosi(@PathVariable Long id) {
try {
Boolean success = positionService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(职位不存在或已删除)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,129 @@
package com.rczn.controller;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.system.domain.Role;
import com.rczn.system.service.RoleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
/**
* 角色管理 CRUD APIMyBatis+PageHelper 实现)
*/
@RestController
@RequestMapping("/role") // RESTful 规范:复数形式
@Tag(name = "角色管理", description = "角色增删改查接口(支持分页+多条件查询+编码唯一性校验)")
public class RoleController {
private final RoleService roleService;
// 构造器注入
public RoleController(RoleService roleService) {
this.roleService = roleService;
}
/**
* 1. 分页查询角色(多条件模糊查询)
*/
@GetMapping("/listPage")
@Operation(summary = "分页查询角色", description = "支持角色名、角色编码模糊查询页码从1开始")
@Parameters({
@Parameter(name = "pageNum", description = "页码必填从1开始", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "roleName", description = "角色名(模糊查询,可选)", required = false, example = "管理员", in = ParameterIn.QUERY),
@Parameter(name = "roleCode", description = "角色编码(模糊查询,可选)", required = false, example = "ADMIN", in = ParameterIn.QUERY)
})
public Result<PageBean<Role>> getRolePage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) String roleName,
@RequestParam(required = false) String roleCode) {
PageBean<Role> pageBean = roleService.selectRolePage(pageNum, pageSize, roleName, roleCode);
return Result.success(pageBean);
}
/**
* 2. 根据ID查询单个角色
*/
@GetMapping("/getById/{id}")
@Operation(summary = "查询单个角色", description = "根据角色ID查询详情")
public Result getRoleById(
@Parameter(name = "id", description = "角色ID必填", required = true, example = "1", in = ParameterIn.PATH)
@PathVariable Long id) {
Role role = roleService.selectById(id);
if (role == null) {
return Result.error("角色ID" + id + " 不存在");
}
return Result.success(role);
}
/**
* 3. 新增角色(校验编码唯一性)
*/
@PostMapping("/add")
@Operation(summary = "新增角色", description = "提交角色信息角色编码不可重复ID无需传入")
public Result addRole(
@Parameter(name = "role", description = "角色信息ID无需传入roleName和roleCode必填", required = true)
@RequestBody Role role) {
try {
// 校验必填字段也可通过JSR-380注解+@Valid实现
if (role.getRoleName() == null || role.getRoleName().trim().isEmpty()) {
return Result.error("角色名不能为空");
}
if (role.getRoleCode() == null || role.getRoleCode().trim().isEmpty()) {
return Result.error("角色编码不能为空");
}
Long roleId = roleService.insert(role);
return Result.success(roleId);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 4. 修改角色(部分字段更新+编码唯一性校验)
*/
@PutMapping("/update")
@Operation(summary = "修改角色", description = "传入角色ID和需要修改的字段角色编码不可重复")
public Result updateRole(
@Parameter(name = "role", description = "角色信息ID必填roleName/roleCode可选但至少传一个", required = true)
@RequestBody Role role) {
try {
// 校验必填字段
if (role.getId() == null) {
return Result.error("角色ID不能为空");
}
if ((role.getRoleName() == null || role.getRoleName().trim().isEmpty())
&& (role.getRoleCode() == null || role.getRoleCode().trim().isEmpty())) {
return Result.error("至少需要修改角色名或角色编码");
}
Boolean success = roleService.update(role);
return success ? Result.success("修改角色成功") : Result.error("修改失败(角色不存在)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 5. 根据ID删除角色
*/
@DeleteMapping("/del/{id}")
@Operation(summary = "删除角色", description = "根据角色ID删除角色")
public Result deleteRole(
@Parameter(name = "id", description = "角色ID必填", required = true, example = "1", in = ParameterIn.PATH)
@PathVariable Long id) {
Boolean success = roleService.deleteById(id);
return success ? Result.success("删除角色成功") : Result.error("删除失败(角色不存在)");
}
}

View File

@@ -0,0 +1,105 @@
package com.rczn.controller;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.system.domain.User;
import com.rczn.system.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* 用户管理 CRUD APIMyBatis+PageHelper 实现)
*/
@RestController
@RequestMapping("/user") // RESTful 规范:复数形式+api前缀
@Tag(name = "用户管理", description = "用户增删改查接口(支持分页+模糊查询)")
public class UserController {
// 注入 Service 层(构造器注入,推荐)
@Autowired
UserService userService;
/**
* 1. 分页查询用户(支持用户名模糊查询)
*/
@GetMapping("/listPage")
@Operation(summary = "分页查询用户", description = "支持分页、用户名模糊查询页码从1开始")
@Parameters({
@Parameter(name = "pageNum", description = "页码从1开始", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "userName", description = "用户名(模糊查询,可选)", required = false, example = "张三", in = ParameterIn.QUERY)
})
public Result<PageBean<User>> getUserPage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) String userName) {
// 调用 Service 分页查询
PageBean<User> pageBean = userService.selectUserPage(pageNum, pageSize, userName);
return Result.success(pageBean);
}
/**
* 2. 根据ID查询单个用户
*/
@GetMapping("/getById/{id}")
@Operation(summary = "查询单个用户", description = "根据用户ID查询详情")
public Result getUserById(
@Parameter(name = "id", description = "用户ID", required = true, example = "1", in = ParameterIn.PATH)
@PathVariable Long id) {
User user = userService.selectById(id);
if (user == null) {
return Result.error("用户ID" + id + " 不存在");
}
return Result.success(user);
}
/**
* 3. 新增用户
*/
@PostMapping("/add")
@Operation(summary = "新增用户", description = "提交用户完整信息创建新用户ID无需传入")
public Result addUser(
@Parameter(name = "user", description = "用户信息ID无需传入", required = true)
@RequestBody User user) {
Long userId = userService.insert(user);
return Result.success("新增用户成功");
}
/**
* 4. 修改用户(支持部分字段更新)
*/
@PutMapping("/update")
@Operation(summary = "修改用户", description = "传入用户ID和需要修改的字段非空字段才会更新")
public Result updateUser(
@Parameter(name = "user", description = "用户信息必须包含ID", required = true)
@RequestBody User user) {
try {
Boolean success = userService.update(user);
return success ? Result.success("修改用户成功") : Result.error("修改失败(用户不存在或无字段更新)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
/**
* 5. 根据ID删除用户
*/
@DeleteMapping("/del/{id}")
@Operation(summary = "删除用户", description = "根据用户ID删除用户")
public Result deleteUser(
@Parameter(name = "id", description = "用户ID", required = true, example = "1", in = ParameterIn.PATH)
@PathVariable Long id) {
Boolean success = userService.deleteById(id);
return success ? Result.success("删除用户成功") : Result.error("删除失败(用户不存在)");
}
}

View File

@@ -0,0 +1,100 @@
package com.rczn.controller;
import com.rczn.domain.PageBean;
import com.rczn.domain.Result;
import com.rczn.system.domain.UserRole;
import com.rczn.system.service.UserRoleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/user-role")
@Tag(name = "用户角色关联管理", description = "用户与角色的关联增删改查接口")
public class UserRoleController {
@Autowired
private UserRoleService userRoleService;
@GetMapping(value = "/listPage", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "分页查询关联", description = "支持用户ID、角色ID精准查询")
@Parameters({
@Parameter(name = "pageNum", description = "页码(必填)", required = true, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "pageSize", description = "每页条数(必填)", required = true, example = "10", in = ParameterIn.QUERY),
@Parameter(name = "userId", description = "用户ID可选", required = false, example = "1", in = ParameterIn.QUERY),
@Parameter(name = "roleId", description = "角色ID可选", required = false, example = "2", in = ParameterIn.QUERY)
})
public Result<PageBean<UserRole>> getUserRolePage(
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(required = false) Integer userId,
@RequestParam(required = false) Integer roleId) {
PageBean<UserRole> pageBean = userRoleService.selectPage(pageNum, pageSize, userId, roleId);
return Result.success(pageBean);
}
@GetMapping(value = "/user/{userId}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "根据用户ID查询关联角色", description = "查询指定用户的所有关联角色")
public Result<List<UserRole>> getByUserId(@PathVariable Integer userId) {
List<UserRole> userRoles = userRoleService.selectByUserId(userId);
return Result.success(userRoles);
}
@GetMapping(value = "/role/{roleId}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "根据角色ID查询关联用户", description = "查询指定角色的所有关联用户")
public Result<List<UserRole>> getByRoleId(@PathVariable Integer roleId) {
List<UserRole> userRoles = userRoleService.selectByRoleId(roleId);
return Result.success(userRoles);
}
@PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "新增用户角色关联", description = "用户ID和角色ID为必填项")
public Result addUserRole(@RequestBody UserRole userRole) {
try {
Long id = userRoleService.insert(userRole);
return Result.success(id);
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/del/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "根据关联ID删除", description = "删除单个用户-角色关联")
public Result deleteById(@PathVariable Long id) {
try {
Boolean success = userRoleService.deleteById(id);
return success ? Result.success(true) : Result.error("删除失败(关联不存在)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/user/{userId}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "根据用户ID删除所有关联", description = "删除指定用户的所有角色关联")
public Result deleteByUserId(@PathVariable Integer userId) {
try {
Boolean success = userRoleService.deleteByUserId(userId);
return success ? Result.success(true) : Result.error("删除失败(无关联数据)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
@DeleteMapping(value = "/role/{roleId}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "根据角色ID删除所有关联", description = "删除指定角色的所有用户关联")
public Result deleteByRoleId(@PathVariable Integer roleId) {
try {
Boolean success = userRoleService.deleteByRoleId(roleId);
return success ? Result.success(true) : Result.error("删除失败(无关联数据)");
} catch (IllegalArgumentException e) {
return Result.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,88 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
import java.util.List;
public class Department extends BaseBean {
private String deptName;
private String deptCode;
private Integer parentId;
private Integer leaderId;
private User leader;
// 新增:子部门列表(核心字段,用于存储树形结构)
private List<Department> children;
public Department() {
}
public Department(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String getDeptCode() {
return deptCode;
}
public void setDeptCode(String deptCode) {
this.deptCode = deptCode;
}
public Integer getParentId() {
return parentId;
}
public void setParentId(Integer parentId) {
this.parentId = parentId;
}
public Integer getLeaderId() {
return leaderId;
}
public void setLeaderId(Integer leaderId) {
this.leaderId = leaderId;
}
public User getLeader() {
return leader;
}
public void setLeader(User leader) {
this.leader = leader;
}
public List<Department> getChildren() {
return children;
}
public void setChildren(List<Department> children) {
this.children = children;
}
@Override
public String toString() {
return "Department{" +
"deptName='" + deptName + '\'' +
", deptCode='" + deptCode + '\'' +
", parentId=" + parentId +
", leaderId=" + leaderId +
", leader=" + leader +
", children=" + children +
'}';
}
}

View File

@@ -0,0 +1,65 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
public class ManageLog extends BaseBean {
private String logName;
private String logType;
private LocalDateTime logWritetime;
private String logContent;
public ManageLog() {
}
public ManageLog(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
}
@Override
public String toString() {
return "ManageLog{" +
"logName='" + logName + '\'' +
", logType='" + logType + '\'' +
", logWritetime=" + logWritetime +
", logContent='" + logContent + '\'' +
'}';
}
public String getLogName() {
return logName;
}
public void setLogName(String logName) {
this.logName = logName;
}
public String getLogType() {
return logType;
}
public void setLogType(String logType) {
this.logType = logType;
}
public LocalDateTime getLogWritetime() {
return logWritetime;
}
public void setLogWritetime(LocalDateTime logWritetime) {
this.logWritetime = logWritetime;
}
public String getLogContent() {
return logContent;
}
public void setLogContent(String logContent) {
this.logContent = logContent;
}
}

View File

@@ -0,0 +1,16 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Permission extends BaseBean {
private String permissionName;
private String permissionCode;}

View File

@@ -0,0 +1,42 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
public class Position extends BaseBean {
private String posiName;
private String posiCode;
public Position() {
}
public Position(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
}
@Override
public String toString() {
return "Position{" +
"posiName='" + posiName + '\'' +
", posiCode='" + posiCode + '\'' +
'}';
}
public String getPosiName() {
return posiName;
}
public void setPosiName(String posiName) {
this.posiName = posiName;
}
public String getPosiCode() {
return posiCode;
}
public void setPosiCode(String posiCode) {
this.posiCode = posiCode;
}
}

View File

@@ -0,0 +1,27 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
public class Role extends BaseBean {
private String roleName;
private String roleCode;
// 全参构造器同步修改 delSign 类型Boolean → boolean
public Role(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark, String roleName, String roleCode) {
super(id, createId, createTime, updateId, updateTime, delSign, remark); // 父类参数类型同步
this.roleName = roleName;
this.roleCode = roleCode;
}
// 其他构造器、getter/setter 保持不变
public Role() { }
public Role(String roleName, String roleCode) {
this.roleName = roleName;
this.roleCode = roleCode;
}
public String getRoleName() { return roleName; }
public void setRoleName(String roleName) { this.roleName = roleName; }
public String getRoleCode() { return roleCode; }
public void setRoleCode(String roleCode) { this.roleCode = roleCode; }
}

View File

@@ -0,0 +1,56 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
public class RolePermission extends BaseBean {
private Integer roleId;
private Integer permissionId;
private Role role;
private Permission permission;
public RolePermission() {
}
public RolePermission(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
}
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public Integer getPermissionId() {
return permissionId;
}
public void setPermissionId(Integer permissionId) {
this.permissionId = permissionId;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public Permission getPermission() {
return permission;
}
public void setPermission(Permission permission) {
this.permission = permission;
}
}

View File

@@ -0,0 +1,152 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
public class User extends BaseBean {
private String userName;
private String password;
private String salt;
private String nicke;
private Boolean sex; // 0-女, 1-男
private String emailAddr;
private String address;
private String telephone;
private Integer depId;
private Integer posId;
private Department department;
private Position position;
public User() {
}
public User(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", password='" + password + '\'' +
", salt='" + salt + '\'' +
", nicke='" + nicke + '\'' +
", sex=" + sex +
", emailAddr='" + emailAddr + '\'' +
", address='" + address + '\'' +
", telephone='" + telephone + '\'' +
", depId=" + depId +
", posId=" + posId +
", department=" + department +
", position=" + position +
'}';
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public String getNicke() {
return nicke;
}
public void setNicke(String nicke) {
this.nicke = nicke;
}
public Boolean getSex() {
return sex;
}
public void setSex(Boolean sex) {
this.sex = sex;
}
public String getEmailAddr() {
return emailAddr;
}
public void setEmailAddr(String emailAddr) {
this.emailAddr = emailAddr;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public Integer getDepId() {
return depId;
}
public void setDepId(Integer depId) {
this.depId = depId;
}
public Integer getPosId() {
return posId;
}
public void setPosId(Integer posId) {
this.posId = posId;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public Position getPosition() {
return position;
}
public void setPosition(Position position) {
this.position = position;
}
}

View File

@@ -0,0 +1,89 @@
package com.rczn.system.domain;
import com.rczn.domain.BaseBean;
import java.time.LocalDateTime;
public class UserRole extends BaseBean {
private Long id;
private Integer userId;
private Integer roleId;
private User user;
private Role role;
@Override
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public UserRole() {
}
public UserRole(Long id, Integer userId, Integer roleId, User user, Role role) {
this.id = id;
this.userId = userId;
this.roleId = roleId;
this.user = user;
this.role = role;
}
public UserRole(Long id, Long createId, LocalDateTime createTime, Long updateId, LocalDateTime updateTime, boolean delSign, String remark, Long id1, Integer userId, Integer roleId, User user, Role role) {
super(id, createId, createTime, updateId, updateTime, delSign, remark);
this.id = id1;
this.userId = userId;
this.roleId = roleId;
this.user = user;
this.role = role;
}
@Override
public String toString() {
return "UserRole{" +
"id=" + id +
", userId=" + userId +
", roleId=" + roleId +
", user=" + user +
", role=" + role +
'}';
}
}

View File

@@ -0,0 +1,27 @@
package com.rczn.system.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* 用户实体类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Schema(description = "用户实体类") // 替代@ApiModel
public class UserTest {
@Schema(description = "用户ID", example = "1001") // 替代@ApiModelProperty
private Long id;
@Schema(description = "用户名", required = true, example = "张三")
private String name;
@Schema(description = "年龄", example = "25")
private Integer age;
}

View File

@@ -0,0 +1,44 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.Department;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface DepartmentMapper {
// 新增部门
int insert(Department department);
// 根据ID删除部门逻辑删除更新delSign=1
int deleteById(Long id);
// 根据ID更新部门
int updateById(Department department);
// 根据ID查询部门
Department selectById(Long id);
// 分页查询部门(支持模糊查询)
List<Department> selectPage(
@Param("deptName") String deptName,
@Param("deptCode") String deptCode,
@Param("parentId") Integer parentId
);
// 查询分页总数(配合分页查询)
int selectTotal(
@Param("deptName") String deptName,
@Param("deptCode") String deptCode,
@Param("parentId") Integer parentId
);
// 新增:查询所有未删除的部门(用于递归组装树)
List<Department> selectAllDept();
// 新增按父部门ID查询子部门用于递归查询
List<Department> selectChildrenByParentId(@Param("parentId") Integer parentId);
// 新增查询顶级部门parent_id IS NULL
List<Department> selectTopDept();
}

View File

@@ -0,0 +1,26 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.ManageLog;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper // 标记为 MyBatis Mapper 接口,确保被 Spring 扫描
public interface ManageLogMapper {
// 新增日志(支持空字段,空字段用数据库默认值)
int insert(ManageLog manageLog);
// 逻辑删除日志(按 ID设置 delSign=1
int deleteById(Long id);
// 更新日志(仅更新非空字段,空字段不更新)
int update(ManageLog manageLog);
// 按 ID 查询日志(仅查未删除数据)
ManageLog selectById(Long id);
// 分页查询日志(支持按字段筛选,空字段忽略条件)
List<ManageLog> selectPage(ManageLog manageLog);
// 查询分页总数(与分页查询条件一致)
Long selectTotal(ManageLog manageLog);
}

View File

@@ -0,0 +1,26 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.Position;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface PositionMapper {
int insert(Position position);
int deleteById(Long id);
int updateById(Position position);
Position selectById(Long id);
List<Position> selectPage(
@Param("posiName") String posiName,
@Param("posiCode") String posiCode
);
int selectTotal(
@Param("posiName") String posiName,
@Param("posiCode") String posiCode
);
List<Position> selectList(
@Param("posiName") String posiName,
@Param("posiCode") String posiCode
);
}

View File

@@ -0,0 +1,55 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.Role;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* Role MyBatis Mapper 接口
*/
@Mapper
public interface RoleMapper {
/**
* 分页查询角色(支持角色名/角色编码模糊查询)
*/
List<Role> selectRolePage(
@Param("roleName") String roleName,
@Param("roleCode") String roleCode);
/**
* 根据ID查询单个角色
*/
Role selectById(@Param("id") Long id);
/**
* 新增角色
*/
int insert(Role role);
/**
* 修改角色(部分字段更新)
*/
int update(Role role);
/**
* 根据ID删除角色
*/
int deleteById(@Param("id") Long id);
/**
* 查询总条数(支持模糊查询条件)
*/
Long selectTotal(
@Param("roleName") String roleName,
@Param("roleCode") String roleCode);
/**
* 校验角色编码唯一性(新增/修改时使用)
*/
Integer checkRoleCodeUnique(
@Param("roleCode") String roleCode,
@Param("id") Long id);
}

View File

@@ -0,0 +1,34 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserMapper {
// 分页查询(参数支持空值,为空时忽略该条件)
List<User> selectUserPage(User user);
// 根据ID查询支持传delSign筛选状态
User selectById(@Param("id") Long id, @Param("delSign") Boolean delSign);
// 新增用户空参数会插入默认值或null
int insert(User user);
// 修改用户(仅更新非空字段)
int update(User user);
// 逻辑删除用户
int deleteById(@Param("id") Long id, @Param("updateId") Long updateId);
// 查询总条数(与分页查询参数一致)
Long selectTotal(
@Param("userName") String userName,
@Param("depId") Integer depId,
@Param("posId") Integer posId,
@Param("createId") Long createId,
@Param("sex") Integer sex,
@Param("delSign") Boolean delSign
);
}

View File

@@ -0,0 +1,44 @@
package com.rczn.system.mapper;
import com.rczn.system.domain.UserRole;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface UserRoleMapper {
// 新增用户-角色关联
int insert(UserRole userRole);
// 根据ID删除关联
int deleteById(Long id);
// 根据用户ID删除所有关联
int deleteByUserId(Integer userId);
// 根据角色ID删除所有关联
int deleteByRoleId(Integer roleId);
// 根据ID查询关联
UserRole selectById(Long id);
// 根据用户ID查询关联的角色列表
List<UserRole> selectByUserId(Integer userId);
// 根据角色ID查询关联的用户列表
List<UserRole> selectByRoleId(Integer roleId);
// 分页查询所有关联
List<UserRole> selectPage(
@Param("userId") Integer userId,
@Param("roleId") Integer roleId,
@Param("start") Integer start,
@Param("pageSize") Integer pageSize
);
// 查询分页总数
int selectTotal(
@Param("userId") Integer userId,
@Param("roleId") Integer roleId
);
}

View File

@@ -0,0 +1,35 @@
package com.rczn.system.service;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Department;
import java.util.List;
public interface DepartmentService {
// 新增部门
Long insert(Department department);
// 根据ID删除部门
Boolean deleteById(Long id);
// 根据ID更新部门
Boolean update(Department department);
// 根据ID查询部门
Department selectById(Long id);
// 分页查询部门
PageBean<Department> selectPage(
Integer pageNum,
Integer pageSize,
String deptName,
String deptCode,
Integer parentId
);
// 新增:获取完整部门树(递归组装)
List<Department> getDeptTree();
// 新增获取简化版部门树仅包含ID、名称、子部门用于下拉选择
List<Department> getSimpleDeptTree();
}

View File

@@ -0,0 +1,21 @@
package com.rczn.system.service;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.ManageLog;
public interface ManageLogService {
// 新增日志
Long insert(ManageLog manageLog);
// 逻辑删除日志
Boolean deleteById(Long id, Long updateId);
// 更新日志(仅更新非空字段)
Boolean update(ManageLog manageLog);
// 按 ID 查询日志
ManageLog selectById(Long id);
// 分页查询日志(支持多条件筛选)
PageBean<ManageLog> selectPage(Integer pageNum, Integer pageSize, ManageLog manageLog);
}

View File

@@ -0,0 +1,15 @@
package com.rczn.system.service;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Position;
import java.util.List;
public interface PositionService {
Long insert(Position position);
Boolean deleteById(Long id);
Boolean update(Position position);
Position selectById(Long id);
PageBean<Position> selectPage(Integer pageNum, Integer pageSize, String posiName, String posiCode);
List<Position> selectList(String posiName, String posiCode);
}

View File

@@ -0,0 +1,50 @@
package com.rczn.system.service;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Role;
/**
* Role 业务逻辑层接口
*/
public interface RoleService {
/**
* 分页查询角色(支持多条件模糊查询)
* @param pageNum 页码从1开始
* @param pageSize 每页条数
* @param roleName 角色名(可选)
* @param roleCode 角色编码(可选)
* @return 分页结果
*/
PageBean<Role> selectRolePage(Integer pageNum, Integer pageSize, String roleName, String roleCode);
/**
* 根据ID查询单个角色
* @param id 角色ID
* @return 角色实体
*/
Role selectById(Long id);
/**
* 新增角色(校验角色编码唯一性)
* @param role 角色实体
* @return 新增成功的角色ID
* @throws IllegalArgumentException 角色编码已存在时抛出
*/
Long insert(Role role);
/**
* 修改角色(校验角色编码唯一性+部分字段更新)
* @param role 角色实体需包含ID
* @return 是否修改成功
* @throws IllegalArgumentException 角色编码已存在或未传ID时抛出
*/
Boolean update(Role role);
/**
* 根据ID删除角色
* @param id 角色ID
* @return 是否删除成功
*/
Boolean deleteById(Long id);
}

View File

@@ -0,0 +1,16 @@
package com.rczn.system.service;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.UserRole;
import java.util.List;
public interface UserRoleService {
Long insert(UserRole userRole);
Boolean deleteById(Long id);
Boolean deleteByUserId(Integer userId);
Boolean deleteByRoleId(Integer roleId);
UserRole selectById(Long id);
List<UserRole> selectByUserId(Integer userId);
List<UserRole> selectByRoleId(Integer roleId);
PageBean<UserRole> selectPage(Integer pageNum, Integer pageSize, Integer userId, Integer roleId);
}

View File

@@ -0,0 +1,47 @@
package com.rczn.system.service;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.User;
/**
* User 业务逻辑层接口
*/
public interface UserService {
/**
* 1. 分页查询用户(支持用户名模糊查询)
* @param pageNum 页码从1开始
* @param pageSize 每页条数
* @param userName 用户名(模糊查询,可选)
* @return 分页结果PageBean
*/
PageBean<User> selectUserPage(Integer pageNum, Integer pageSize, String userName);
/**
* 2. 根据ID查询单个用户
* @param id 用户ID
* @return 单个用户实体
*/
User selectById(Long id);
/**
* 3. 新增用户
* @param user 用户实体
* @return 新增成功的用户ID
*/
Long insert(User user);
/**
* 4. 修改用户(部分字段更新)
* @param user 用户实体需包含ID仅更新非空字段
* @return 是否修改成功true/false
*/
Boolean update(User user);
/**
* 5. 根据ID删除用户
* @param id 用户ID
* @return 是否删除成功true/false
*/
Boolean deleteById(Long id);
}

View File

@@ -0,0 +1,186 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Department;
import com.rczn.system.mapper.DepartmentMapper;
import com.rczn.system.service.DepartmentService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class DepartmentServiceImpl implements DepartmentService {
@Autowired
private DepartmentMapper departmentMapper;
@Override
public Long insert(Department department) {
// 校验必填字段
Assert.notNull(department.getDeptName(), "部门名称不能为空");
Assert.notNull(department.getDeptCode(), "部门编码不能为空");
// 补充创建时间字段
// department.setCreateId(getCurrentUserId());
if (department.getCreateTime() == null) {
department.setCreateTime(LocalDateTime.now());
}
int rows = departmentMapper.insert(department);
return rows > 0 ? department.getId() : null;
}
@Override
public Boolean deleteById(Long id) {
Assert.notNull(id, "部门ID不能为空");
int rows = departmentMapper.deleteById(id);
return rows > 0;
}
@Override
public Boolean update(Department department) {
Assert.notNull(department.getId(), "部门ID不能为空");
// department.setUpdateId(null);
if (department.getUpdateTime() == null) {
department.setUpdateTime(LocalDateTime.now());
}
int rows = departmentMapper.updateById(department);
return rows > 0;
}
@Override
public Department selectById(Long id) {
Assert.notNull(id, "部门ID不能为空");
return departmentMapper.selectById(id);
}
@Override
public PageBean<Department> selectPage(Integer pageNum, Integer pageSize, String deptName, String deptCode, Integer parentId) {
// 校验分页参数
Assert.notNull(pageNum, "页码不能为空");
Assert.notNull(pageSize, "每页条数不能为空");
Assert.isTrue(pageNum > 0, "页码必须大于0");
Assert.isTrue(pageSize > 0 && pageSize <= 100000, "每页条数必须在1-10000之间");
// 1. 设置分页参数PageHelper 自动拦截后续的 SQL 进行分页)
PageHelper.startPage(pageNum, pageSize);
// 查询分页数据和总数
List<Department> items = departmentMapper.selectPage(deptName, deptCode, parentId);
Page<Department> page = (Page<Department>) items;
PageBean<Department> pageBean = new PageBean<>();
pageBean.setTotal(page.getTotal());
pageBean.setItems(page.getResult());
// 封装PageBean返回
return pageBean;
}
/**
* 核心:获取完整部门树(包含所有字段和层级关系)
*/
@Override
public List<Department> getDeptTree() {
// 1. 查询所有未删除的部门(一次性查询,减少数据库交互)
List<Department> allDept = departmentMapper.selectAllDept();
// 2. 递归组装树形结构(从顶级部门开始)
return buildDeptTree(allDept, null);
}
/**
* 核心获取简化版部门树仅ID、名称、子部门用于下拉选择框等场景
*/
@Override
public List<Department> getSimpleDeptTree() {
List<Department> allDept = departmentMapper.selectAllDept();
List<Department> deptTree = buildDeptTree(allDept, null);
// 简化部门树字段(仅保留必要字段,减少返回数据量)
return simplifyDeptTree(deptTree);
}
/**
* 递归组装部门树
* @param allDept 所有部门列表
* @param parentId 父部门IDnull 表示查询顶级部门)
* @return 组装后的子部门列表
*/
private List<Department> buildDeptTree(List<Department> allDept, Integer parentId) {
// 筛选当前父部门的所有子部门
List<Department> childrenDept = allDept.stream()
.filter(dept -> {
// 父部门ID为null时筛选parent_id IS NULL的顶级部门否则筛选parent_id等于当前parentId的部门
if (parentId == null) {
return dept.getParentId() == null;
} else {
return parentId.equals(dept.getParentId());
}
})
.collect(Collectors.toList());
// 递归为每个子部门设置下属子部门
for (Department dept : childrenDept) {
List<Department> children = buildDeptTree(allDept, dept.getId().intValue()); // dept.id是Long转Integer匹配parentId类型
dept.setLeader(null); // 简化场景可清空负责人,如需保留可删除此句
dept.setChildren(children); // 给当前部门设置子部门
}
return childrenDept;
}
/**
* 简化部门树字段仅保留ID、名称、子部门
* @param deptTree 完整部门树
* @return 简化后的部门树
*/
private List<Department> simplifyDeptTree(List<Department> deptTree) {
List<Department> simpleTree = new ArrayList<>();
for (Department dept : deptTree) {
Department simpleDept = new Department();
simpleDept.setId(dept.getId());
simpleDept.setDeptName(dept.getDeptName());
simpleDept.setDeptCode(dept.getDeptCode());
// 递归简化子部门
if (dept.getChildren() != null && !dept.getChildren().isEmpty()) {
simpleDept.setChildren(simplifyDeptTree(dept.getChildren()));
}
simpleTree.add(simpleDept);
}
return simpleTree;
}
/**
* 辅助方法获取当前登录用户ID需替换为你的实际获取逻辑如从Token中解析
*/
private Long getCurrentUserId() {
// 示例临时返回1实际项目中需替换为真实的用户ID获取逻辑如SecurityContext、ThreadLocal等
return 1L;
}
// 为Department实体类添加children字段的setter因为原实体类没有需动态设置子部门
// 注意这里是通过反射或直接在实体类中添加children字段推荐在实体类中显式添加
// 下面是临时解决方案实际需修改Department实体类见步骤六
private void setChildren(Department dept, List<Department> children) {
try {
// 通过反射给Department设置children字段若实体类已添加可直接调用setChildren
java.lang.reflect.Field field = Department.class.getDeclaredField("children");
field.setAccessible(true);
field.set(dept, children);
} catch (Exception e) {
throw new RuntimeException("设置部门子节点失败", e);
}
}
}

View File

@@ -0,0 +1,86 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.Page;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.ManageLog;
import com.github.pagehelper.PageHelper;
import com.rczn.system.domain.Position;
import com.rczn.system.mapper.ManageLogMapper;
import com.rczn.system.service.ManageLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class ManageLogServiceImpl implements ManageLogService {
@Autowired
private ManageLogMapper manageLogMapper;
@Override
public Long insert(ManageLog manageLog) {
// 校验必填字段(日志名称和类型为必填)
Assert.notNull(manageLog.getLogName(), "日志名称不能为空");
Assert.notNull(manageLog.getLogType(), "日志类型不能为空");
//补充日志时间
if (manageLog.getLogWritetime() == null) {
manageLog.setLogWritetime(LocalDateTime.now());
}
// TODO 补充日志创建人信息
// manageLog.setCreateId(null);
manageLog.setCreateTime(LocalDateTime.now());
int rows = manageLogMapper.insert(manageLog);
return rows > 0 ? manageLog.getId() : null;
}
@Override
public Boolean deleteById(Long id, Long updateId) {
Assert.notNull(id, "日志ID不能为空");
int rows = manageLogMapper.deleteById(id);
return rows > 0;
}
@Override
public Boolean update(ManageLog manageLog) {
Assert.notNull(manageLog.getId(), "日志ID不能为空");
//如果更新时间为空,则自动更新
if (manageLog.getUpdateTime() == null) {
manageLog.setUpdateTime(LocalDateTime.now());
}
// TODO 补充日志更新人信息
// manageLog.setUpdateId(null);
int rows = manageLogMapper.update(manageLog);
return rows > 0;
}
@Override
public ManageLog selectById(Long id) {
Assert.notNull(id, "日志ID不能为空");
return manageLogMapper.selectById(id);
}
@Override
public PageBean<ManageLog> selectPage(Integer pageNum, Integer pageSize, ManageLog manageLog) {
// 校验分页参数
Assert.notNull(pageNum, "页码不能为空");
Assert.notNull(pageSize, "每页条数不能为空");
Assert.isTrue(pageNum > 0, "页码必须大于0");
Assert.isTrue(pageSize > 0 && pageSize <= 100000, "每页条数必须在1-10000之间");
// PageHelper 分页(自动拦截查询,添加 LIMIT 条件)
PageHelper.startPage(pageNum, pageSize);
List<ManageLog> logList = manageLogMapper.selectPage(manageLog);
Page<ManageLog> page = (Page<ManageLog>) logList;
PageBean<ManageLog> pageBean = new PageBean<>();
pageBean.setTotal(page.getTotal());
pageBean.setItems(page.getResult());
// 封装PageBean返回
return pageBean;
}
}

View File

@@ -0,0 +1,83 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Department;
import com.rczn.system.domain.Position;
import com.rczn.system.mapper.PositionMapper;
import com.rczn.system.service.PositionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.util.List;
@Service
public class PositionServiceImpl implements PositionService {
@Autowired
private PositionMapper positionMapper;
@Override
public Long insert(Position position) {
Assert.notNull(position.getPosiName(), "职位名称不能为空");
Assert.notNull(position.getPosiCode(), "职位编码不能为空");
int rows = positionMapper.insert(position);
return rows > 0 ? position.getId() : null;
}
@Override
public Boolean deleteById(Long id) {
Assert.notNull(id, "职位ID不能为空");
int rows = positionMapper.deleteById(id);
return rows > 0;
}
@Override
public Boolean update(Position position) {
Assert.notNull(position.getId(), "职位ID不能为空");
int rows = positionMapper.updateById(position);
return rows > 0;
}
@Override
public Position selectById(Long id) {
Assert.notNull(id, "职位ID不能为空");
return positionMapper.selectById(id);
}
@Override
public PageBean<Position> selectPage(Integer pageNum, Integer pageSize, String posiName, String posiCode) {
Assert.notNull(pageNum, "页码不能为空");
Assert.notNull(pageSize, "每页条数不能为空");
Assert.isTrue(pageNum > 0, "页码必须大于0");
Assert.isTrue(pageSize > 0 && pageSize <= 100000, "每页条数必须在1-10000之间");
// 1. 设置分页参数PageHelper 自动拦截后续的 SQL 进行分页)
PageHelper.startPage(pageNum, pageSize);
// 查询分页数据和总数
List<Position> items = positionMapper.selectPage(posiName, posiCode);
Page<Position> page = (Page<Position>) items;
PageBean<Position> pageBean = new PageBean<>();
pageBean.setTotal(page.getTotal());
pageBean.setItems(page.getResult());
// 封装PageBean返回
return pageBean;
}
/**
* 条件查询职位列表
* @param posiName 职位名称
* @param posiCode 职位编码
* @return 职位列表
*/
@Override
public List<Position> selectList(String posiName, String posiCode) {
return positionMapper.selectList(posiName, posiCode);
}
}

View File

@@ -0,0 +1,98 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.PageHelper;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Role;
import com.rczn.system.mapper.RoleMapper;
import com.rczn.system.service.RoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
/**
* Role 业务逻辑层实现
*/
@Service
@Transactional
public class RoleServiceImpl implements RoleService {
@Autowired
RoleMapper roleMapper;
@Override
public PageBean<Role> selectRolePage(Integer pageNum, Integer pageSize, String roleName, String roleCode) {
// 1. PageHelper 设置分页参数
PageHelper.startPage(pageNum, pageSize);
// 2. 执行查询
List<Role> roleList = roleMapper.selectRolePage(roleName, roleCode);
// 3. 查询总条数
Long total = roleMapper.selectTotal(roleName, roleCode);
// 4. 封装分页结果
return new PageBean<Role>() {{
setTotal(total);
setItems(roleList);
}};
}
@Override
public Role selectById(Long id) {
return roleMapper.selectById(id);
}
@Override
public Long insert(Role role) {
// 校验角色编码唯一性
Integer count = roleMapper.checkRoleCodeUnique(role.getRoleCode(), null);
if (count != null && count > 0) {
throw new IllegalArgumentException("角色编码:" + role.getRoleCode() + " 已存在");
}
// 更新创建时间、创建者
// TODO 待实现
// role.setCreateId(1L);
if (role.getCreateTime() == null) {
role.setCreateTime(LocalDateTime.now());
}
// 执行新增自动回填ID
roleMapper.insert(role);
return role.getId();
}
@Override
public Boolean update(Role role) {
// 校验ID是否存在
if (role.getId() == null) {
throw new IllegalArgumentException("修改角色必须传入ID");
}
// 校验角色编码唯一性(排除自身)
Integer count = roleMapper.checkRoleCodeUnique(role.getRoleCode(), role.getId());
if (count != null && count > 0) {
throw new IllegalArgumentException("角色编码:" + role.getRoleCode() + " 已存在");
}
// 更新更新时间、更新者
// TODO 待实现
// role.setUpdateId(1L);
if (role.getUpdateTime() == null) {
role.setUpdateTime(LocalDateTime.now());
}
// 执行修改
int rows = roleMapper.update(role);
return rows > 0;
}
@Override
public Boolean deleteById(Long id) {
// 先校验角色是否存在
Role role = roleMapper.selectById(id);
if (role == null) {
return false;
}
// 执行删除
int rows = roleMapper.deleteById(id);
return rows > 0;
}
}

View File

@@ -0,0 +1,86 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.Page;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.Position;
import com.rczn.system.domain.UserRole;
import com.rczn.system.mapper.UserRoleMapper;
import com.rczn.system.service.UserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.util.List;
@Service
public class UserRoleServiceImpl implements UserRoleService {
@Autowired
private UserRoleMapper userRoleMapper;
@Override
public Long insert(UserRole userRole) {
Assert.notNull(userRole.getUserId(), "用户ID不能为空");
Assert.notNull(userRole.getRoleId(), "角色ID不能为空");
int rows = userRoleMapper.insert(userRole);
return rows > 0 ? userRole.getId() : null;
}
@Override
public Boolean deleteById(Long id) {
Assert.notNull(id, "关联ID不能为空");
int rows = userRoleMapper.deleteById(id);
return rows > 0;
}
@Override
public Boolean deleteByUserId(Integer userId) {
Assert.notNull(userId, "用户ID不能为空");
int rows = userRoleMapper.deleteByUserId(userId);
return rows > 0;
}
@Override
public Boolean deleteByRoleId(Integer roleId) {
Assert.notNull(roleId, "角色ID不能为空");
int rows = userRoleMapper.deleteByRoleId(roleId);
return rows > 0;
}
@Override
public UserRole selectById(Long id) {
Assert.notNull(id, "关联ID不能为空");
return userRoleMapper.selectById(id);
}
@Override
public List<UserRole> selectByUserId(Integer userId) {
Assert.notNull(userId, "用户ID不能为空");
return userRoleMapper.selectByUserId(userId);
}
@Override
public List<UserRole> selectByRoleId(Integer roleId) {
Assert.notNull(roleId, "角色ID不能为空");
return userRoleMapper.selectByRoleId(roleId);
}
@Override
public PageBean<UserRole> selectPage(Integer pageNum, Integer pageSize, Integer userId, Integer roleId) {
Assert.notNull(pageNum, "页码不能为空");
Assert.notNull(pageSize, "每页条数不能为空");
Assert.isTrue(pageNum > 0, "页码必须大于0");
Assert.isTrue(pageSize > 0 && pageSize <= 100000, "每页条数必须在1-10000之间");
int start = (pageNum - 1) * pageSize;
List<UserRole> items = userRoleMapper.selectPage(userId, roleId, start, pageSize);
Page<UserRole> page = (Page<UserRole>) items;
PageBean<UserRole> pageBean = new PageBean<>();
pageBean.setTotal(page.getTotal());
pageBean.setItems(page.getResult());
// 封装PageBean返回
return pageBean;
}
}

View File

@@ -0,0 +1,77 @@
package com.rczn.system.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rczn.domain.PageBean;
import com.rczn.system.domain.User;
import com.rczn.system.mapper.UserMapper;
import com.rczn.system.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* User 业务逻辑层实现
*/
@Service
@Transactional // 事务管理(增删改操作需事务)
public class UserServiceImpl implements UserService {
// 注入 MapperLombok @RequiredArgsConstructor 自动生成构造器)
@Autowired
UserMapper userMapper;
@Override
public PageBean<User> selectUserPage(Integer pageNum, Integer pageSize, String userName) {
// 1. 设置分页参数PageHelper 自动拦截后续的 SQL 进行分页)
PageHelper.startPage(pageNum, pageSize);
// 2. 执行查询MyBatis 会自动添加 LIMIT 分页)
User user = new User();
user.setUserName(userName);
List<User> userList = userMapper.selectUserPage(user);
Page<User> userPage = (Page<User>) userList;
// 3. 查询总条数(支持模糊查询条件)
PageBean<User> pageBean = new PageBean<>();
pageBean.setTotal(userPage.getTotal());
pageBean.setItems(userPage);
// 4. 封装分页结果(使用你的自定义 PageBean
return pageBean;
}
@Override
public User selectById(Long id) {
// 查询不到返回 null后续 Controller 处理)
return userMapper.selectById(id, false);
}
@Override
public Long insert(User user) {
// 执行新增XML 中已配置 useGeneratedKeys会自动回填 ID 到 user 对象)
userMapper.insert(user);
return user.getId(); // 返回新增用户的 ID
}
@Override
public Boolean update(User user) {
if (user.getId() == null) {
throw new IllegalArgumentException("修改用户必须传入 ID");
}
// 执行修改(返回影响行数,>0 表示修改成功)
int rows = userMapper.update(user);
return rows > 0;
}
@Override
public Boolean deleteById(Long id) {
// 执行删除(返回影响行数,>0 表示删除成功)
int rows = userMapper.deleteById(id,null);
return rows > 0;
}
}

View File

@@ -0,0 +1,97 @@
# 服务器配置
server:
port: 9090 # 项目端口
servlet:
encoding:
charset: UTF-8 # 解决中文乱码(含接口文档/响应)
enabled: true
force: true
# Spring核心配置
spring:
application:
name: rczn-admin # 应用名称
# 数据源配置MySQL 8.x
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://47.116.126.33:3306/rc_autoplc_program?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: nianke
password: Jy@.niankeCrm2025
# 解决跨域可选配合之前的CorsConfig
web:
cors:
allowed-origins: false # 禁用默认CORS使用自定义CorsConfig
# 关键Jackson 序列化配置(替代 JacksonConfig
jackson:
# 允许空对象序列化(解决 HttpMediaTypeNotAcceptableException 核心)
serialization:
fail-on-empty-beans: false
# 格式化 JSON 输出(可选,便于调试)
indent-output: true
# 忽略未知字段(避免前端传多余字段报错)
deserialization:
fail-on-unknown-properties: false
# 支持 Java 8 日期类型LocalDateTime
modules:
- com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
# 日期格式化(可选,统一日期返回格式)
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
# MyBatis配置
mybatis:
configuration:
map-underscore-to-camel-case: true # 下划线转驼峰
mapper-locations: classpath:mapper/**/*.xml # 补充指定Mapper.xml文件路径必加
type-aliases-package: com.rczn.**.domain # 补充:实体类别名包(可选)
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 关键SQL 打印到控制台
log-prefix: "[MyBatis] " # 可选:日志前缀,便于区分 SQL 日志
default-statement-timeout: 30 # 可选SQL 执行超时时间(秒)
# HikariCP 连接池配置(关键)
hikari:
max-lifetime: 1800000 # 连接最大生命周期30 分钟,必须小于 MySQL wait_timeout默认 8 小时)
idle-timeout: 600000 # 连接空闲超时时间10 分钟)
connection-timeout: 30000 # 连接超时时间30 秒)
minimum-idle: 5 # 最小空闲连接数
maximum-pool-size: 10 # 最大连接池大小
test-while-idle: true # 空闲时检测连接有效性
validation-timeout: 5000 # 连接校验超时时间5 秒)
connection-test-query: SELECT 1 # 连接校验 SQLMySQL 可用此简单查询)
# PageHelper 分页插件配置
pagehelper:
helper-dialect: mysql # 数据库方言(适配 MySQL
reasonable: true # 合理化分页页码≤0时查第1页页码超出总页数时查最后1页
support-methods-arguments: true # 支持通过 Mapper 接口参数传递分页参数
params: count=countSql # 分页参数名映射
# SpringDoc OpenAPI 3 核心配置适配Spring Boot 3.x
springdoc:
packages-to-scan: com.rczn # 扫描的基础包Controller所在包
api-docs:
enabled: true # 启用/v3/api-docs接口
path: /v3/api-docs # OpenAPI JSON数据路径默认
swagger-ui:
path: /swagger-ui.html # 自定义Swagger UI访问路径兼容Spring Boot 2.x习惯
tags-sorter: alpha # 标签字母排序
operations-sorter: alpha # 接口字母排序
disable-swagger-default-url: true # 禁用默认PetStore示例
default-flat-param-object: false # 禁用扁平参数对象
paths-to-exclude: /error, /actuator/** # 排除错误接口/监控接口(可选)
# OpenAPI文档基础信息中文正常显示
openapi:
info:
title: XX自动化编程系统API文档
description: SpringBoot 3.x + SpringDoc OpenAPI 3 接口文档
version: 1.0.0
contact:
name: 研发组
email: xxx@xxx.com
servers:
- url: http://localhost:9090 # 开发环境地址
description: 本地开发环境
- url: http://47.116.126.33:9090 # 测试环境地址
description: 测试环境

View File

@@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rczn.system.mapper.DepartmentMapper">
<!-- 通用字段BaseBean继承的字段 -->
<sql id="baseColumn">
id, create_id, create_time, update_id, update_time, del_sign, remark
</sql>
<!-- Department专属字段 -->
<sql id="deptColumn">
dept_name, dept_code, parent_id, leader_id
</sql>
<!-- 新增部门(修复多余逗号问题,支持空字段忽略) -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_department (
<!-- 用 trim 标签prefix="(" suffix=")" suffixOverrides="," 去除末尾多余逗号 -->
<trim prefix="" suffix="" suffixOverrides=",">
<!-- 通用字段:非空才添加字段 -->
<if test="createId != null">create_id,</if>
<if test="createTime != null">create_time,</if>
<if test="remark != null and remark != ''">remark,</if>
<!-- 部门专属字段:非空才添加字段 -->
<if test="deptName != null and deptName != ''">dept_name,</if>
<if test="deptCode != null and deptCode != ''">dept_code,</if>
<if test="parentId != null">parent_id,</if>
<if test="leaderId != null">leader_id,</if>
</trim>
) VALUES (
<!-- 用 trim 标签去除值列表末尾多余逗号 -->
<trim prefix="" suffix="" suffixOverrides=",">
<!-- 通用字段:非空才添加值 -->
<if test="createId != null">#{createId},</if>
<if test="createTime != null">#{createTime},</if>
<if test="remark != null and remark != ''">#{remark},</if>
<!-- 部门专属字段:非空才添加值 -->
<if test="deptName != null and deptName != ''">#{deptName},</if>
<if test="deptCode != null and deptCode != ''">#{deptCode},</if>
<if test="parentId != null">#{parentId},</if>
<if test="leaderId != null">#{leaderId},</if>
</trim>
)
</insert>
<!-- 逻辑删除部门 -->
<update id="deleteById">
UPDATE sys_department
SET del_sign = 1, update_time = NOW()
WHERE id = #{id} AND del_sign = 0
</update>
<!-- 更新部门 -->
<update id="updateById">
UPDATE sys_department
<set>
<if test="deptName != null and deptName != ''">dept_name = #{deptName},</if>
<if test="deptCode != null and deptCode != ''">dept_code = #{deptCode},</if>
<if test="parentId != null">parent_id = #{parentId},</if>
<if test="leaderId != null">leader_id = #{leaderId},</if>
<if test="updateId != null">update_id = #{updateId},</if>
<if test="remark != null">remark = #{remark},</if>
update_time = NOW()
</set>
WHERE id = #{id} AND del_sign = 0
</update>
<!-- 根据ID查询部门 -->
<select id="selectById" resultType="com.rczn.system.domain.Department">
SELECT
<include refid="baseColumn"/>, <include refid="deptColumn"/>
FROM sys_department
WHERE id = #{id} AND del_sign = 0
</select>
<!-- 分页查询部门 -->
<select id="selectPage" resultType="com.rczn.system.domain.Department">
SELECT
<include refid="baseColumn"/>, <include refid="deptColumn"/>
FROM sys_department
WHERE del_sign = 0
<if test="deptName != null and deptName != ''">
AND dept_name LIKE CONCAT('%', #{deptName}, '%')
</if>
<if test="deptCode != null and deptCode != ''">
AND dept_code LIKE CONCAT('%', #{deptCode}, '%')
</if>
<if test="parentId != null">
AND parent_id = #{parentId}
</if>
ORDER BY id DESC
</select>
<!-- 查询分页总数 -->
<select id="selectTotal" resultType="java.lang.Integer">
SELECT COUNT(id)
FROM sys_department
WHERE del_sign = 0
<if test="deptName != null and deptName != ''">
AND dept_name LIKE CONCAT('%', #{deptName}, '%')
</if>
<if test="deptCode != null and deptCode != ''">
AND dept_code LIKE CONCAT('%', #{deptCode}, '%')
</if>
<if test="parentId != null">
AND parent_id = #{parentId}
</if>
</select>
<!-- 公共字段映射复用原有resultMap新增parent/leader关联 -->
<resultMap id="DeptResultMap" type="com.rczn.system.domain.Department">
<!-- 基础字段继承BaseBean -->
<id column="id" property="id"/>
<result column="create_id" property="createId"/>
<result column="create_time" property="createTime"/>
<result column="update_id" property="updateId"/>
<result column="update_time" property="updateTime"/>
<result column="del_sign" property="delSign"/>
<result column="remark" property="remark"/>
<!-- 部门专属字段 -->
<result column="dept_name" property="deptName"/>
<result column="dept_code" property="deptCode"/>
<result column="parent_id" property="parentId"/>
<result column="leader_id" property="leaderId"/>
<!-- &lt;!&ndash; 关联父部门(可选,用于显示父部门名称) &ndash;&gt;-->
<!-- <association property="parent" javaType="com.rczn.system.domain.Department">-->
<!-- <id column="parent_id" property="id"/>-->
<!-- <result column="parent_dept_name" property="deptName"/>-->
<!-- </association>-->
<!-- &lt;!&ndash; 关联部门负责人(可选,用于显示负责人名称) &ndash;&gt;-->
<!-- <association property="leader" javaType="com.rczn.system.domain.User">-->
<!-- <id column="leader_id" property="id"/>-->
<!-- <result column="leader_name" property="userName"/>-->
<!-- </association>-->
</resultMap>
<!-- 1. 查询所有未删除的部门(用于递归组装树) -->
<select id="selectAllDept" resultMap="DeptResultMap">
SELECT
d.id, d.dept_name, d.dept_code, d.parent_id, d.leader_id,
d.create_id, d.create_time, d.update_id, d.update_time, d.del_sign, d.remark
-- p.dept_name AS parent_dept_name, -- 父部门名称(关联查询)
-- u.user_name AS leader_name -- 负责人名称(关联查询)
FROM sys_department d
-- LEFT JOIN sys_department p ON d.parent_id = p.id AND p.del_sign = 0 -- 关联父部门(未删除)
-- LEFT JOIN sys_user u ON d.leader_id = u.id AND u.del_sign = 0 -- 关联负责人(未删除)
WHERE d.del_sign = 0 -- 仅查询未删除的部门
ORDER BY d.id ASC
</select>
<!-- 2. 按父部门ID查询子部门用于递归查询 -->
<select id="selectChildrenByParentId" resultMap="DeptResultMap" parameterType="java.lang.Integer">
SELECT
d.id, d.dept_name, d.dept_code, d.parent_id, d.leader_id,
d.create_id, d.create_time, d.update_id, d.update_time, d.del_sign, d.remark
-- p.dept_name AS parent_dept_name,
-- u.user_name AS leader_name
FROM sys_department d
-- LEFT JOIN sys_department p ON d.parent_id = p.id AND p.del_sign = 0
-- LEFT JOIN sys_user u ON d.leader_id = u.id AND u.del_sign = 0
WHERE d.del_sign = 0
AND d.parent_id = #{parentId} -- 按父部门ID筛选
ORDER BY d.id ASC
</select>
<!-- 3. 查询顶级部门parent_id IS NULL -->
<select id="selectTopDept" resultMap="DeptResultMap">
SELECT
d.id, d.dept_name, d.dept_code, d.parent_id, d.leader_id,
d.create_id, d.create_time, d.update_id, d.update_time, d.del_sign, d.remark
-- p.dept_name AS parent_dept_name,
-- u.user_name AS leader_name
FROM sys_department d
-- LEFT JOIN sys_department p ON d.parent_id = p.id AND p.del_sign = 0
-- LEFT JOIN sys_user u ON d.leader_id = u.id AND u.del_sign = 0
WHERE d.del_sign = 0
AND d.parent_id IS NULL -- 顶级部门(无父部门)
ORDER BY d.id ASC
</select>
</mapper>

View File

@@ -0,0 +1,175 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rczn.system.mapper.ManageLogMapper">
<!-- 公共字段BaseBean 继承的字段) -->
<sql id="baseColumn">
id, create_id, create_time, update_id, update_time, del_sign, remark
</sql>
<!-- ManageLog 专属字段 -->
<sql id="logColumn">
log_name, log_type, log_writetime, log_content
</sql>
<!-- 结果集映射(关联数据库列与实体类字段) -->
<resultMap id="LogResultMap" type="com.rczn.system.domain.ManageLog">
<!-- 公共字段映射 -->
<id column="id" property="id"/>
<result column="create_id" property="createId"/>
<result column="create_time" property="createTime"/>
<result column="update_id" property="updateId"/>
<result column="update_time" property="updateTime"/>
<result column="del_sign" property="delSign"/>
<result column="remark" property="remark"/>
<!-- 专属字段映射 -->
<result column="log_name" property="logName"/>
<result column="log_type" property="logType"/>
<result column="log_writetime" property="logWritetime"/>
<result column="log_content" property="logContent"/>
</resultMap>
<!-- 1. 新增日志(空字段忽略,用数据库默认值) -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_manage_log (
<trim suffixOverrides=",">
<!-- 专属字段 -->
<if test="logName != null and logName != ''"> log_name,</if>
<if test="logType != null and logType != ''"> log_type,</if>
<if test="logWritetime != null"> log_writetime,</if>
<if test="logContent != null and logContent != ''"> log_content,</if>
<!-- 公共字段 -->
<if test="createId != null"> create_id,</if>
<if test="createTime != null"> create_time,</if>
<if test="updateId != null"> update_id,</if>
<if test="updateTime != null"> update_time,</if>
<if test="delSign != null"> del_sign,</if>
<if test="remark != null and remark != ''"> remark,</if>
</trim>
) VALUES (
<trim suffixOverrides=",">
<!-- 专属字段:空字段传递 null数据库设默认值 -->
<if test="logName != null and logName != ''">#{logName},</if>
<if test="logType != null and logType != ''">#{logType},</if>
<if test="logWritetime != null">#{logWritetime},</if>
<if test="logContent != null and logContent != ''">#{logContent},</if>
<!-- 公共字段:空字段传递 null数据库设默认值 -->
<if test="createId != null">#{createId},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateId != null">#{updateId},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="delSign != null">#{delSign},</if>
<if test="remark != null and remark != ''">#{remark},</if>
</trim>
)
</insert>
<!-- 2. 更新日志(仅更新非空字段) -->
<update id="update">
UPDATE sys_manage_log
<set>
<!-- 专属字段:非空才更新 -->
<if test="logName != null and logName != ''">log_name = #{logName},</if>
<if test="logType != null and logType != ''">log_type = #{logType},</if>
<if test="logWritetime != null">log_writetime = #{logWritetime},</if>
<if test="logContent != null and logContent != ''">log_content = #{logContent},</if>
<!-- 公共字段:非空才更新 -->
<if test="updateId != null">update_id = #{updateId},</if>
<if test="remark != null and remark != ''">remark = #{remark},</if>
<if test="delSign != null">del_sign = #{delSign},</if>
<!-- 强制更新时间为当前时间 -->
update_time = NOW()
</set>
WHERE id = #{id}
AND del_sign = 0 <!-- 仅更新未删除的数据 -->
</update>
<!-- 3. 逻辑删除日志 -->
<delete id="deleteById">
UPDATE sys_manage_log
SET
del_sign = 1,
update_time = NOW(),
<if test="updateId != null">update_id = #{updateId}</if>
WHERE id = #{id}
AND del_sign = 0 <!-- 避免重复删除 -->
</delete>
<!-- 4. 按 ID 查询日志 -->
<select id="selectById" resultMap="LogResultMap">
SELECT
<include refid="baseColumn"/>,
<include refid="logColumn"/>
FROM sys_manage_log
WHERE id = #{id}
AND del_sign = 0 <!-- 仅查未删除数据 -->
</select>
<!-- 5. 分页查询日志(空字段忽略条件) -->
<select id="selectPage" resultMap="LogResultMap" parameterType="com.rczn.system.domain.ManageLog">
SELECT
<include refid="baseColumn"/>,
<include refid="logColumn"/>
FROM sys_manage_log
<where>
<!-- 默认查未删除数据,传 delSign=1 可查已删除 -->
<if test="delSign == null">
AND del_sign = 0
</if>
<if test="delSign != null">
AND del_sign = #{delSign}
</if>
<!-- 日志名称:模糊查询,空字段忽略 -->
<if test="logName != null and logName != ''">
AND log_name LIKE CONCAT('%', #{logName}, '%')
</if>
<!-- 日志类型:精准查询,空字段忽略 -->
<if test="logType != null and logType != ''">
AND log_type = #{logType}
</if>
<!-- 日志写入时间:范围查询(可选,空字段忽略) -->
<if test="startTime != null">
AND log_writetime >= #{startTime}
</if>
<if test="endTime != null">
AND log_writetime &lt;= #{endTime}
</if>
<!-- 创建人ID精准查询空字段忽略 -->
<if test="createId != null">
AND create_id = #{createId}
</if>
</where>
ORDER BY log_writetime DESC <!-- 按日志写入时间倒序 -->
</select>
<!-- 6. 查询分页总数(与分页查询条件一致) -->
<select id="selectTotal" resultType="java.lang.Long" parameterType="com.rczn.system.domain.ManageLog">
SELECT COUNT(*)
FROM sys_manage_log
<where>
<if test="delSign == null">
AND del_sign = 0
</if>
<if test="delSign != null">
AND del_sign = #{delSign}
</if>
<if test="logName != null and logName != ''">
AND log_name LIKE CONCAT('%', #{logName}, '%')
</if>
<if test="logType != null and logType != ''">
AND log_type = #{logType}
</if>
<if test="logWritetimeStart != null">
AND log_writetime >= #{logWritetimeStart}
</if>
<if test="logWritetimeEnd != null">
AND log_writetime &lt;= #{logWritetimeEnd}
</if>
<if test="createId != null">
AND create_id = #{createId}
</if>
</where>
</select>
</mapper>

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rczn.system.mapper.PositionMapper">
<sql id="baseColumn">
id, create_id, create_time, update_id, update_time, del_sign, remark
</sql>
<sql id="posiColumn">
posi_name, posi_code
</sql>
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_position (
<include refid="posiColumn"/>, create_time, update_time, del_sign
) VALUES (
#{posiName}, #{posiCode}, NOW(), NOW(), 0
)
</insert>
<update id="deleteById">
UPDATE sys_position
SET del_sign = 1, update_time = NOW()
WHERE id = #{id} AND del_sign = 0
</update>
<update id="updateById">
UPDATE sys_position
<set>
<if test="posiName != null and posiName != ''">posi_name = #{posiName},</if>
<if test="posiCode != null and posiCode != ''">posi_code = #{posiCode},</if>
<if test="updateId != null">update_id = #{updateId},</if>
<if test="remark != null">remark = #{remark},</if>
update_time = NOW()
</set>
WHERE id = #{id} AND del_sign = 0
</update>
<select id="selectById" resultType="com.rczn.system.domain.Position">
SELECT
<include refid="baseColumn"/>, <include refid="posiColumn"/>
FROM sys_position
WHERE id = #{id} AND del_sign = 0
</select>
<select id="selectPage" resultType="com.rczn.system.domain.Position">
SELECT
<include refid="baseColumn"/>, <include refid="posiColumn"/>
FROM sys_position
WHERE del_sign = 0
<if test="posiName != null and posiName != ''">
AND posi_name LIKE CONCAT('%', #{posiName}, '%')
</if>
<if test="posiCode != null and posiCode != ''">
AND posi_code LIKE CONCAT('%', #{posiCode}, '%')
</if>
ORDER BY id DESC
</select>
<select id="selectTotal" resultType="java.lang.Integer">
SELECT COUNT(id)
FROM sys_position
WHERE del_sign = 0
<if test="posiName != null and posiName != ''">
AND posi_name LIKE CONCAT('%', #{posiName}, '%')
</if>
<if test="posiCode != null and posiCode != ''">
AND posi_code LIKE CONCAT('%', #{posiCode}, '%')
</if>
</select>
<select id="selectList" resultType="com.rczn.system.domain.Position">
SELECT
<include refid="baseColumn"/>, <include refid="posiColumn"/>
FROM sys_position
WHERE del_sign = 0
<if test="posiName != null and posiName != ''">
AND posi_name LIKE CONCAT('%', #{posiName}, '%')
</if>
<if test="posiCode != null and posiCode != ''">
AND posi_code LIKE CONCAT('%', #{posiCode}, '%')
</if>
ORDER BY id DESC
</select>
</mapper>

View File

@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rczn.system.mapper.RoleMapper">
<!-- 通用结果集映射 -->
<resultMap id="RoleResultMap" type="com.rczn.system.domain.Role">
<id column="id" property="id"/>
<result column="role_name" property="roleName"/>
<result column="role_code" property="roleCode"/>
</resultMap>
<sql id="baseColumn">
id, create_id, create_time, update_id, update_time, del_sign, remark
</sql>
<!-- 1. 分页查询角色(支持多条件模糊查询) -->
<select id="selectRolePage" resultMap="RoleResultMap">
SELECT id, role_name, role_code
FROM sys_role
<where>
<if test="roleName != null and roleName != ''">
AND role_name LIKE CONCAT('%', #{roleName}, '%')
</if>
<if test="roleCode != null and roleCode != ''">
AND role_code LIKE CONCAT('%', #{roleCode}, '%')
</if>
</where>
ORDER BY id DESC
</select>
<!-- 2. 根据ID查询角色 -->
<select id="selectById" resultMap="RoleResultMap">
SELECT <include refid="baseColumn"></include>, role_name, role_code
FROM sys_role
WHERE id = #{id}
</select>
<!-- 3. 新增角色 -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_role (
<trim suffixOverrides=",">
<if test="roleName != null ">role_name,</if>
<if test="roleCode != null ">role_code,</if>
<if test="createId != null ">create_id,</if>
<if test="createTime != null ">create_time,</if>
<if test="updateId != null ">update_id,</if>
<if test="updateTime != null ">update_time,</if>
<if test="delSign != null ">del_sign,</if>
<if test="remark != null ">remark,</if>
</trim>
)
VALUES (
<trim suffixOverrides=",">
<if test="roleName != null ">#{roleName},</if>
<if test="roleCode != null ">#{roleCode},</if>
<if test="createId != null ">#{createId},</if>
<if test="createTime != null ">#{createTime},</if>
<if test="updateId != null ">#{updateId},</if>
<if test="updateTime != null ">#{updateTime},</if>
<if test="delSign != null ">#{delSign},</if>
<if test="remark != null ">#{remark},</if>
</trim>
)
</insert>
<!-- 4. 修改角色(仅更新非空字段) -->
<update id="update">
UPDATE sys_role
<set>
<if test="roleName != null ">role_name = #{roleName},</if>
<if test="roleCode != null ">role_code = #{roleCode}</if>
<if test="updateId != null ">updateId = NULL,</if>
<if test="updateTime != null ">updateTime = now(),</if>
<if test="remark != null ">remark = NULL,</if>
</set>
WHERE id = #{id}
</update>
<!-- 5. 根据ID删除角色 -->
<delete id="deleteById">
DELETE FROM sys_role WHERE id = #{id}
</delete>
<!-- 6. 查询总条数(支持多条件模糊查询) -->
<select id="selectTotal" resultType="java.lang.Long">
SELECT COUNT(*) FROM sys_role
<where>
<if test="roleName != null and roleName != ''">
AND role_name LIKE CONCAT('%', #{roleName}, '%')
</if>
<if test="roleCode != null and roleCode != ''">
AND role_code LIKE CONCAT('%', #{roleCode}, '%')
</if>
</where>
</select>
<!-- 7. 校验角色编码唯一性 -->
<select id="checkRoleCodeUnique" resultType="java.lang.Integer">
SELECT COUNT(*) FROM sys_role
WHERE role_code = #{roleCode}
<if test="id != null">
AND id != #{id} <!-- 修改时排除自身ID -->
</if>
</select>
</mapper>

View File

@@ -0,0 +1,202 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 对应 Mapper 接口全路径 -->
<mapper namespace="com.rczn.system.mapper.UserMapper">
<!-- 通用结果集映射(复用,避免重复编写) -->
<resultMap id="UserResultMap" type="com.rczn.system.domain.User">
<id column="id" property="id"/>
<result column="create_id" property="createId"/>
<result column="create_time" property="createTime"/>
<result column="update_id" property="updateId"/>
<result column="update_time" property="updateTime"/>
<result column="del_sign" property="delSign"/>
<result column="remark" property="remark"/>
<result column="user_name" property="userName"/>
<result column="password" property="password"/>
<result column="salt" property="salt"/>
<result column="nicke" property="nicke"/>
<result column="sex" property="sex"/>
<result column="email_addr" property="emailAddr"/>
<result column="address" property="address"/>
<result column="telephone" property="telephone"/>
<result column="dep_id" property="depId"/>
<result column="pos_id" property="posId"/>
</resultMap>
<!-- 公共字段BaseBean 继承的字段) -->
<sql id="baseColumn">
id, create_id, create_time, update_id, update_time, del_sign, remark
</sql>
<!-- 用户专属字段 -->
<sql id="userColumn">
user_name, password, salt, nicke, sex, email_addr, address, telephone, dep_id, pos_id
</sql>
<!-- 1. 分页查询用户(所有传参为空时忽略该条件) -->
<select id="selectUserPage" resultMap="UserResultMap" parameterType="com.rczn.system.domain.User">
SELECT
<include refid="baseColumn"/>,
<include refid="userColumn"/>
FROM sys_user
<where>
<!-- 逻辑删除标识默认查未删除del_sign=0传参不为空时按传参筛选 -->
<if test="delSign == null">
AND del_sign = 0
</if>
<if test="delSign != null">
AND del_sign = #{delSign}
</if>
<!-- 用户名:为空时忽略模糊查询 -->
<if test="userName != null and userName != ''">
AND user_name LIKE CONCAT('%', #{userName}, '%')
</if>
<!-- 部门ID为空时忽略 -->
<if test="depId != null">
AND dep_id = #{depId}
</if>
<!-- 职位ID为空时忽略 -->
<if test="posId != null">
AND pos_id = #{posId}
</if>
<!-- 创建人ID为空时忽略 -->
<if test="createId != null">
AND create_id = #{createId}
</if>
<!-- 性别:为空时忽略 -->
<if test="sex != null">
AND sex = #{sex}
</if>
</where>
ORDER BY id DESC
</select>
<!-- 2. 根据ID查询用户支持查询已删除数据传参为空时返回null -->
<select id="selectById" resultMap="UserResultMap">
SELECT
<include refid="baseColumn"/>,
<include refid="userColumn"/>
FROM sys_user
WHERE id = #{id}
<!-- 可选:添加删除标识筛选(为空时查所有状态,不为空时按状态筛选) -->
<if test="delSign != null">
AND del_sign = #{delSign}
</if>
</select>
<!-- 3. 新增用户(传参为空时用默认值,非空时用传参值) -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_user (
<trim suffixOverrides=",">
<if test="userName != null and userName != ''"> user_name,</if>
<if test="password != null and password != ''"> password,</if>
<if test="salt != null and salt != ''"> salt,</if>
<if test="nicke != null and nicke != ''"> nicke,</if>
<if test="sex != null"> sex,</if>
<if test="emailAddr != null and emailAddr != ''"> email_addr,</if>
<if test="address != null and address != ''"> address,</if>
<if test="telephone != null and telephone != ''"> telephone,</if>
<if test="depId != null"> dep_id,</if>
<if test="posId != null"> pos_id,</if>
<!-- 公共字段:为空时用默认值,非空时用传参 -->
<if test="createId != null"> create_id,</if>
<if test="createTime != null"> create_time,</if>
<if test="updateId != null"> update_id,</if>
<if test="updateTime != null"> update_time,</if>
<!-- 方案1delSign 为空时设为 0 -->
<if test="delSign != null"> del_sign,</if>
<if test="remark != null and remark != ''"> remark,</if>
</trim>
) VALUES (
<trim suffixOverrides=",">
<if test="userName != null and userName != ''"> #{userName},</if>
<if test="password != null and password != ''"> #{password},</if>
<if test="salt != null and salt != ''"> #{salt},</if>
<if test="nicke != null and nicke != ''"> #{nicke},</if>
<if test="sex != null"> #{sex},</if>
<if test="emailAddr != null and emailAddr != ''"> #{emailAddr},</if>
<if test="address != null and address != ''"> #{address},</if>
<if test="telephone != null and telephone != ''"> #{telephone},</if>
<if test="depId != null"> #{depId},</if>
<if test="posId != null"> #{posId},</if>
<!-- 公共字段:为空时用默认值,非空时用传参 -->
<if test="createId != null"> #{createId},</if>
<if test="createTime != null"> #{createTime},</if>
<if test="updateId != null"> #{updateId},</if>
<if test="updateTime != null"> #{updateTime},</if>
<!-- 方案1delSign 为空时设为 0 -->
<if test="delSign != null"> #{delSign},</if>
<if test="remark != null and remark != ''"> #{remark},</if>
</trim>
)
</insert>
<!-- 4. 修改用户(仅更新非空字段,空字段不更新) -->
<update id="update">
UPDATE sys_user
<set>
<!-- 用户专属字段:非空才更新 -->
<if test="userName != null and userName != ''">user_name = #{userName},</if>
<if test="password != null and password != ''">password = #{password},</if>
<if test="salt != null and salt != ''">salt = #{salt},</if>
<if test="nicke != null and nicke != ''">nicke = #{nicke},</if>
<if test="sex != null">sex = #{sex},</if>
<if test="emailAddr != null and emailAddr != ''">email_addr = #{emailAddr},</if>
<if test="address != null and address != ''">address = #{address},</if>
<if test="telephone != null and telephone != ''">telephone = #{telephone},</if>
<if test="depId != null">dep_id = #{depId},</if>
<if test="posId != null">pos_id = #{posId},</if>
<!-- 公共字段:非空才更新 -->
<if test="updateId != null">update_id = #{updateId},</if>
<if test="remark != null and remark != ''">remark = #{remark},</if>
<if test="delSign != null">del_sign = #{delSign},</if>
<!-- 更新时间:强制更新为当前时间(无论是否传参) -->
update_time = NOW()
</set>
WHERE id = #{id}
</update>
<!-- 5. 根据ID删除用户逻辑删除替代物理删除传参为空时不执行 -->
<delete id="deleteById">
UPDATE sys_user
SET
del_sign = 1,
update_time = NOW()
<if test="updateId != null">, update_id = #{updateId}</if>
WHERE id = #{id}
AND del_sign = 0 <!-- 避免重复删除 -->
</delete>
<!-- 6. 查询总条数(与分页查询条件一致,传参为空时忽略) -->
<select id="selectTotal" resultType="java.lang.Long">
SELECT COUNT(*)
FROM sys_user
<where>
<if test="delSign == null">
AND del_sign = 0
</if>
<if test="delSign != null">
AND del_sign = #{delSign}
</if>
<if test="userName != null and userName != ''">
AND user_name LIKE CONCAT('%', #{userName}, '%')
</if>
<if test="depId != null">
AND dep_id = #{depId}
</if>
<if test="posId != null">
AND pos_id = #{posId}
</if>
<if test="createId != null">
AND create_id = #{createId}
</if>
<if test="sex != null">
AND sex = #{sex}
</if>
</where>
</select>
</mapper>

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rczn.system.mapper.UserRoleMapper">
<sql id="baseColumn">
id, create_id, create_time, update_id, update_time, del_sign, remark
</sql>
<sql id="userRoleColumn">
user_id, role_id
</sql>
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_user_role (
<include refid="userRoleColumn"/>, create_time, update_time, del_sign
) VALUES (
#{userId}, #{roleId}, NOW(), NOW(), 0
)
</insert>
<delete id="deleteById">
DELETE FROM sys_user_role WHERE id = #{id}
</delete>
<delete id="deleteByUserId">
DELETE FROM sys_user_role WHERE user_id = #{userId}
</delete>
<delete id="deleteByRoleId">
DELETE FROM sys_user_role WHERE role_id = #{roleId}
</delete>
<select id="selectById" resultType="com.rczn.system.domain.UserRole">
SELECT
<include refid="baseColumn"/>, <include refid="userRoleColumn"/>
FROM sys_user_role
WHERE id = #{id}
</select>
<select id="selectByUserId" resultType="com.rczn.system.domain.UserRole">
SELECT
<include refid="baseColumn"/>, <include refid="userRoleColumn"/>
FROM sys_user_role
WHERE user_id = #{userId}
</select>
<select id="selectByRoleId" resultType="com.rczn.system.domain.UserRole">
SELECT
<include refid="baseColumn"/>, <include refid="userRoleColumn"/>
FROM sys_user_role
WHERE role_id = #{roleId}
</select>
<select id="selectPage" resultType="com.rczn.system.domain.UserRole">
SELECT
<include refid="baseColumn"/>, <include refid="userRoleColumn"/>
FROM sys_user_role
WHERE 1=1
<if test="userId != null">AND user_id = #{userId}</if>
<if test="roleId != null">AND role_id = #{roleId}</if>
ORDER BY id DESC
LIMIT #{start}, #{pageSize}
</select>
<select id="selectTotal" resultType="java.lang.Integer">
SELECT COUNT(id)
FROM sys_user_role
WHERE 1=1
<if test="userId != null">AND user_id = #{userId}</if>
<if test="roleId != null">AND role_id = #{roleId}</if>
</select>
</mapper>