1. 统一包名修改

This commit is contained in:
chenbowen
2025-09-22 11:55:27 +08:00
parent a001fc8f16
commit 0d46897482
2739 changed files with 512 additions and 512 deletions

24
zt-module-system/pom.xml Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.zt.plat</groupId>
<artifactId>zt</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<modules>
<module>zt-module-system-api</module>
<module>zt-module-system-server</module>
</modules>
<artifactId>zt-module-system</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<description>
system 模块下,我们放通用业务,支撑上层的核心业务。
例如说:用户、部门、权限、数据字典等等
</description>
</project>

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.zt.plat</groupId>
<artifactId>zt-module-system</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>zt-module-system-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
system 模块 API暴露给其它模块调用
</description>
<dependencies>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-common</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springdoc</groupId> <!-- 接口文档:使用最新版本的 Swagger 模型 -->
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,89 @@
package com.zt.plat.module.system.api.dept;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.util.collection.CollectionUtils;
import com.zt.plat.module.system.api.dept.dto.*;
import com.zt.plat.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 部门")
public interface DeptApi {
String PREFIX = ApiConstants.PREFIX + "/dept";
// === 以下为补全的接口方法 ===
@PostMapping(PREFIX + "/create")
@Operation(summary = "新增部门")
CommonResult<Long> createDept(@RequestBody DeptSaveReqDTO createReqVO);
@PutMapping(PREFIX + "/update")
@Operation(summary = "修改部门")
CommonResult<Boolean> updateDept(@RequestBody DeptSaveReqDTO updateReqVO);
@DeleteMapping(PREFIX + "/delete")
@Operation(summary = "删除部门")
CommonResult<Boolean> deleteDept(@RequestParam("id") Long id);
@PostMapping(PREFIX + "/list-all")
@Operation(summary = "获得部门列表")
CommonResult<List<DeptDetailRespDTO>> getDeptList(@RequestBody DeptListReqDTO reqVO);
@GetMapping(PREFIX + "/simple-list")
@Operation(summary = "获得部门精简信息列表")
CommonResult<List<DeptSimpleRespDTO>> getSimpleDeptList();
@GetMapping(PREFIX + "/simple-company-list")
@Operation(summary = "获得公司精简信息列表")
CommonResult<List<DeptSimpleRespDTO>> getSimpleCompanyList();
@GetMapping(PREFIX + "/all-company-list")
@Operation(summary = "获得所有公司精简信息列表")
CommonResult<List<DeptSimpleRespDTO>> getAllCompanyList();
@GetMapping(PREFIX + "/get")
@Operation(summary = "获得部门信息")
@Parameter(name = "id", description = "部门编号", example = "1024", required = true)
CommonResult<DeptRespDTO> getDept(@RequestParam("id") Long id);
@GetMapping(PREFIX + "/list")
@Operation(summary = "获得部门信息数组")
@Parameter(name = "ids", description = "部门编号数组", example = "1,2", required = true)
CommonResult<List<DeptRespDTO>> getDeptList(@RequestParam("ids") Collection<Long> ids);
@GetMapping(PREFIX + "/valid")
@Operation(summary = "校验部门是否合法")
@Parameter(name = "ids", description = "部门编号数组", example = "1,2", required = true)
CommonResult<Boolean> validateDeptList(@RequestParam("ids") Collection<Long> ids);
/**
* 获得指定编号的部门 Map
*
* @param ids 部门编号数组
* @return 部门 Map
*/
default Map<Long, DeptRespDTO> getDeptMap(Collection<Long> ids) {
List<DeptRespDTO> list = getDeptList(ids).getCheckedData();
return CollectionUtils.convertMap(list, DeptRespDTO::getId);
}
@GetMapping(PREFIX + "/list-child")
@Operation(summary = "获得指定部门的所有子部门")
@Parameter(name = "id", description = "部门编号", example = "1024", required = true)
CommonResult<List<DeptRespDTO>> getChildDeptList(@RequestParam("id") Long id);
@GetMapping(PREFIX + "/company-dept-info")
@Operation(summary = "获得指定用户的公司部门信息")
@Parameter(name = "userId", description = "用户编号", example = "1", required = true)
CommonResult<Set<CompanyDeptInfoRespDTO>> getCompanyDeptInfoListByUserId(@RequestParam("userId") Long userId);
}

View File

@@ -0,0 +1,67 @@
package com.zt.plat.module.system.api.dept;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.util.collection.CollectionUtils;
import com.zt.plat.module.system.api.dept.dto.PostRespDTO;
import com.zt.plat.module.system.api.dept.dto.PostSaveReqDTO;
import com.zt.plat.module.system.api.dept.dto.PostSimpleRespDTO;
import com.zt.plat.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 岗位")
public interface PostApi {
String PREFIX = ApiConstants.PREFIX + "/post";
// === 以下为补全的接口方法 ===
@PostMapping(PREFIX + "/create")
@Operation(summary = "新增岗位")
CommonResult<Long> createPost(@RequestBody PostSaveReqDTO createReqVO);
@PutMapping(PREFIX + "/update")
@Operation(summary = "修改岗位")
CommonResult<Boolean> updatePost(@RequestBody PostSaveReqDTO updateReqVO);
@DeleteMapping(PREFIX + "/delete")
@Operation(summary = "删除岗位")
CommonResult<Boolean> deletePost(@RequestParam("id") Long id);
@GetMapping(PREFIX + "/get")
@Operation(summary = "获得岗位详情")
CommonResult<PostRespDTO> getPost(@RequestParam("id") Long id);
@GetMapping(PREFIX + "/simple-list")
@Operation(summary = "获得岗位精简信息列表")
CommonResult<List<PostSimpleRespDTO>> getSimplePostList();
@GetMapping(PREFIX + "/valid")
@Operation(summary = "校验岗位是否合法")
@Parameter(name = "ids", description = "岗位编号数组", example = "1,2", required = true)
CommonResult<Boolean> validPostList(@RequestParam("ids") Collection<Long> ids);
@GetMapping(PREFIX + "/list")
@Operation(summary = "获得岗位列表")
@Parameter(name = "ids", description = "岗位编号数组", example = "1,2", required = true)
CommonResult<List<PostRespDTO>> getPostList(@RequestParam("ids") Collection<Long> ids);
default Map<Long, PostRespDTO> getPostMap(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return MapUtil.empty();
}
List<PostRespDTO> list = getPostList(ids).getData();
return CollectionUtils.convertMap(list, PostRespDTO::getId);
}
}

View File

@@ -0,0 +1,27 @@
package com.zt.plat.module.system.api.dept.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 公司部门信息 Response DTO
*
* @author ZT
*/
@Schema(description = "RPC 服务 - 公司部门信息 Response DTO")
@Data
public class CompanyDeptInfoRespDTO {
@Schema(description = "公司编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long companyId;
@Schema(description = "公司名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "ZT源码")
private String companyName;
@Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long deptId;
@Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "研发部")
private String deptName;
}

View File

@@ -0,0 +1,53 @@
package com.zt.plat.module.system.api.dept.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 部门信息 Response DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 部门信息 Response DTO")
@Data
public class DeptDetailRespDTO {
@Schema(description = "部门编号", example = "1024")
private Long id;
@Schema(description = "部门名称", example = "ZT")
private String name;
@Schema(description = "父部门 ID", example = "1024")
private Long parentId;
@Schema(description = "显示顺序", example = "1024")
private Integer sort;
@Schema(description = "负责人的用户编号", example = "2048")
private Long leaderUserId;
@Schema(description = "联系电话", example = "15601691000")
private String phone;
@Schema(description = "邮箱", example = "cloud@iocoder.cn")
private String email;
@Schema(description = "状态,见 CommonStatusEnum 枚举", example = "1")
private Integer status;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "租户编号", example = "1024")
private Long tenantId;
@Schema(description = "是否公司", example = "false")
private Boolean isCompany;
@Schema(description = "是否集团", example = "false")
private Boolean isGroup;
}

View File

@@ -0,0 +1,27 @@
package com.zt.plat.module.system.api.dept.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 部门列表 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 部门列表 Request DTO")
@Data
public class DeptListReqDTO {
@Schema(description = "部门名称,模糊匹配", example = "ZT")
private String name;
@Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
private Integer status;
@Schema(description = "是否公司", example = "false")
private Boolean isCompany;
@Schema(description = "是否集团", example = "false")
private Boolean isGroup;
}

View File

@@ -0,0 +1,34 @@
package com.zt.plat.module.system.api.dept.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "RPC 服务 - 部门 Response DTO")
@Data
public class DeptRespDTO {
@Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "研发部")
private String name;
@Schema(description = "部门编码", example = "XXXXXXX")
private String code;
@Schema(description = "父部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long parentId;
@Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long leaderUserId;
@Schema(description = "部门状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status; // 参见 CommonStatusEnum 枚举
@Schema(description = "是否公司", example = "false")
private Boolean isCompany;
@Schema(description = "是否集团", example = "false")
private Boolean isGroup;
}

View File

@@ -0,0 +1,39 @@
package com.zt.plat.module.system.api.dept.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 部门创建/修改 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 部门创建/修改 Request DTO")
@Data
public class DeptSaveReqDTO {
@Schema(description = "部门编号", example = "1024")
private Long id;
@Schema(description = "部门名称", example = "ZT")
private String name;
@Schema(description = "父部门 ID", example = "1024")
private Long parentId;
@Schema(description = "显示顺序", example = "1024")
private Integer sort;
@Schema(description = "负责人的用户编号", example = "2048")
private Long leaderUserId;
@Schema(description = "联系电话", example = "15601691000")
private String phone;
@Schema(description = "邮箱", example = "cloud@iocoder.cn")
private String email;
@Schema(description = "状态,见 CommonStatusEnum 枚举0 开启 1 关闭", example = "0")
private Integer status;
}

View File

@@ -0,0 +1,30 @@
package com.zt.plat.module.system.api.dept.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 部门精简信息 Response DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 部门精简信息 Response DTO")
@Data
public class DeptSimpleRespDTO {
@Schema(description = "部门编号", example = "1024")
private Long id;
@Schema(description = "部门名称", example = "ZT")
private String name;
@Schema(description = "父部门 ID", example = "1024")
private Long parentId;
@Schema(description = "是否公司", example = "false")
private Boolean isCompany;
@Schema(description = "是否集团", example = "false")
private Boolean isGroup;
}

View File

@@ -0,0 +1,27 @@
package com.zt.plat.module.system.api.dept.dto;
import com.zt.plat.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 岗位分页 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 岗位分页 Request DTO")
@Data
@EqualsAndHashCode(callSuper = true)
public class PostPageReqDTO extends PageParam {
@Schema(description = "岗位编码,模糊匹配", example = "cloud")
private String code;
@Schema(description = "岗位名称,模糊匹配", example = "ZT")
private String name;
@Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
private Integer status;
}

View File

@@ -0,0 +1,30 @@
package com.zt.plat.module.system.api.dept.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 岗位 Response DTO
*
* @author ZT
*/
@Schema(description = "RPC 服务 - 岗位 Response DTO")
@Data
public class PostRespDTO {
@Schema(description = "岗位编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "岗位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小土豆")
private String name;
@Schema(description = "岗位编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "cloud")
private String code;
@Schema(description = "岗位排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer sort;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status; // 参见 CommonStatusEnum 枚举
}

View File

@@ -0,0 +1,33 @@
package com.zt.plat.module.system.api.dept.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 岗位创建/修改 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 岗位创建/修改 Request DTO")
@Data
public class PostSaveReqDTO {
@Schema(description = "岗位编号", example = "1024")
private Long id;
@Schema(description = "岗位名称", example = "小土豆")
private String name;
@Schema(description = "岗位编码", example = "cloud")
private String code;
@Schema(description = "显示顺序", example = "1024")
private Integer sort;
@Schema(description = "状态", example = "1")
private Integer status;
@Schema(description = "备注", example = "快乐的备注")
private String remark;
}

View File

@@ -0,0 +1,21 @@
package com.zt.plat.module.system.api.dept.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 岗位信息的精简 Response DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 岗位信息的精简 Response DTO")
@Data
public class PostSimpleRespDTO {
@Schema(description = "岗位序号", example = "1024")
private Long id;
@Schema(description = "岗位名称", example = "小土豆")
private String name;
}

View File

@@ -0,0 +1,55 @@
package com.zt.plat.module.system.api.dict;
import com.zt.plat.framework.common.biz.system.dict.DictDataCommonApi;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.system.api.dict.dto.DictDataDetailRespDTO;
import com.zt.plat.module.system.api.dict.dto.DictDataSaveReqDTO;
import com.zt.plat.module.system.api.dict.dto.DictDataSimpleRespDTO;
import com.zt.plat.module.system.enums.ApiConstants;
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.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.List;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 字典数据")
public interface DictDataApi extends DictDataCommonApi {
String PREFIX = ApiConstants.PREFIX + "/dict-data";
// === 以下为补全的接口方法 ===
@PostMapping(PREFIX + "/create")
@Operation(summary = "新增字典数据")
CommonResult<Long> createDictData(@RequestBody DictDataSaveReqDTO createReqVO);
@PutMapping(PREFIX + "/update")
@Operation(summary = "修改字典数据")
CommonResult<Boolean> updateDictData(@RequestBody DictDataSaveReqDTO updateReqVO);
@DeleteMapping(PREFIX + "/delete")
@Operation(summary = "删除字典数据")
CommonResult<Boolean> deleteDictData(@RequestParam("id") Long id);
@GetMapping(PREFIX + "/simple-list")
@Operation(summary = "获得字典数据精简信息列表")
CommonResult<List<DictDataSimpleRespDTO>> getSimpleDictDataList();
@GetMapping(PREFIX + "/get")
@Operation(summary = "获得字典数据详情")
CommonResult<DictDataDetailRespDTO> getDictData(@RequestParam("id") Long id);
@GetMapping(PREFIX + "/valid")
@Operation(summary = "校验字典数据们是否有效")
@Parameters({
@Parameter(name = "dictType", description = "字典类型", example = "SEX", required = true),
@Parameter(name = "descriptions", description = "字典数据值的数组", example = "1,2", required = true)
})
CommonResult<Boolean> validateDictDataList(@RequestParam("dictType") String dictType,
@RequestParam("values") Collection<String> values);
}

View File

@@ -0,0 +1,47 @@
package com.zt.plat.module.system.api.dict.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 字典数据信息 Response DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 字典数据信息 Response DTO")
@Data
public class DictDataDetailRespDTO {
@Schema(description = "字典数据编号", example = "1024")
private Long id;
@Schema(description = "显示顺序", example = "1")
private Integer sort;
@Schema(description = "字典标签", example = "")
private String label;
@Schema(description = "字典值", example = "1")
private String value;
@Schema(description = "字典类型", example = "gender")
private String dictType;
@Schema(description = "状态", example = "1")
private Integer status;
@Schema(description = "颜色类型", example = "primary")
private String colorType;
@Schema(description = "css 样式", example = "color: red")
private String cssClass;
@Schema(description = "备注", example = "我是一个角色")
private String remark;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,27 @@
package com.zt.plat.module.system.api.dict.dto;
import com.zt.plat.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 字典数据分页 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 字典数据分页 Request DTO")
@Data
@EqualsAndHashCode(callSuper = true)
public class DictDataPageReqDTO extends PageParam {
@Schema(description = "字典标签", example = "ZT")
private String label;
@Schema(description = "字典类型,模糊匹配", example = "sys_common_sex")
private String dictType;
@Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
private Integer status;
}

View File

@@ -0,0 +1,42 @@
package com.zt.plat.module.system.api.dict.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 字典数据创建/修改 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 字典数据创建/修改 Request DTO")
@Data
public class DictDataSaveReqDTO {
@Schema(description = "字典数据编号", example = "1024")
private Long id;
@Schema(description = "显示顺序", example = "1")
private Integer sort;
@Schema(description = "字典标签", example = "")
private String label;
@Schema(description = "字典值", example = "1")
private String value;
@Schema(description = "字典类型", example = "gender")
private String dictType;
@Schema(description = "状态", example = "1")
private Integer status;
@Schema(description = "颜色类型", example = "primary")
private String colorType;
@Schema(description = "css 样式", example = "color: red")
private String cssClass;
@Schema(description = "备注", example = "我是一个角色")
private String remark;
}

View File

@@ -0,0 +1,30 @@
package com.zt.plat.module.system.api.dict.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 字典数据精简信息 Response DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 字典数据精简信息 Response DTO")
@Data
public class DictDataSimpleRespDTO {
@Schema(description = "字典数据编号", example = "1024")
private Long id;
@Schema(description = "字典标签", example = "")
private String label;
@Schema(description = "字典值", example = "1")
private String value;
@Schema(description = "字典类型", example = "gender")
private String dictType;
@Schema(description = "状态", example = "1")
private Integer status;
}

View File

@@ -0,0 +1,24 @@
package com.zt.plat.module.system.api.logger;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.system.api.logger.dto.LoginLogCreateReqDTO;
import com.zt.plat.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import jakarta.validation.Valid;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 登录日志")
public interface LoginLogApi {
String PREFIX = ApiConstants.PREFIX + "/login-log";
@PostMapping(PREFIX + "/create")
@Operation(summary = "创建登录日志")
CommonResult<Boolean> createLoginLog(@Valid @RequestBody LoginLogCreateReqDTO reqDTO);
}

View File

@@ -0,0 +1,25 @@
package com.zt.plat.module.system.api.logger;
import com.zt.plat.framework.common.biz.system.logger.OperateLogCommonApi;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.module.system.api.logger.dto.OperateLogPageReqDTO;
import com.zt.plat.module.system.api.logger.dto.OperateLogRespDTO;
import com.zt.plat.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 操作日志")
public interface OperateLogApi extends OperateLogCommonApi {
String PREFIX = ApiConstants.PREFIX + "/operate-log";
@PostMapping(PREFIX + "/page")
@Operation(summary = "获取指定模块的指定数据的操作日志分页")
CommonResult<PageResult<OperateLogRespDTO>> getOperateLogPage(@RequestBody OperateLogPageReqDTO pageReqDTO);
}

View File

@@ -0,0 +1,40 @@
package com.zt.plat.module.system.api.logger.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
@Schema(description = "RPC 服务 - 登录日志创建 Request DTO")
@Data
public class LoginLogCreateReqDTO {
@Schema(description = "日志类型,参见 LoginLogTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1" )
@NotNull(message = "日志类型不能为空")
private Integer logType;
@Schema(description = "链路追踪编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "89aca178-a370-411c-ae02-3f0d672be4ab")
private String traceId;
@Schema(description = "用户编号", example = "666")
private Long userId;
@Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2" )
@NotNull(message = "用户类型不能为空")
private Integer userType;
@Schema(description = "用户账号", example = "cloud")
@Size(max = 30, message = "用户账号长度不能超过30个字符")
private String username; // 不再强制校验 username 非空,因为 Member 社交登录时,此时暂时没有 username(mobile
@Schema(description = "登录结果,参见 LoginResultEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "登录结果不能为空")
private Integer result;
@Schema(description = "用户 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "127.0.0.1")
@NotEmpty(message = "用户 IP 不能为空")
private String userIp;
@Schema(description = "浏览器 UserAgent", requiredMode = Schema.RequiredMode.REQUIRED, example = "Mozilla/5.0")
private String userAgent;
}

View File

@@ -0,0 +1,20 @@
package com.zt.plat.module.system.api.logger.dto;
import com.zt.plat.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(name = "RPC 服务 - 操作日志分页 Request DTO")
@Data
public class OperateLogPageReqDTO extends PageParam {
@Schema(description = "模块类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "订单")
private String type;
@Schema(description = "模块数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "188")
private Long bizId;
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "666")
private Long userId;
}

View File

@@ -0,0 +1,52 @@
package com.zt.plat.module.system.api.logger.dto;
import com.zt.plat.module.system.api.user.AdminUserApi;
import com.fhs.core.trans.anno.Trans;
import com.fhs.core.trans.constant.TransType;
import com.fhs.core.trans.vo.VO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(name = "RPC 服务 - 系统操作日志 Response DTO")
@Data
public class OperateLogRespDTO implements VO {
@Schema(description = "日志编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "链路追踪编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "89aca178-a370-411c-ae02-3f0d672be4ab")
private String traceId;
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "666")
@Trans(type = TransType.AUTO_TRANS, key = AdminUserApi.PREFIX, fields = "nickname", ref = "userName")
private Long userId;
@Schema(description = "用户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "ZT")
private String userName;
@Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2" )
private Integer userType;
@Schema(description = "操作模块类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "订单")
private String type;
@Schema(description = "操作名", requiredMode = Schema.RequiredMode.REQUIRED, example = "创建订单")
private String subType;
@Schema(description = "操作模块业务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "188")
private Long bizId;
@Schema(description = "操作内容", requiredMode = Schema.RequiredMode.REQUIRED,
example = "修改编号为 1 的用户信息将性别从男改成女将姓名从ZT改成源码")
private String action;
@Schema(description = "拓展字段", example = "{\"orderId\": \"1\"}")
private String extra;
@Schema(description = "请求方法名", requiredMode = Schema.RequiredMode.REQUIRED, example = "GET")
private String requestMethod;
@Schema(description = "请求地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "/order/get")
private String requestUrl;
@Schema(description = "用户 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "127.0.0.1")
private String userIp;
@Schema(description = "浏览器 UserAgent", requiredMode = Schema.RequiredMode.REQUIRED, example = "Mozilla/5.0")
private String userAgent;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,28 @@
package com.zt.plat.module.system.api.mail;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.system.api.mail.dto.MailSendSingleToUserReqDTO;
import com.zt.plat.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 邮件发送")
public interface MailSendApi {
String PREFIX = ApiConstants.PREFIX + "/mail/send";
@PostMapping(PREFIX + "/send-single-admin")
@Operation(summary = "发送单条邮件给 Admin 用户", description = "在 mail 为空时,使用 userId 加载对应 Admin 的邮箱")
CommonResult<Long> sendSingleMailToAdmin(@Valid @RequestBody MailSendSingleToUserReqDTO reqDTO);
@PostMapping(PREFIX + "/send-single-member")
@Operation(summary = "发送单条邮件给 Member 用户", description = "在 mail 为空时,使用 userId 加载对应 Member 的邮箱")
CommonResult<Long> sendSingleMailToMember(@Valid @RequestBody MailSendSingleToUserReqDTO reqDTO);
}

View File

@@ -0,0 +1,27 @@
package com.zt.plat.module.system.api.mail.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotNull;
import java.util.Map;
@Schema(description = "RPC 服务 - 邮件发送给 Admin 或者 Member 用户 Request DTO")
@Data
public class MailSendSingleToUserReqDTO {
@Schema(description = "用户编号", example = "1024")
private Long userId;
@Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
@Email
private String mail;
@Schema(description = "邮件模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "USER_SEND")
@NotNull(message = "邮件模板编号不能为空")
private String templateCode;
@Schema(description = "邮件模板参数")
private Map<String, Object> templateParams;
}

View File

@@ -0,0 +1,28 @@
package com.zt.plat.module.system.api.notify;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
import com.zt.plat.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 站内信发送")
public interface NotifyMessageSendApi {
String PREFIX = ApiConstants.PREFIX + "/notify/send";
@PostMapping(PREFIX + "/send-single-admin")
@Operation(summary = "发送单条站内信给 Admin 用户")
CommonResult<Long> sendSingleMessageToAdmin(@Valid @RequestBody NotifySendSingleToUserReqDTO reqDTO);
@PostMapping(PREFIX + "/send-single-member")
@Operation(summary = "发送单条站内信给 Member 用户")
CommonResult<Long> sendSingleMessageToMember(@Valid @RequestBody NotifySendSingleToUserReqDTO reqDTO);
}

View File

@@ -0,0 +1,23 @@
package com.zt.plat.module.system.api.notify.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.util.Map;
@Schema(description = "RPC 服务 - 站内信发送给 Admin 或者 Member 用户 Request DTO")
@Data
public class NotifySendSingleToUserReqDTO {
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "用户编号不能为空")
private Long userId;
@Schema(description = "站内信模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "USER_SEND")
@NotEmpty(message = "站内信模板编号不能为空")
private String templateCode;
@Schema(description = "邮件模板参数")
private Map<String, Object> templateParams;
}

View File

@@ -0,0 +1,4 @@
/**
* System API 包,定义暴露给其它模块的 API
*/
package com.zt.plat.module.system.api;

View File

@@ -0,0 +1,53 @@
package com.zt.plat.module.system.api.permission;
import com.zt.plat.framework.common.biz.system.permission.PermissionCommonApi;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.system.api.permission.dto.*;
import com.zt.plat.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.Set;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 权限")
public interface PermissionApi extends PermissionCommonApi {
String PREFIX = ApiConstants.PREFIX + "/permission";
// === 以下为补全的接口方法 ===
@GetMapping(PREFIX + "/role-menu-list")
@Operation(summary = "获得角色拥有的菜单编号集合")
CommonResult<Set<Long>> getRoleMenuList(@RequestParam("roleId") Long roleId);
@PostMapping(PREFIX + "/assign-role-menu")
@Operation(summary = "分配角色菜单")
CommonResult<Boolean> assignRoleMenu(@RequestBody PermissionAssignRoleMenuReqDTO reqVO);
@PostMapping(PREFIX + "/assign-role-data-scope")
@Operation(summary = "分配角色数据权限")
CommonResult<Boolean> assignRoleDataScope(@RequestBody PermissionAssignRoleDataScopeReqDTO reqVO);
@GetMapping(PREFIX + "/admin-roles")
@Operation(summary = "获得管理员拥有的角色编号集合")
CommonResult<Set<Long>> listAdminRoles(@RequestParam("userId") Long userId);
@PostMapping(PREFIX + "/assign-user-role")
@Operation(summary = "分配用户角色")
CommonResult<Boolean> assignUserRole(@RequestBody PermissionAssignUserRoleReqDTO reqVO);
@GetMapping(PREFIX + "/user-role-id-list-by-role-id")
@Operation(summary = "获得拥有多个角色的用户编号集合")
@Parameter(name = "roleIds", description = "角色编号集合", example = "1,2", required = true)
CommonResult<Set<Long>> getUserRoleIdListByRoleIds(@RequestParam("roleIds") Collection<Long> roleIds);
@GetMapping(PREFIX + "/user-role-id-list-by-user-id")
@Operation(summary = "获得用户拥有的角色编号集合")
@Parameter(name = "userId", description = "用户编号", example = "1", required = true)
CommonResult<Set<Long>> getUserRoleIdListByUserId(@RequestParam("userId") Long userId);
}

View File

@@ -0,0 +1,30 @@
package com.zt.plat.module.system.api.permission;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Collection;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 角色")
public interface RoleApi {
String PREFIX = ApiConstants.PREFIX + "/role";
@GetMapping(PREFIX + "/valid")
@Operation(summary = "校验角色是否合法")
@Parameter(name = "ids", description = "角色编号数组", example = "1,2", required = true)
CommonResult<Boolean> validRoleList(@RequestParam("ids") Collection<Long> ids);
@GetMapping(PREFIX + "/has-any-super-admin")
@Operation(summary = "判断角色列表中是否有超级管理员")
@Parameter(name = "roleIds", description = "角色编号集合", example = "1,2", required = true)
CommonResult<Boolean> hasAnySuperAdmin(@RequestParam("roleIds") Collection<Long> roleIds);
}

View File

@@ -0,0 +1,26 @@
package com.zt.plat.module.system.api.permission.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Set;
/**
* 权限分配角色数据权限 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 权限分配角色数据权限 Request DTO")
@Data
public class PermissionAssignRoleDataScopeReqDTO {
@Schema(description = "角色编号", example = "1")
private Long roleId;
@Schema(description = "数据范围", example = "1")
private Integer dataScope;
@Schema(description = "部门编号数组", example = "1,3,5")
private Set<Long> dataScopeDeptIds;
}

View File

@@ -0,0 +1,23 @@
package com.zt.plat.module.system.api.permission.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Set;
/**
* 权限分配角色菜单 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 权限分配角色菜单 Request DTO")
@Data
public class PermissionAssignRoleMenuReqDTO {
@Schema(description = "角色编号", example = "1")
private Long roleId;
@Schema(description = "菜单编号列表", example = "1,3,5")
private Set<Long> menuIds;
}

View File

@@ -0,0 +1,23 @@
package com.zt.plat.module.system.api.permission.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Set;
/**
* 权限分配用户角色 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 权限分配用户角色 Request DTO")
@Data
public class PermissionAssignUserRoleReqDTO {
@Schema(description = "用户编号", example = "1")
private Long userId;
@Schema(description = "角色编号数组", example = "1,3,5")
private Set<Long> roleIds;
}

View File

@@ -0,0 +1,48 @@
package com.zt.plat.module.system.api.permission.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Set;
/**
* 角色信息 Response DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 角色信息 Response DTO")
@Data
public class RoleDetailRespDTO {
@Schema(description = "角色编号", example = "1024")
private Long id;
@Schema(description = "角色名称", example = "管理员")
private String name;
@Schema(description = "角色标识", example = "admin")
private String code;
@Schema(description = "显示顺序", example = "1024")
private Integer sort;
@Schema(description = "数据范围", example = "1")
private Integer dataScope;
@Schema(description = "数据范围(指定部门数组)", example = "1,2,3")
private Set<Long> dataScopeDeptIds;
@Schema(description = "角色状态", example = "1")
private Integer status;
@Schema(description = "角色类型", example = "1")
private Integer type;
@Schema(description = "备注", example = "我是一个角色")
private String remark;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,32 @@
package com.zt.plat.module.system.api.permission.dto;
import com.zt.plat.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* 角色分页 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 角色分页 Request DTO")
@Data
@EqualsAndHashCode(callSuper = true)
public class RolePageReqDTO extends PageParam {
@Schema(description = "角色名称,模糊匹配", example = "ZT")
private String name;
@Schema(description = "角色标识,模糊匹配", example = "admin")
private String code;
@Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
private Integer status;
@Schema(description = "创建时间")
private LocalDateTime[] createTime;
}

View File

@@ -0,0 +1,44 @@
package com.zt.plat.module.system.api.permission.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Set;
/**
* 角色创建/修改 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 角色创建/修改 Request DTO")
@Data
public class RoleSaveReqDTO {
@Schema(description = "角色编号", example = "1024")
private Long id;
@Schema(description = "角色名称", example = "管理员")
private String name;
@Schema(description = "角色标识", example = "admin")
private String code;
@Schema(description = "显示顺序", example = "1024")
private Integer sort;
@Schema(description = "数据范围", example = "1")
private Integer dataScope;
@Schema(description = "数据范围(指定部门数组)", example = "1,2,3")
private Set<Long> dataScopeDeptIds;
@Schema(description = "角色状态", example = "1")
private Integer status;
@Schema(description = "角色类型", example = "1")
private Integer type;
@Schema(description = "备注", example = "我是一个角色")
private String remark;
}

View File

@@ -0,0 +1,30 @@
package com.zt.plat.module.system.api.sequence;
import com.zt.plat.framework.common.biz.system.sequence.SequenceCommonApi;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* @author chenbowen
*/
@FeignClient(name = ApiConstants.NAME, primary = false) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 序列号")
public interface SequenceApi extends SequenceCommonApi {
String PREFIX = ApiConstants.PREFIX + "/sequence";
@PostMapping(PREFIX + "/next-sequence")
@Operation(summary = "获取下一个序列号")
@Override
CommonResult<String> getNextSequence(@RequestParam("sequenceCode") String sequenceCode,
@RequestParam(value = "circulationValue", required = false) String circulationValue,
@RequestParam(value = "inputStrs", required = false) List<String> inputStrs);
}

View File

@@ -0,0 +1,36 @@
package com.zt.plat.module.system.api.sms;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.system.api.sms.dto.code.SmsCodeValidateReqDTO;
import com.zt.plat.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
import com.zt.plat.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
import com.zt.plat.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import jakarta.validation.Valid;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 短信验证码")
public interface SmsCodeApi {
String PREFIX = ApiConstants.PREFIX + "/oauth2/sms/code";
@PostMapping(PREFIX + "/send")
@Operation(summary = "创建短信验证码,并进行发送")
CommonResult<Boolean> sendSmsCode(@Valid @RequestBody SmsCodeSendReqDTO reqDTO);
@PutMapping(PREFIX + "/use")
@Operation(summary = "验证短信验证码,并进行使用")
CommonResult<Boolean> useSmsCode(@Valid @RequestBody SmsCodeUseReqDTO reqDTO);
@PostMapping(PREFIX + "/validate")
@Operation(summary = "检查验证码是否有效")
CommonResult<Boolean> validateSmsCode(@Valid @RequestBody SmsCodeValidateReqDTO reqDTO);
}

View File

@@ -0,0 +1,28 @@
package com.zt.plat.module.system.api.sms;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO;
import com.zt.plat.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import jakarta.validation.Valid;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 短信发送")
public interface SmsSendApi {
String PREFIX = ApiConstants.PREFIX + "/sms/send";
@PostMapping(PREFIX + "/send-single-admin")
@Operation(summary = "发送单条短信给 Admin 用户", description = "在 mobile 为空时,使用 userId 加载对应 Admin 的手机号")
CommonResult<Long> sendSingleSmsToAdmin(@Valid @RequestBody SmsSendSingleToUserReqDTO reqDTO);
@PostMapping(PREFIX + "/send-single-member")
@Operation(summary = "发送单条短信给 Member 用户", description = "在 mobile 为空时,使用 userId 加载对应 Member 的手机号")
CommonResult<Long> sendSingleSmsToMember(@Valid @RequestBody SmsSendSingleToUserReqDTO reqDTO);
}

View File

@@ -0,0 +1,30 @@
package com.zt.plat.module.system.api.sms.dto.code;
import com.zt.plat.framework.common.validation.InEnum;
import com.zt.plat.framework.common.validation.Mobile;
import com.zt.plat.module.system.enums.sms.SmsSceneEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
@Schema(description = "RPC 服务 - 短信验证码的发送 Request DTO")
@Data
public class SmsCodeSendReqDTO {
@Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
@Mobile
@NotEmpty(message = "手机号不能为空")
private String mobile;
@Schema(description = "发送场景", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "发送场景不能为空")
@InEnum(SmsSceneEnum.class)
private Integer scene;
@Schema(description = "发送 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "10.20.30.40")
@NotEmpty(message = "发送 IP 不能为空")
private String createIp;
}

View File

@@ -0,0 +1,34 @@
package com.zt.plat.module.system.api.sms.dto.code;
import com.zt.plat.framework.common.validation.InEnum;
import com.zt.plat.framework.common.validation.Mobile;
import com.zt.plat.module.system.enums.sms.SmsSceneEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
@Schema(description = "RPC 服务 - 短信验证码的使用 Request DTO")
@Data
public class SmsCodeUseReqDTO {
@Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
@Mobile
@NotEmpty(message = "手机号不能为空")
private String mobile;
@Schema(description = "发送场景", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "发送场景不能为空")
@InEnum(SmsSceneEnum.class)
private Integer scene;
@Schema(description = "验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotEmpty(message = "验证码")
private String code;
@Schema(description = "发送 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "10.20.30.40")
@NotEmpty(message = "使用 IP 不能为空")
private String usedIp;
}

View File

@@ -0,0 +1,30 @@
package com.zt.plat.module.system.api.sms.dto.code;
import com.zt.plat.framework.common.validation.InEnum;
import com.zt.plat.framework.common.validation.Mobile;
import com.zt.plat.module.system.enums.sms.SmsSceneEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
@Schema(description = "RPC 服务 - 短信验证码的校验 Request DTO")
@Data
public class SmsCodeValidateReqDTO {
@Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
@Mobile
@NotEmpty(message = "手机号不能为空")
private String mobile;
@Schema(description = "发送场景", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "发送场景不能为空")
@InEnum(SmsSceneEnum.class)
private Integer scene;
@Schema(description = "验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotEmpty(message = "验证码")
private String code;
}

View File

@@ -0,0 +1,26 @@
package com.zt.plat.module.system.api.sms.dto.send;
import com.zt.plat.framework.common.validation.Mobile;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotEmpty;
import java.util.Map;
@Schema(description = "RPC 服务 - 短信发送给 Admin 或者 Member 用户 Request DTO")
@Data
public class SmsSendSingleToUserReqDTO {
@Schema(description = "用户编号", example = "1024")
private Long userId;
@Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
@Mobile
private String mobile;
@Schema(description = "短信模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "USER_SEND")
@NotEmpty(message = "短信模板编号不能为空")
private String templateCode;
@Schema(description = "短信模板参数")
private Map<String, Object> templateParams;
}

View File

@@ -0,0 +1,83 @@
package com.zt.plat.module.system.api.social;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.system.api.social.dto.*;
import com.zt.plat.module.system.enums.ApiConstants;
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.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 社交应用")
public interface SocialClientApi {
String PREFIX = ApiConstants.PREFIX + "/social-client";
@GetMapping(PREFIX + "/get-authorize-url")
@Operation(summary = "获得社交平台的授权 URL")
@Parameters({
@Parameter(name = "socialType", description = "社交平台的类型", example = "1", required = true),
@Parameter(name = "userType", description = "用户类型", example = "1", required = true),
@Parameter(name = "redirectUri", description = "重定向 URL", example = "https://www.iocoder.cn", required = true)
})
CommonResult<String> getAuthorizeUrl(@RequestParam("socialType") Integer socialType,
@RequestParam("userType") Integer userType,
@RequestParam("redirectUri") String redirectUri);
@GetMapping(PREFIX + "/create-wx-mp-jsapi-signature")
@Operation(summary = "创建微信公众号 JS SDK 初始化所需的签名")
@Parameters({
@Parameter(name = "userType", description = "用户类型", example = "1", required = true),
@Parameter(name = "url", description = "访问 URL", example = "https://www.iocoder.cn", required = true)
})
CommonResult<SocialWxJsapiSignatureRespDTO> createWxMpJsapiSignature(@RequestParam("userType") Integer userType,
@RequestParam("url") String url);
@GetMapping(PREFIX + "/create-wx-ma-phone-number-info")
@Operation(summary = "获得微信小程序的手机信息")
@Parameters({
@Parameter(name = "userType", description = "用户类型", example = "1", required = true),
@Parameter(name = "phoneCode", description = "手机授权码", example = "cloud11", required = true)
})
CommonResult<SocialWxPhoneNumberInfoRespDTO> getWxMaPhoneNumberInfo(@RequestParam("userType") Integer userType,
@RequestParam("phoneCode") String phoneCode);
@PostMapping(PREFIX + "/get-wxa-qrcode")
@Operation(summary = "获得小程序二维码")
CommonResult<byte[]> getWxaQrcode(@RequestBody SocialWxQrcodeReqDTO reqVO);
@GetMapping(PREFIX + "/get-wxa-subscribe-template-list")
@Operation(summary = "获得微信小程订阅模板")
CommonResult<List<SocialWxaSubscribeTemplateRespDTO>> getWxaSubscribeTemplateList(@RequestParam("userType") Integer userType);
@PostMapping(PREFIX + "/send-wxa-subscribe-message")
@Operation(summary = "发送微信小程序订阅消息")
CommonResult<Boolean> sendWxaSubscribeMessage(@Valid @RequestBody SocialWxaSubscribeMessageSendReqDTO reqDTO);
/**
* 上传订单发货到微信小程序
*
* @param userType 用户类型
* @param reqDTO 请求
*/
@PostMapping(PREFIX + "/upload-wxa-order-shipping-info")
@Operation(summary = "上传订单发货到微信小程序")
CommonResult<Boolean> uploadWxaOrderShippingInfo(@RequestParam("userType") Integer userType,
@Valid @RequestBody SocialWxaOrderUploadShippingInfoReqDTO reqDTO);
@PostMapping(PREFIX + "/notify-wxa-order-confirm-receive")
@Operation(summary = "通知订单收货到微信小程序")
CommonResult<Boolean> notifyWxaOrderConfirmReceive(@RequestParam("userType") Integer userType,
@Valid @RequestBody SocialWxaOrderNotifyConfirmReceiveReqDTO reqDTO);
}

View File

@@ -0,0 +1,56 @@
package com.zt.plat.module.system.api.social;
import com.zt.plat.framework.common.exception.ServiceException;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.system.api.social.dto.SocialUserBindReqDTO;
import com.zt.plat.module.system.api.social.dto.SocialUserRespDTO;
import com.zt.plat.module.system.api.social.dto.SocialUserUnbindReqDTO;
import com.zt.plat.module.system.enums.ApiConstants;
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.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 社交用户")
public interface SocialUserApi {
String PREFIX = ApiConstants.PREFIX + "/social-user";
@PostMapping(PREFIX + "/bind")
@Operation(summary = "绑定社交用户")
CommonResult<String> bindSocialUser(@Valid @RequestBody SocialUserBindReqDTO reqDTO);
@DeleteMapping(PREFIX + "/unbind")
@Operation(summary = "取消绑定社交用户")
CommonResult<Boolean> unbindSocialUser(@Valid @RequestBody SocialUserUnbindReqDTO reqDTO);
@GetMapping(PREFIX + "/get-by-user-id")
@Operation(summary = "获得社交用户,基于 userId")
@Parameters({
@Parameter(name = "userType", description = "用户类型", example = "2", required = true),
@Parameter(name = "userId", description = "用户编号", example = "1024", required = true),
@Parameter(name = "socialType", description = "社交平台的类型", example = "1", required = true),
})
CommonResult<SocialUserRespDTO> getSocialUserByUserId(@RequestParam("userType") Integer userType,
@RequestParam("userId") Long userId,
@RequestParam("socialType") Integer socialType);
@GetMapping(PREFIX + "/get-by-code")
@Operation(summary = "获得社交用") // 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常
@Parameters({
@Parameter(name = "userType", description = "用户类型", example = "2", required = true),
@Parameter(name = "socialType", description = "社交平台的类型", example = "1", required = true),
@Parameter(name = "code", description = "授权码", example = "88888", required = true),
@Parameter(name = "state", description = "state", example = "666", required = true),
})
CommonResult<SocialUserRespDTO> getSocialUserByCode(@RequestParam("userType") Integer userType,
@RequestParam("socialType") Integer socialType,
@RequestParam("code") String code,
@RequestParam("state") String state);
}

View File

@@ -0,0 +1,33 @@
package com.zt.plat.module.system.api.social.dto;
import com.zt.plat.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 社交客户端分页 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 社交客户端分页 Request DTO")
@Data
@EqualsAndHashCode(callSuper = true)
public class SocialClientPageReqDTO extends PageParam {
@Schema(description = "应用名,模糊匹配", example = "cloud")
private String name;
@Schema(description = "社交平台的类型", example = "1")
private Integer socialType;
@Schema(description = "用户类型", example = "2")
private Integer userType;
@Schema(description = "客户端编号", example = "wx12345")
private String clientId;
@Schema(description = "状态", example = "1")
private Integer status;
}

View File

@@ -0,0 +1,44 @@
package com.zt.plat.module.system.api.social.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 社交客户端信息 Response DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 社交客户端信息 Response DTO")
@Data
public class SocialClientRespDTO {
@Schema(description = "编号", example = "27162")
private Long id;
@Schema(description = "应用名", example = "cloud商城")
private String name;
@Schema(description = "社交平台的类型", example = "31")
private Integer socialType;
@Schema(description = "用户类型", example = "2")
private Integer userType;
@Schema(description = "客户端编号", example = "wwd411c69a39ad2e54")
private String clientId;
@Schema(description = "客户端密钥", example = "peter")
private String clientSecret;
@Schema(description = "授权方的网页应用编号", example = "2000045")
private String agentId;
@Schema(description = "状态", example = "1")
private Integer status;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,39 @@
package com.zt.plat.module.system.api.social.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 社交客户端创建/修改 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 社交客户端创建/修改 Request DTO")
@Data
public class SocialClientSaveReqDTO {
@Schema(description = "编号", example = "27162")
private Long id;
@Schema(description = "应用名", example = "cloud商城")
private String name;
@Schema(description = "社交平台的类型", example = "31")
private Integer socialType;
@Schema(description = "用户类型", example = "2")
private Integer userType;
@Schema(description = "客户端编号", example = "wwd411c69a39ad2e54")
private String clientId;
@Schema(description = "客户端密钥", example = "peter")
private String clientSecret;
@Schema(description = "授权方的网页应用编号", example = "2000045")
private String agentId;
@Schema(description = "状态", example = "1")
private Integer status;
}

View File

@@ -0,0 +1,39 @@
package com.zt.plat.module.system.api.social.dto;
import com.zt.plat.framework.common.enums.UserTypeEnum;
import com.zt.plat.framework.common.validation.InEnum;
import com.zt.plat.module.system.enums.social.SocialTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
@Schema(description = "RPC 服务 - 取消绑定社交用户 Request DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SocialUserBindReqDTO {
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "用户编号不能为空")
private Long userId;
@Schema(description = "用户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@InEnum(UserTypeEnum.class)
@NotNull(message = "用户类型不能为空")
private Integer userType;
@Schema(description = "社交平台的类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@InEnum(SocialTypeEnum.class)
@NotNull(message = "社交平台的类型不能为空")
private Integer socialType;
@Schema(description = "授权码", requiredMode = Schema.RequiredMode.REQUIRED, example = "zsw")
@NotEmpty(message = "授权码不能为空")
private String code;
@Schema(description = "state", requiredMode = Schema.RequiredMode.REQUIRED, example = "qtw")
@NotEmpty(message = "state 不能为空")
private String state;
}

View File

@@ -0,0 +1,26 @@
package com.zt.plat.module.system.api.social.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Schema(description = "RPC 服务 - 社交用户 Response DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SocialUserRespDTO {
@Schema(description = "社交用户 openid", requiredMode = Schema.RequiredMode.REQUIRED, example = "zsw")
private String openid;
@Schema(description = "社交用户的昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "ZT源码")
private String nickname;
@Schema(description = "社交用户的头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.jpg")
private String avatar;
@Schema(description = "关联的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long userId;
}

View File

@@ -0,0 +1,36 @@
package com.zt.plat.module.system.api.social.dto;
import com.zt.plat.framework.common.enums.UserTypeEnum;
import com.zt.plat.framework.common.validation.InEnum;
import com.zt.plat.module.system.enums.social.SocialTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.NoArgsConstructor;
@Schema(description = "RPC 服务 - 取消绑定社交用户 Request DTO")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SocialUserUnbindReqDTO {
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "用户编号不能为空")
private Long userId;
@Schema(description = "用户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@InEnum(UserTypeEnum.class)
@NotNull(message = "用户类型不能为空")
private Integer userType;
@Schema(description = "社交平台的类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@InEnum(SocialTypeEnum.class)
@NotNull(message = "社交平台的类型不能为空")
private Integer socialType;
@Schema(description = "社交平台的 openid", requiredMode = Schema.RequiredMode.REQUIRED, example = "zsw")
@NotEmpty(message = "社交平台的 openid 不能为空")
private String openid;
}

View File

@@ -0,0 +1,25 @@
package com.zt.plat.module.system.api.social.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "RPC 服务 - 微信公众号 JSAPI 签名 Response DTO")
@Data
public class SocialWxJsapiSignatureRespDTO {
@Schema(description = "微信公众号的 appId", requiredMode = Schema.RequiredMode.REQUIRED, example = "wx123456")
private String appId;
@Schema(description = "匿名串", requiredMode = Schema.RequiredMode.REQUIRED, example = "zsw")
private String nonceStr;
@Schema(description = "时间戳", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456789")
private Long timestamp;
@Schema(description = "URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
private String url;
@Schema(description = "签名", requiredMode = Schema.RequiredMode.REQUIRED, example = "zsw")
private String signature;
}

View File

@@ -0,0 +1,18 @@
package com.zt.plat.module.system.api.social.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "RPC 服务 - 微信小程序的手机信息 Response DTO")
@Data
public class SocialWxPhoneNumberInfoRespDTO {
@Schema(description = "用户绑定的手机号(国外手机号会有区号)", requiredMode = Schema.RequiredMode.REQUIRED, example = "021-13579246810")
private String phoneNumber;
@Schema(description = "没有区号的手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13579246810")
private String purePhoneNumber;
@Schema(description = "区号", requiredMode = Schema.RequiredMode.REQUIRED, example = "021")
private String countryCode;
}

View File

@@ -0,0 +1,57 @@
package com.zt.plat.module.system.api.social.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
/**
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getUnlimitedQRCode.html">获取不限制的小程序码</a>
*/
@Schema(description = "RPC 服务 - 获得获取小程序码 Request DTO")
@Data
public class SocialWxQrcodeReqDTO {
/**
* 页面路径不能携带参数参数请放在scene字段里
*/
public static final String SCENE = "";
/**
* 二维码宽度
*/
public static final Integer WIDTH = 430;
/**
* 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调
*/
public static final Boolean AUTO_COLOR = true;
/**
* 检查 page 是否存在
*/
public static final Boolean CHECK_PATH = true;
/**
* 是否需要透明底色
*
* hyaline 为 true 时,生成透明底色的小程序码
*/
public static final Boolean HYALINE = true;
@Schema(description = "场景", requiredMode = Schema.RequiredMode.REQUIRED, example = "1001")
@NotEmpty(message = "场景不能为空")
private String scene;
@Schema(description = "页面路径", requiredMode = Schema.RequiredMode.REQUIRED, example = "pages/goods/index")
@NotEmpty(message = "页面路径不能为空")
private String path;
@Schema(description = "二维码宽度", example = "430")
private Integer width;
@Schema(description = "是否需要透明底色", example = "true")
private Boolean autoColor;
@Schema(description = "是否检查 page 是否存在", example = "true")
private Boolean checkPath;
@Schema(description = "是否需要透明底色", example = "true")
private Boolean hyaline;
}

View File

@@ -0,0 +1,30 @@
package com.zt.plat.module.system.api.social.dto;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 小程序订单上传购物详情
*
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/shopping-order/normal-shopping-detail/uploadShoppingInfo.html">上传购物详情</a>
* @author ZT
*/
@Data
public class SocialWxaOrderNotifyConfirmReceiveReqDTO {
/**
* 原支付交易对应的微信订单号
*/
@NotEmpty(message = "原支付交易对应的微信订单号不能为空")
private String transactionId;
/**
* 快递签收时间
*/
@NotNull(message = "快递签收时间不能为空")
private LocalDateTime receivedTime;
}

View File

@@ -0,0 +1,67 @@
package com.zt.plat.module.system.api.social.dto;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* 小程序订单上传购物详情
*
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/shopping-order/normal-shopping-detail/uploadShoppingInfo.html">上传购物详情</a>
* @author ZT
*/
@Data
public class SocialWxaOrderUploadShippingInfoReqDTO {
/**
* 物流模式 - 实体物流配送采用快递公司进行实体物流配送形式
*/
public static final Integer LOGISTICS_TYPE_EXPRESS = 1;
/**
* 物流模式 - 虚拟商品,虚拟商品,例如话费充值,点卡等,无实体配送形式
*/
public static final Integer LOGISTICS_TYPE_VIRTUAL = 3;
/**
* 物流模式 - 用户自提
*/
public static final Integer LOGISTICS_TYPE_PICK_UP = 4;
/**
* 支付者,支付者信息(openid)
*/
@NotEmpty(message = "支付者,支付者信息(openid)不能为空")
private String openid;
/**
* 原支付交易对应的微信订单号
*/
@NotEmpty(message = "原支付交易对应的微信订单号不能为空")
private String transactionId;
/**
* 物流模式
*/
@NotNull(message = "物流模式不能为空")
private Integer logisticsType;
/**
* 物流发货单号
*/
private String logisticsNo;
/**
* 物流公司编号
*
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/business/express_search.html#%E8%8E%B7%E5%8F%96%E8%BF%90%E5%8A%9Bid%E5%88%97%E8%A1%A8get-delivery-list">物流查询插件简介</a>
*/
private String expressCompany;
/**
* 商品信息
*/
@NotEmpty(message = "商品信息不能为空")
private String itemDesc;
/**
* 收件人手机号
*/
@NotEmpty(message = "收件人手机号")
private String receiverContact;
}

View File

@@ -0,0 +1,43 @@
package com.zt.plat.module.system.api.social.dto;
import com.zt.plat.framework.common.enums.UserTypeEnum;
import com.zt.plat.framework.common.validation.InEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Schema(description = "RPC 服务 - 微信小程序订阅消息发送 Request DTO")
@Data
public class SocialWxaSubscribeMessageSendReqDTO {
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "用户编号不能为空")
private Long userId;
@Schema(description = "用户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@InEnum(UserTypeEnum.class)
@NotNull(message = "用户类型不能为空")
private Integer userType;
@Schema(description = "消息模版标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "模版标题")
@NotEmpty(message = "消息模版标题不能为空")
private String templateTitle;
@Schema(description = "点击模板卡片后的跳转页面,仅限本小程序内的页面", example = "pages/index?foo=bar")
private String page; // 支持带参数,(示例 index?foo=bar )。该字段不填则模板无跳转。
@Schema(description = "模板内容的参数")
private Map<String, String> messages;
public SocialWxaSubscribeMessageSendReqDTO addMessage(String key, String value) {
if (messages == null) {
messages = new HashMap<>();
}
messages.put(key, value);
return this;
}
}

View File

@@ -0,0 +1,25 @@
package com.zt.plat.module.system.api.social.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "RPC 服务 - 小程序订阅消息模版 Response DTO")
@Data
public class SocialWxaSubscribeTemplateRespDTO {
@Schema(description = "模版编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private String id;
@Schema(description = "模版标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "模版标题")
private String title;
@Schema(description = "模版内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "模版内容")
private String content;
@Schema(description = "模板内容示例", requiredMode = Schema.RequiredMode.REQUIRED, example = "模版内容示例")
private String example;
@Schema(description = "模版类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
private Integer type; // 2为一次性订阅3为长期订阅
}

View File

@@ -0,0 +1,119 @@
package com.zt.plat.module.system.api.user;
import cn.hutool.core.convert.Convert;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.util.collection.CollectionUtils;
import com.zt.plat.module.system.api.user.dto.AdminUserRespDTO;
import com.zt.plat.module.system.api.user.dto.AdminUserSaveReqDTO;
import com.zt.plat.module.system.api.user.dto.AdminUserUpdatePasswordReqDTO;
import com.zt.plat.module.system.api.user.dto.AdminUserUpdateStatusReqDTO;
import com.zt.plat.module.system.enums.ApiConstants;
import com.fhs.core.trans.anno.AutoTrans;
import com.fhs.trans.service.AutoTransable;
import feign.FeignIgnore;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static com.zt.plat.module.system.api.user.AdminUserApi.PREFIX;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 管理员用户")
@AutoTrans(namespace = PREFIX, fields = {"nickname"})
public interface AdminUserApi extends AutoTransable<AdminUserRespDTO> {
String PREFIX = ApiConstants.PREFIX + "/user";
// === 以下为补全的接口方法 ===
@PostMapping(PREFIX + "/create")
@Operation(summary = "新增用户")
CommonResult<Long> createUser(@RequestBody AdminUserSaveReqDTO reqVO);
@PutMapping(PREFIX + "/update")
@Operation(summary = "修改用户")
CommonResult<Boolean> updateUser(@RequestBody AdminUserSaveReqDTO reqVO);
@DeleteMapping(PREFIX + "/delete")
@Operation(summary = "删除用户")
CommonResult<Boolean> deleteUser(@RequestParam("id") Long id);
@PutMapping(PREFIX + "/update-password")
@Operation(summary = "重置用户密码")
CommonResult<Boolean> updateUserPassword(@RequestBody AdminUserUpdatePasswordReqDTO reqVO);
@PutMapping(PREFIX + "/update-status")
@Operation(summary = "修改用户状态")
CommonResult<Boolean> updateUserStatus(@RequestBody AdminUserUpdateStatusReqDTO reqVO);
@GetMapping(PREFIX + "/get")
@Operation(summary = "通过用户 ID 查询用户")
@Parameter(name = "id", description = "用户编号", example = "1", required = true)
CommonResult<AdminUserRespDTO> getUser(@RequestParam("id") Long id);
@GetMapping(PREFIX + "/list-by-subordinate")
@Operation(summary = "通过用户 ID 查询用户下属")
@Parameter(name = "id", description = "用户编号", example = "1", required = true)
CommonResult<List<AdminUserRespDTO>> getUserListBySubordinate(@RequestParam("id") Long id);
@GetMapping(PREFIX + "/list")
@Operation(summary = "通过用户 ID 查询用户们")
@Parameter(name = "ids", description = "部门编号数组", example = "1,2", required = true)
CommonResult<List<AdminUserRespDTO>> getUserList(@RequestParam("ids") Collection<Long> ids);
@GetMapping(PREFIX + "/list-by-dept-id")
@Operation(summary = "获得指定部门的用户数组")
@Parameter(name = "deptIds", description = "部门编号数组", example = "1,2", required = true)
CommonResult<List<AdminUserRespDTO>> getUserListByDeptIds(@RequestParam("deptIds") Collection<Long> deptIds);
@GetMapping(PREFIX + "/list-by-post-id")
@Operation(summary = "获得指定岗位的用户数组")
@Parameter(name = "postIds", description = "岗位编号数组", example = "2,3", required = true)
CommonResult<List<AdminUserRespDTO>> getUserListByPostIds(@RequestParam("postIds") Collection<Long> postIds);
/**
* 获得用户 Map
*
* @param ids 用户编号数组
* @return 用户 Map
*/
default Map<Long, AdminUserRespDTO> getUserMap(Collection<Long> ids) {
List<AdminUserRespDTO> users = getUserList(ids).getCheckedData();
return CollectionUtils.convertMap(users, AdminUserRespDTO::getId);
}
/**
* 校验用户是否有效。如下情况,视为无效:
* 1. 用户编号不存在
* 2. 用户被禁用
*
* @param id 用户编号
*/
default void validateUser(Long id) {
validateUserList(Collections.singleton(id));
}
@GetMapping(PREFIX + "/valid")
@Operation(summary = "校验用户们是否有效")
@Parameter(name = "ids", description = "用户编号数组", example = "3,5", required = true)
CommonResult<Boolean> validateUserList(@RequestParam("ids") Collection<Long> ids);
@Override
@FeignIgnore
default List<AdminUserRespDTO> selectByIds(List<?> ids) {
return getUserList(Convert.toList(Long.class, ids)).getCheckedData();
}
@Override
@FeignIgnore
default AdminUserRespDTO selectById(Object id) {
return getUser(Convert.toLong(id)).getCheckedData();
}
}

View File

@@ -0,0 +1,62 @@
package com.zt.plat.module.system.api.user.dto;
import com.zt.plat.framework.common.pojo.PageResult;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
/**
* 管理员用户信息 Response DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 管理员用户信息 Response DTO")
@Data
public class AdminUserDetailRespDTO {
@Schema(description = "用户编号", example = "1")
private Long id;
@Schema(description = "用户账号", example = "cloud")
private String username;
@Schema(description = "用户昵称", example = "芋艿")
private String nickname;
@Schema(description = "备注", example = "我是一个用户")
private String remark;
@Schema(description = "部门ID列表")
private List<Long> deptIds;
@Schema(description = "岗位编号数组", example = "1")
private Set<Long> postIds;
@Schema(description = "用户邮箱", example = "cloud@iocoder.cn")
private String email;
@Schema(description = "手机号码", example = "15601691300")
private String mobile;
@Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
private Integer sex;
@Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png")
private String avatar;
@Schema(description = "状态,参见 CommonStatusEnum 枚举类", example = "1")
private Integer status;
@Schema(description = "最后登录 IP", example = "192.168.1.1")
private String loginIp;
@Schema(description = "最后登录时间")
private LocalDateTime loginDate;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,38 @@
package com.zt.plat.module.system.api.user.dto;
import com.zt.plat.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* 管理员用户分页 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 管理员用户分页 Request DTO")
@Data
@EqualsAndHashCode(callSuper = true)
public class AdminUserPageReqDTO extends PageParam {
@Schema(description = "用户账号,模糊匹配", example = "cloud")
private String username;
@Schema(description = "手机号码,模糊匹配", example = "cloud")
private String mobile;
@Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
private Integer status;
@Schema(description = "创建时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]")
private LocalDateTime[] createTime;
@Schema(description = "部门编号,同时筛选子部门", example = "1024")
private Long deptId;
@Schema(description = "角色编号", example = "1024")
private Long roleId;
}

View File

@@ -0,0 +1,35 @@
package com.zt.plat.module.system.api.user.dto;
import com.fhs.core.trans.vo.VO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
import java.util.Set;
@Schema(description = "RPC 服务 - Admin 用户 Response DTO")
@Data
public class AdminUserRespDTO implements VO {
@Schema(description = "用户 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小王")
private String nickname;
@Schema(description = "帐号状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status; // 参见 CommonStatusEnum 枚举
@Schema(description = "部门编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private List<Long> deptIds;
@Schema(description = "岗位编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 3]")
private Set<Long> postIds;
@Schema(description = "手机号码", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
private String mobile;
@Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
private String avatar;
}

View File

@@ -0,0 +1,53 @@
package com.zt.plat.module.system.api.user.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Set;
/**
* 管理员用户创建/修改 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 管理员用户创建/修改 Request DTO")
@Data
public class AdminUserSaveReqDTO {
@Schema(description = "用户编号", example = "1024")
private Long id;
@Schema(description = "用户账号", example = "cloud")
private String username;
@Schema(description = "用户昵称", example = "芋艿")
private String nickname;
@Schema(description = "备注", example = "我是一个用户")
private String remark;
@Schema(description = "部门编号数组", example = "1")
private Set<Long> deptIds;
@Schema(description = "岗位编号数组", example = "1")
private Set<Long> postIds;
@Schema(description = "用户邮箱", example = "cloud@iocoder.cn")
private String email;
@Schema(description = "手机号码", example = "15601691300")
private String mobile;
@Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
private Integer sex;
@Schema(description = "用户状态", example = "1")
private Integer status;
@Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png")
private String avatar;
@Schema(description = "密码", example = "123456")
private String password;
}

View File

@@ -0,0 +1,27 @@
package com.zt.plat.module.system.api.user.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 管理员用户精简信息 Response DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 管理员用户精简信息 Response DTO")
@Data
public class AdminUserSimpleRespDTO {
@Schema(description = "用户编号", example = "1024")
private Long id;
@Schema(description = "用户昵称", example = "ZT")
private String nickname;
@Schema(description = "部门ID", example = "1")
private Long deptId;
@Schema(description = "部门名称", example = "IT 部")
private String deptName;
}

View File

@@ -0,0 +1,21 @@
package com.zt.plat.module.system.api.user.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 管理员用户更新密码 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 管理员用户更新密码 Request DTO")
@Data
public class AdminUserUpdatePasswordReqDTO {
@Schema(description = "用户编号", example = "1024")
private Long id;
@Schema(description = "密码", example = "123456")
private String password;
}

View File

@@ -0,0 +1,21 @@
package com.zt.plat.module.system.api.user.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 管理员用户更新状态 Request DTO
*
* @author system
*/
@Schema(description = "RPC 服务 - 管理员用户更新状态 Request DTO")
@Data
public class AdminUserUpdateStatusReqDTO {
@Schema(description = "用户编号", example = "1024")
private Long id;
@Schema(description = "状态,见 CommonStatusEnum 枚举", example = "1")
private Integer status;
}

View File

@@ -0,0 +1,23 @@
package com.zt.plat.module.system.enums;
import com.zt.plat.framework.common.enums.RpcConstants;
/**
* API 相关的枚举
*
* @author ZT
*/
public class ApiConstants {
/**
* 服务名
*
* 注意,需要保证和 spring.application.name 保持一致
*/
public static final String NAME = "system-server";
public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/system";
public static final String VERSION = "1.0.0";
}

View File

@@ -0,0 +1,26 @@
package com.zt.plat.module.system.enums;
/**
* System 字典类型的枚举类
*
* @author ZT
*/
public interface DictTypeConstants {
String USER_TYPE = "user_type"; // 用户类型
String COMMON_STATUS = "common_status"; // 系统状态
// ========== SYSTEM 模块 ==========
String USER_SEX = "system_user_sex"; // 用户性别
String DATA_SCOPE = "system_data_scope"; // 数据范围
String LOGIN_TYPE = "system_login_type"; // 登录日志的类型
String LOGIN_RESULT = "system_login_result"; // 登录结果
String SMS_CHANNEL_CODE = "system_sms_channel_code"; // 短信渠道编码
String SMS_TEMPLATE_TYPE = "system_sms_template_type"; // 短信模板类型
String SMS_SEND_STATUS = "system_sms_send_status"; // 短信发送状态
String SMS_RECEIVE_STATUS = "system_sms_receive_status"; // 短信接收状态
}

View File

@@ -0,0 +1,205 @@
package com.zt.plat.module.system.enums;
import com.zt.plat.framework.common.exception.ErrorCode;
/**
* System 错误码枚举类
*
* system 系统,使用 1-002-000-000 段
* @author chenbowen
*/
public interface ErrorCodeConstants {
// ========== AUTH 模块 1-002-000-000 ==========
ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1_002_000_000, "登录失败,账号密码不正确");
ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1_002_000_001, "登录失败,账号被禁用");
ErrorCode AUTH_LOGIN_CAPTCHA_CODE_ERROR = new ErrorCode(1_002_000_004, "验证码不正确,原因:{}");
ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1_002_000_005, "未绑定账号,需要进行绑定");
ErrorCode AUTH_MOBILE_NOT_EXISTS = new ErrorCode(1_002_000_007, "手机号不存在");
ErrorCode AUTH_REGISTER_CAPTCHA_CODE_ERROR = new ErrorCode(1_002_000_008, "验证码不正确,原因:{}");
ErrorCode AUTH_TEST_LOGIN_NOT_ALLOWED = new ErrorCode(1_002_000_009, "测试登录接口仅在测试环境和本地开发环境下可用");
// ========== 菜单模块 1-002-001-000 ==========
ErrorCode MENU_NAME_DUPLICATE = new ErrorCode(1_002_001_000, "已经存在该名字的菜单");
ErrorCode MENU_PARENT_NOT_EXISTS = new ErrorCode(1_002_001_001, "父菜单不存在");
ErrorCode MENU_PARENT_ERROR = new ErrorCode(1_002_001_002, "不能设置自己为父菜单");
ErrorCode MENU_NOT_EXISTS = new ErrorCode(1_002_001_003, "菜单不存在");
ErrorCode MENU_EXISTS_CHILDREN = new ErrorCode(1_002_001_004, "存在子菜单,无法删除");
ErrorCode MENU_PARENT_NOT_DIR_OR_MENU = new ErrorCode(1_002_001_005, "父菜单的类型必须是目录或者菜单");
ErrorCode MENU_COMPONENT_NAME_DUPLICATE = new ErrorCode(1_002_001_006, "已经存在该组件名的菜单");
// ========== 角色模块 1-002-002-000 ==========
ErrorCode ROLE_NOT_EXISTS = new ErrorCode(1_002_002_000, "角色不存在");
ErrorCode ROLE_NAME_DUPLICATE = new ErrorCode(1_002_002_001, "已经存在名为【{}】的角色");
ErrorCode ROLE_CODE_DUPLICATE = new ErrorCode(1_002_002_002, "已经存在标识为【{}】的角色");
ErrorCode ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE = new ErrorCode(1_002_002_003, "不能操作类型为系统内置的角色");
ErrorCode ROLE_IS_DISABLE = new ErrorCode(1_002_002_004, "名字为【{}】的角色已被禁用");
ErrorCode ROLE_ADMIN_CODE_ERROR = new ErrorCode(1_002_002_005, "标识【{}】不能使用");
ErrorCode ROLE_CAN_NOT_UPDATE_NORMAL_TYPE_ROLE = new ErrorCode(1_002_002_006, "非管理员,不能操作类型为标准的角色");
ErrorCode ROLE_CAN_NOT_DELETE_HAS_CHILDREN = new ErrorCode(1_002_002_007, " 角色【{}】存在子角色,不允许删除");
ErrorCode ROLE_PARENT_IS_CHILD = new ErrorCode(1_002_002_008, "不能设置自己的子角色为父角色");
// ========== 用户模块 1-002-003-000 ==========
ErrorCode USER_USERNAME_EXISTS = new ErrorCode(1_002_003_000, "用户账号已经存在");
ErrorCode USER_MOBILE_EXISTS = new ErrorCode(1_002_003_001, "手机号已经存在");
ErrorCode USER_EMAIL_EXISTS = new ErrorCode(1_002_003_002, "邮箱已经存在");
ErrorCode USER_NOT_EXISTS = new ErrorCode(1_002_003_003, "用户不存在");
ErrorCode USER_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_002_003_004, "导入用户数据不能为空!");
ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1_002_003_005, "用户密码校验失败");
ErrorCode USER_IS_DISABLE = new ErrorCode(1_002_003_006, "名字为【{}】的用户已被禁用");
ErrorCode USER_COUNT_MAX = new ErrorCode(1_002_003_008, "创建用户失败,原因:超过租户最大租户配额({})");
ErrorCode USER_IMPORT_INIT_PASSWORD = new ErrorCode(1_002_003_009, "初始密码不能为空");
ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1_002_003_010, "该手机号尚未注册");
ErrorCode USER_REGISTER_DISABLED = new ErrorCode(1_002_003_011, "注册功能已关闭");
// ========== 部门模块 1-002-004-000 ==========
ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1_002_004_000, "已经存在该名字的部门");
ErrorCode DEPT_PARENT_NOT_EXITS = new ErrorCode(1_002_004_001,"父级部门不存在");
ErrorCode DEPT_NOT_FOUND = new ErrorCode(1_002_004_002, "机构不存在或当前账号无权限修改");
ErrorCode DEPT_EXITS_CHILDREN = new ErrorCode(1_002_004_003, "存在子部门,无法删除");
ErrorCode DEPT_PARENT_ERROR = new ErrorCode(1_002_004_004, "不能设置自己为父部门");
ErrorCode DEPT_NOT_ENABLE = new ErrorCode(1_002_004_006, "部门({})不处于开启状态,不允许选择");
ErrorCode DEPT_PARENT_IS_CHILD = new ErrorCode(1_002_004_007, "不能设置自己的子部门为父部门");
ErrorCode DEPT_TENANT_RELATION_EXISTS = new ErrorCode(1_002_004_008, "当前租户已经关联组织机构");
ErrorCode DEPT_CODE_NOT_NULL = new ErrorCode(1_002_004_009, "部门编码不能为空");
ErrorCode DEPT_CODE_DUPLICATE = new ErrorCode(1_002_004_010, "已经存在该编码的部门");
// ========== 岗位模块 1-002-005-000 ==========
ErrorCode POST_NOT_FOUND = new ErrorCode(1_002_005_000, "当前岗位不存在");
ErrorCode POST_NOT_ENABLE = new ErrorCode(1_002_005_001, "岗位({}) 不处于开启状态,不允许选择");
ErrorCode POST_NAME_DUPLICATE = new ErrorCode(1_002_005_002, "已经存在该名字的岗位");
ErrorCode POST_CODE_DUPLICATE = new ErrorCode(1_002_005_003, "已经存在该标识的岗位");
// ========== 字典类型 1-002-006-000 ==========
ErrorCode DICT_TYPE_NOT_EXISTS = new ErrorCode(1_002_006_001, "当前字典类型不存在");
ErrorCode DICT_TYPE_NOT_ENABLE = new ErrorCode(1_002_006_002, "字典类型不处于开启状态,不允许选择");
ErrorCode DICT_TYPE_NAME_DUPLICATE = new ErrorCode(1_002_006_003, "已经存在该名字的字典类型");
ErrorCode DICT_TYPE_TYPE_DUPLICATE = new ErrorCode(1_002_006_004, "已经存在该类型的字典类型");
ErrorCode DICT_TYPE_HAS_CHILDREN = new ErrorCode(1_002_006_005, "无法删除,该字典类型还有字典数据");
// ========== 字典数据 1-002-007-000 ==========
ErrorCode DICT_DATA_NOT_EXISTS = new ErrorCode(1_002_007_001, "当前字典数据不存在");
ErrorCode DICT_DATA_NOT_ENABLE = new ErrorCode(1_002_007_002, "字典数据({})不处于开启状态,不允许选择");
ErrorCode DICT_DATA_VALUE_DUPLICATE = new ErrorCode(1_002_007_003, "已经存在该值的字典数据");
// ========== 通知公告 1-002-008-000 ==========
ErrorCode NOTICE_NOT_FOUND = new ErrorCode(1_002_008_001, "当前通知公告不存在");
// ========== 短信渠道 1-002-011-000 ==========
ErrorCode SMS_CHANNEL_NOT_EXISTS = new ErrorCode(1_002_011_000, "短信渠道不存在");
ErrorCode SMS_CHANNEL_DISABLE = new ErrorCode(1_002_011_001, "短信渠道不处于开启状态,不允许选择");
ErrorCode SMS_CHANNEL_HAS_CHILDREN = new ErrorCode(1_002_011_002, "无法删除,该短信渠道还有短信模板");
// ========== 短信模板 1-002-012-000 ==========
ErrorCode SMS_TEMPLATE_NOT_EXISTS = new ErrorCode(1_002_012_000, "短信模板不存在");
ErrorCode SMS_TEMPLATE_CODE_DUPLICATE = new ErrorCode(1_002_012_001, "已经存在编码为【{}】的短信模板");
ErrorCode SMS_TEMPLATE_API_ERROR = new ErrorCode(1_002_012_002, "短信 API 模板调用失败,原因是:{}");
ErrorCode SMS_TEMPLATE_API_AUDIT_CHECKING = new ErrorCode(1_002_012_003, "短信 API 模版无法使用,原因:审批中");
ErrorCode SMS_TEMPLATE_API_AUDIT_FAIL = new ErrorCode(1_002_012_004, "短信 API 模版无法使用,原因:审批不通过,{}");
ErrorCode SMS_TEMPLATE_API_NOT_FOUND = new ErrorCode(1_002_012_005, "短信 API 模版无法使用,原因:模版不存在");
// ========== 短信发送 1-002-013-000 ==========
ErrorCode SMS_SEND_MOBILE_NOT_EXISTS = new ErrorCode(1_002_013_000, "手机号不存在");
ErrorCode SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS = new ErrorCode(1_002_013_001, "模板参数({})缺失");
ErrorCode SMS_SEND_TEMPLATE_NOT_EXISTS = new ErrorCode(1_002_013_002, "短信模板不存在");
// ========== 短信验证码 1-002-014-000 ==========
ErrorCode SMS_CODE_NOT_FOUND = new ErrorCode(1_002_014_000, "验证码不存在");
ErrorCode SMS_CODE_EXPIRED = new ErrorCode(1_002_014_001, "验证码已过期");
ErrorCode SMS_CODE_USED = new ErrorCode(1_002_014_002, "验证码已使用");
ErrorCode SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY = new ErrorCode(1_002_014_004, "超过每日短信发送数量");
ErrorCode SMS_CODE_SEND_TOO_FAST = new ErrorCode(1_002_014_005, "短信发送过于频繁");
// ========== 租户信息 1-002-015-000 ==========
ErrorCode TENANT_NOT_EXISTS = new ErrorCode(1_002_015_000, "租户不存在");
ErrorCode TENANT_DISABLE = new ErrorCode(1_002_015_001, "名字为【{}】的租户已被禁用");
ErrorCode TENANT_EXPIRE = new ErrorCode(1_002_015_002, "名字为【{}】的租户已过期");
ErrorCode TENANT_CAN_NOT_UPDATE_SYSTEM = new ErrorCode(1_002_015_003, "系统租户不能进行修改、删除等操作!");
ErrorCode TENANT_NAME_DUPLICATE = new ErrorCode(1_002_015_004, "名字为【{}】的租户已存在");
ErrorCode TENANT_WEBSITE_DUPLICATE = new ErrorCode(1_002_015_005, "域名为【{}】的租户已存在");
// ========== 租户套餐 1-002-016-000 ==========
ErrorCode TENANT_PACKAGE_NOT_EXISTS = new ErrorCode(1_002_016_000, "租户套餐不存在");
ErrorCode TENANT_PACKAGE_USED = new ErrorCode(1_002_016_001, "租户正在使用该套餐,请给租户重新设置套餐后再尝试删除");
ErrorCode TENANT_PACKAGE_DISABLE = new ErrorCode(1_002_016_002, "名字为【{}】的租户套餐已被禁用");
ErrorCode TENANT_PACKAGE_NAME_DUPLICATE = new ErrorCode(1_002_016_003, "已经存在该名字的租户套餐");
// ========== 社交用户 1-002-018-000 ==========
ErrorCode SOCIAL_USER_AUTH_FAILURE = new ErrorCode(1_002_018_000, "社交授权失败,原因是:{}");
ErrorCode SOCIAL_USER_NOT_FOUND = new ErrorCode(1_002_018_001, "社交授权失败,找不到对应的用户");
ErrorCode SOCIAL_CLIENT_WEIXIN_MINI_APP_PHONE_CODE_ERROR = new ErrorCode(1_002_018_200, "获得手机号失败");
ErrorCode SOCIAL_CLIENT_WEIXIN_MINI_APP_QRCODE_ERROR = new ErrorCode(1_002_018_201, "获得小程序码失败");
ErrorCode SOCIAL_CLIENT_WEIXIN_MINI_APP_SUBSCRIBE_TEMPLATE_ERROR = new ErrorCode(1_002_018_202, "获得小程序订阅消息模版失败");
ErrorCode SOCIAL_CLIENT_WEIXIN_MINI_APP_SUBSCRIBE_MESSAGE_ERROR = new ErrorCode(1_002_018_203, "发送小程序订阅消息失败");
ErrorCode SOCIAL_CLIENT_WEIXIN_MINI_APP_ORDER_UPLOAD_SHIPPING_INFO_ERROR = new ErrorCode(1_002_018_204, "上传微信小程序发货信息失败");
ErrorCode SOCIAL_CLIENT_WEIXIN_MINI_APP_ORDER_NOTIFY_CONFIRM_RECEIVE_ERROR = new ErrorCode(1_002_018_205, "上传微信小程序订单收货信息失败");
ErrorCode SOCIAL_CLIENT_NOT_EXISTS = new ErrorCode(1_002_018_210, "社交客户端不存在");
ErrorCode SOCIAL_CLIENT_UNIQUE = new ErrorCode(1_002_018_211, "社交客户端已存在配置");
// ========== OAuth2 客户端 1-002-020-000 =========
ErrorCode OAUTH2_CLIENT_NOT_EXISTS = new ErrorCode(1_002_020_000, "OAuth2 客户端不存在");
ErrorCode OAUTH2_CLIENT_EXISTS = new ErrorCode(1_002_020_001, "OAuth2 客户端编号已存在");
ErrorCode OAUTH2_CLIENT_DISABLE = new ErrorCode(1_002_020_002, "OAuth2 客户端已禁用");
ErrorCode OAUTH2_CLIENT_AUTHORIZED_GRANT_TYPE_NOT_EXISTS = new ErrorCode(1_002_020_003, "不支持该授权类型");
ErrorCode OAUTH2_CLIENT_SCOPE_OVER = new ErrorCode(1_002_020_004, "授权范围过大");
ErrorCode OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH = new ErrorCode(1_002_020_005, "无效 redirect_uri: {}");
ErrorCode OAUTH2_CLIENT_CLIENT_SECRET_ERROR = new ErrorCode(1_002_020_006, "无效 client_secret: {}");
// ========== OAuth2 授权 1-002-021-000 =========
ErrorCode OAUTH2_GRANT_CLIENT_ID_MISMATCH = new ErrorCode(1_002_021_000, "client_id 不匹配");
ErrorCode OAUTH2_GRANT_REDIRECT_URI_MISMATCH = new ErrorCode(1_002_021_001, "redirect_uri 不匹配");
ErrorCode OAUTH2_GRANT_STATE_MISMATCH = new ErrorCode(1_002_021_002, "state 不匹配");
// ========== OAuth2 授权 1-002-022-000 =========
ErrorCode OAUTH2_CODE_NOT_EXISTS = new ErrorCode(1_002_022_000, "code 不存在");
ErrorCode OAUTH2_CODE_EXPIRE = new ErrorCode(1_002_022_001, "code 已过期");
// ========== 同步验证工具 1-002-019-000 ==========
ErrorCode SYNC_DECRYPT_TYPE = new ErrorCode(1_002_019_000, "解密失败");
ErrorCode SYNC_ENCRYPT_TYPE = new ErrorCode(1_002_019_001, "加密失败");
ErrorCode SYNC_SIGNATURE_UNSUPPORTED_TYPE = new ErrorCode(1_002_019_002, "签名类型不存在");
// 同步签名验证失败
ErrorCode SYNC_SIGNATURE_VERIFY_FAILED = new ErrorCode(1_002_019_003, "签名验证失败");
// ========== 邮箱账号 1-002-023-000 ==========
ErrorCode MAIL_ACCOUNT_NOT_EXISTS = new ErrorCode(1_002_023_000, "邮箱账号不存在");
ErrorCode MAIL_ACCOUNT_RELATE_TEMPLATE_EXISTS = new ErrorCode(1_002_023_001, "无法删除,该邮箱账号还有邮件模板");
// ========== 邮件模版 1-002-024-000 ==========
ErrorCode MAIL_TEMPLATE_NOT_EXISTS = new ErrorCode(1_002_024_000, "邮件模版不存在");
ErrorCode MAIL_TEMPLATE_CODE_EXISTS = new ErrorCode(1_002_024_001, "邮件模版 code({}) 已存在");
// ========== 邮件发送 1-002-025-000 ==========
ErrorCode MAIL_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1_002_025_000, "模板参数({})缺失");
ErrorCode MAIL_SEND_MAIL_NOT_EXISTS = new ErrorCode(1_002_025_001, "邮箱不存在");
// ========== 站内信模版 1-002-026-000 ==========
ErrorCode NOTIFY_TEMPLATE_NOT_EXISTS = new ErrorCode(1_002_026_000, "站内信模版不存在");
ErrorCode NOTIFY_TEMPLATE_CODE_DUPLICATE = new ErrorCode(1_002_026_001, "已经存在编码为【{}】的站内信模板");
// ========== 站内信模版 1-002-027-000 ==========
// ========== 站内信发送 1-002-028-000 ==========
ErrorCode NOTIFY_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1_002_028_000, "模板参数({})缺失");
// ========== 用户与部门关系 1-002-029-000 ==========
ErrorCode USER_DEPT_NOT_EXISTS = new ErrorCode(1_002_029_000, "用户与部门关系不存在");
// ========== 系统序列号分段明细 1-002-030-000 ==========
ErrorCode SEQUENCE_DETAIL_NOT_EXISTS = new ErrorCode(1_002_030_000, "系统序列号分段明细不存在");
// ========== 系统序列号 1-002-031-000 ==========
ErrorCode SEQUENCE_NOT_EXISTS = new ErrorCode(1_002_031_000, "系统序列号不存在");
ErrorCode SEQUENCE_DETAIL_EMPTY = new ErrorCode(1_002_031_001, "序列号分段明细不存在");
ErrorCode SEQUENCE_GENERATE_ERROR = new ErrorCode(1_002_031_002, "序列号生成失败:{}");
ErrorCode SEQUENCE_LOCK_TIMEOUT = new ErrorCode(1_002_031_003, "序列号生成锁超时");
// ========== 系统序列号规则校验 1-002-031-010 ==========
ErrorCode SEQUENCE_DETAIL_RULE_INVALID = new ErrorCode(1_002_031_010, "序列号分段规则无效:{}");
// ========== 系统序列号记录 1-002-032-000 ==========
ErrorCode SEQUENCE_RECORD_NOT_EXISTS = new ErrorCode(1_002_032_000, "系统序列号记录不存在");
}

View File

@@ -0,0 +1,33 @@
package com.zt.plat.module.system.enums;
/**
* System 操作日志枚举
* 目的:统一管理,也减少 Service 里各种“复杂”字符串
*
* @author ZT
*/
public interface LogRecordConstants {
// ======================= SYSTEM_USER 用户 =======================
String SYSTEM_USER_TYPE = "SYSTEM 用户";
String SYSTEM_USER_CREATE_SUB_TYPE = "创建用户";
String SYSTEM_USER_CREATE_SUCCESS = "创建了用户【{{#user.nickname}}】";
String SYSTEM_USER_UPDATE_SUB_TYPE = "更新用户";
String SYSTEM_USER_UPDATE_SUCCESS = "更新了用户【{{#user.nickname}}】: {_DIFF{#updateReqVO}}";
String SYSTEM_USER_DELETE_SUB_TYPE = "删除用户";
String SYSTEM_USER_DELETE_SUCCESS = "删除了用户【{{#user.nickname}}】";
String SYSTEM_USER_UPDATE_PASSWORD_SUB_TYPE = "重置用户密码";
String SYSTEM_USER_UPDATE_PASSWORD_SUCCESS = "将用户【{{#user.nickname}}】的密码从【{{#user.password}}】重置为【{{#newPassword}}】";
// ======================= SYSTEM_ROLE 角色 =======================
String SYSTEM_ROLE_TYPE = "SYSTEM 角色";
String SYSTEM_ROLE_CREATE_SUB_TYPE = "创建角色";
String SYSTEM_ROLE_CREATE_SUCCESS = "创建了角色【{{#role.name}}】";
String SYSTEM_ROLE_UPDATE_SUB_TYPE = "更新角色";
String SYSTEM_ROLE_UPDATE_SUCCESS = "更新了角色【{{#role.name}}】: {_DIFF{#updateReqVO}}";
String SYSTEM_ROLE_DELETE_SUB_TYPE = "删除角色";
String SYSTEM_ROLE_DELETE_SUCCESS = "删除了角色【{{#role.name}}】";
}

View File

@@ -0,0 +1,27 @@
package com.zt.plat.module.system.enums.common;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 性别的枚举值
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum SexEnum {
/** 男 */
MALE(1),
/** 女 */
FEMALE(2),
/* 未知 */
UNKNOWN(0);
/**
* 性别
*/
private final Integer sex;
}

View File

@@ -0,0 +1,27 @@
package com.zt.plat.module.system.enums.dept;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 部门来源枚举
*
* @author ZT
*/
@AllArgsConstructor
@Getter
public enum DeptSourceEnum {
EXTERNAL(1, "外部部门"), // 系统创建的部门
SYNC(2, "同步部门"); // 通过 OrgSyncService 同步的部门
/**
* 类型
*/
private final Integer source;
/**
* 名字
*/
private final String name;
}

View File

@@ -0,0 +1,63 @@
package com.zt.plat.module.system.enums.dept;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 机构类型枚举
*
* @author chenbowen
*/
@Getter
@AllArgsConstructor
public enum DeptTypeEnum {
/**
* 单位/公司
*/
COMPANY(28, "单位"),
/**
* 部门
*/
DEPARTMENT(26, "部门");
/**
* 类型编码
*/
private final Integer code;
/**
* 类型名称
*/
private final String name;
/**
* 根据编码获取枚举
*/
public static DeptTypeEnum getByCode(Integer code) {
if (code == null) {
return null;
}
for (DeptTypeEnum value : DeptTypeEnum.values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}
/**
* 判断是否为公司
*/
public static boolean isCompany(Integer code) {
return COMPANY.getCode().equals(code);
}
/**
* 判断是否为部门
*/
public static boolean isDepartment(Integer code) {
return DEPARTMENT.getCode().equals(code);
}
}

View File

@@ -0,0 +1,27 @@
package com.zt.plat.module.system.enums.logger;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 登录日志的类型枚举
*/
@Getter
@AllArgsConstructor
public enum LoginLogTypeEnum {
LOGIN_USERNAME(100), // 使用账号登录
LOGIN_SOCIAL(101), // 使用社交登录
LOGIN_MOBILE(103), // 使用手机登陆
LOGIN_SMS(104), // 使用短信登陆
LOGOUT_SELF(200), // 自己主动登出
LOGOUT_DELETE(202), // 强制退出
;
/**
* 日志类型
*/
private final Integer type;
}

View File

@@ -0,0 +1,26 @@
package com.zt.plat.module.system.enums.logger;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 登录结果的枚举类
*/
@Getter
@AllArgsConstructor
public enum LoginResultEnum {
SUCCESS(0), // 成功
BAD_CREDENTIALS(10), // 账号或密码不正确
USER_DISABLED(20), // 用户被禁用
CAPTCHA_NOT_FOUND(30), // 图片验证码不存在
CAPTCHA_CODE_ERROR(31), // 图片验证码不正确
;
/**
* 结果
*/
private final Integer result;
}

View File

@@ -0,0 +1,24 @@
package com.zt.plat.module.system.enums.mail;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 邮件的发送状态枚举
*
* @author wangjingyi
* @since 2022/4/10 13:39
*/
@Getter
@AllArgsConstructor
public enum MailSendStatusEnum {
INIT(0), // 初始化
SUCCESS(10), // 发送成功
FAILURE(20), // 发送失败
IGNORE(30), // 忽略,即不发送
;
private final int status;
}

View File

@@ -0,0 +1,23 @@
package com.zt.plat.module.system.enums.notice;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 通知类型
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum NoticeTypeEnum {
NOTICE(1),
ANNOUNCEMENT(2);
/**
* 类型
*/
private final Integer type;
}

View File

@@ -0,0 +1,26 @@
package com.zt.plat.module.system.enums.notify;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 通知模板类型枚举
*
* @author HUIHUI
*/
@Getter
@AllArgsConstructor
public enum NotifyTemplateTypeEnum {
/**
* 系统消息
*/
SYSTEM_MESSAGE(2),
/**
* 通知消息
*/
NOTIFICATION_MESSAGE(1);
private final Integer type;
}

View File

@@ -0,0 +1,12 @@
package com.zt.plat.module.system.enums.oauth2;
/**
* OAuth2.0 客户端的通用枚举
*
* @author ZT
*/
public interface OAuth2ClientConstants {
String CLIENT_ID_DEFAULT = "default";
}

View File

@@ -0,0 +1,29 @@
package com.zt.plat.module.system.enums.oauth2;
import cn.hutool.core.util.ArrayUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* OAuth2 授权类型(模式)的枚举
*
* @author ZT
*/
@AllArgsConstructor
@Getter
public enum OAuth2GrantTypeEnum {
PASSWORD("password"), // 密码模式
AUTHORIZATION_CODE("authorization_code"), // 授权码模式
IMPLICIT("implicit"), // 简化模式
CLIENT_CREDENTIALS("client_credentials"), // 客户端模式
REFRESH_TOKEN("refresh_token"), // 刷新模式
;
private final String grantType;
public static OAuth2GrantTypeEnum getByGrantType(String grantType) {
return ArrayUtil.firstMatch(o -> o.getGrantType().equals(grantType), values());
}
}

View File

@@ -0,0 +1,40 @@
package com.zt.plat.module.system.enums.permission;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 数据范围枚举类
*
* 用于实现数据级别的权限
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum DataScopeEnum implements ArrayValuable<Integer> {
ALL(1), // 全部数据权限
DEPT_CUSTOM(2), // 指定部门数据权限
DEPT_ONLY(3), // 部门数据权限
DEPT_AND_CHILD(4), // 部门及以下数据权限
SELF(5); // 仅本人数据权限
/**
* 范围
*/
private final Integer scope;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(DataScopeEnum::getScope).toArray(Integer[]::new);
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,25 @@
package com.zt.plat.module.system.enums.permission;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 菜单类型枚举类
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum MenuTypeEnum {
DIR(1), // 目录
MENU(2), // 菜单
BUTTON(3) // 按钮
;
/**
* 类型
*/
private final Integer type;
}

View File

@@ -0,0 +1,39 @@
package com.zt.plat.module.system.enums.permission;
import com.zt.plat.framework.common.util.object.ObjectUtils;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 角色标识枚举
*/
@Getter
@AllArgsConstructor
public enum RoleCodeEnum {
SUPER_ADMIN("super_admin", "超级管理员"),
TENANT_ADMIN("tenant_admin", "租户管理员"),
CRM_ADMIN("crm_admin", "CRM 管理员");
;
/**
* 角色编码
*/
private final String code;
/**
* 名字
*/
private final String name;
public static boolean isSuperAdmin(String code) {
return ObjectUtils.equalsAny(code, SUPER_ADMIN.getCode());
}
// 是否存在管理员角色编码
public static boolean isAdmin(String code) {
return ObjectUtils.equalsAny(code, Arrays.stream(RoleCodeEnum.values()).map(RoleCodeEnum::getCode).toArray(String[]::new));
}
}

View File

@@ -0,0 +1,30 @@
package com.zt.plat.module.system.enums.permission;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author chenbowen
*/
@Getter
@AllArgsConstructor
public enum RoleTypeEnum {
/**
* 内置角色
*/
SYSTEM(1),
/**
* 标准角色
*/
NORMAL(2),
/**
* 自定义角色
*/
CUSTOM(3);
private final Integer type;
}

View File

@@ -0,0 +1,64 @@
package com.zt.plat.module.system.enums.sequence;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 序列号循环类型
*/
@Getter
@AllArgsConstructor
public enum SequenceCycleTypeEnum {
// 年循环。示例: 2025
SEQUENCE_CYCLE_YEAR("Y", "年循环。示例: 2025"),
// 年-月循环。示例: 2025-08
SEQUENCE_CYCLE_YEAR_MONTH("Y-M", "年-月循环。示例: 2025-08"),
// 年月紧凑。示例: 202508
SEQUENCE_CYCLE_YEAR_MONTH_COMPACT("YM", "年月紧凑。示例: 202508"),
// 两位年+月。示例: 2508
SEQUENCE_CYCLE_SHORT_YEAR_MONTH("yM", "两位年+月。示例: 2508"),
// 年-月-日循环。示例: 2025-08-08
SEQUENCE_CYCLE_YEAR_MONTH_DAY("Y-M-D", "年-月-日循环。示例: 2025-08-08"),
// 年月日紧凑。示例: 20250808
SEQUENCE_CYCLE_YEAR_MONTH_DAY_COMPACT("YMD", "年月日紧凑。示例: 20250808"),
// 两位年+月日。示例: 250808
SEQUENCE_CYCLE_SHORT_YEAR_MONTH_DAY("yMD", "两位年+月日。示例: 250808"),
// 自定义循环值;若未传 circulationValue则默认用 seqId
SEQUENCE_CYCLE_CUSTOM("CUST", "自定义循环值;若未传 circulationValue则默认用 seqId"),
// 仅前缀,不需要时间循环值(不设置则不抛错)
SEQUENCE_CYCLE_PREFIX_ONLY("PFX", "仅前缀,不需要时间循环值(不设置则不抛错)");
/**
* 类型编码(精简版)
*/
private final String code;
private final String name;
public static SequenceCycleTypeEnum getByCode(String code) {
if (code == null) {
return null;
}
// 先按精简编码匹配
for (SequenceCycleTypeEnum value : SequenceCycleTypeEnum.values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}
public static SequenceCycleTypeEnum getByName(String name) {
for (SequenceCycleTypeEnum value : SequenceCycleTypeEnum.values()) {
if (value.getName().equals(name)) {
return value;
}
}
return null;
}
// 获取 EnumList
public static SequenceCycleTypeEnum[] getEnumList() {
return SequenceCycleTypeEnum.values();
}
}

View File

@@ -0,0 +1,20 @@
package com.zt.plat.module.system.enums.sequence;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 序列号分段规则类型枚举
*/
@Getter
@AllArgsConstructor
public enum SequenceDetailRuleEnum {
// 示例规则类型
FIXED("FIXED", "固定值"),
DATE("DATE", "日期格式"),
NUMBER("NUMBER", "数字格式"),
CUSTOM("CUSTOM", "自定义格式");
private final String code;
private final String name;
}

View File

@@ -0,0 +1,39 @@
package com.zt.plat.module.system.enums.sequence;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 序列号分段类型枚举
*/
@Getter
@AllArgsConstructor
public enum SequenceDetailTypeEnum {
// 默认字符分段
SEQ_DETAIL_TYPE_STR("STR", "默认字符分段"),
// 给定字符分段
SEQ_DETAIL_TYPE_INPUT("INPUT", "给定字符分段"),
// 日期分段
SEQ_DETAIL_TYPE_DATE("DATE", "日期分段"),
// 流水号分段
SEQ_DETAIL_TYPE_SEQ("SEQ", "流水号分段");
/**
* 类型编码
*/
private final String code;
private final String name;
public static SequenceDetailTypeEnum getByCode(String code) {
if (code == null) {
return null;
}
for (SequenceDetailTypeEnum value : SequenceDetailTypeEnum.values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}
}

View File

@@ -0,0 +1,23 @@
package com.zt.plat.module.system.enums.sms;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 短信的接收状态枚举
*
* @author ZT
* @date 2021/2/1 13:39
*/
@Getter
@AllArgsConstructor
public enum SmsReceiveStatusEnum {
INIT(0), // 初始化
SUCCESS(10), // 接收成功
FAILURE(20), // 接收失败
;
private final int status;
}

View File

@@ -0,0 +1,53 @@
package com.zt.plat.module.system.enums.sms;
import cn.hutool.core.util.ArrayUtil;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 用户短信验证码发送场景的枚举
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum SmsSceneEnum implements ArrayValuable<Integer> {
MEMBER_LOGIN(1, "user-sms-login", "会员用户 - 手机号登陆"),
MEMBER_UPDATE_MOBILE(2, "user-update-mobile", "会员用户 - 修改手机"),
MEMBER_UPDATE_PASSWORD(3, "user-update-password", "会员用户 - 修改密码"),
MEMBER_RESET_PASSWORD(4, "user-reset-password", "会员用户 - 忘记密码"),
ADMIN_MEMBER_LOGIN(21, "admin-sms-login", "后台用户 - 手机号登录"),
ADMIN_MEMBER_REGISTER(22, "admin-sms-register", "后台用户 - 手机号注册"),
ADMIN_MEMBER_RESET_PASSWORD(23, "admin-reset-password", "后台用户 - 忘记密码");
public static final Integer[] ARRAYS = Arrays.stream(values()).map(SmsSceneEnum::getScene).toArray(Integer[]::new);
/**
* 验证场景的编号
*/
private final Integer scene;
/**
* 模版编码
*/
private final String templateCode;
/**
* 描述
*/
private final String description;
@Override
public Integer[] array() {
return ARRAYS;
}
public static SmsSceneEnum getCodeByScene(Integer scene) {
return ArrayUtil.firstMatch(sceneEnum -> sceneEnum.getScene().equals(scene),
values());
}
}

View File

@@ -0,0 +1,24 @@
package com.zt.plat.module.system.enums.sms;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 短信的发送状态枚举
*
* @author zzf
* @date 2021/2/1 13:39
*/
@Getter
@AllArgsConstructor
public enum SmsSendStatusEnum {
INIT(0), // 初始化
SUCCESS(10), // 发送成功
FAILURE(20), // 发送失败
IGNORE(30), // 忽略,即不发送
;
private final int status;
}

View File

@@ -0,0 +1,25 @@
package com.zt.plat.module.system.enums.sms;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 短信的模板类型枚举
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum SmsTemplateTypeEnum {
VERIFICATION_CODE(1), // 验证码
NOTICE(2), // 通知
PROMOTION(3), // 营销
;
/**
* 类型
*/
private final int type;
}

View File

@@ -0,0 +1,78 @@
package com.zt.plat.module.system.enums.social;
import cn.hutool.core.util.ArrayUtil;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 社交平台的类型枚举
*
* @author ZT
*/
@Getter
@AllArgsConstructor
public enum SocialTypeEnum implements ArrayValuable<Integer> {
/**
* Gitee
*
* @see <a href="https://gitee.com/api/v5/oauth_doc#/">接入文档</a>
*/
GITEE(10, "GITEE"),
/**
* 钉钉
*
* @see <a href="https://developers.dingtalk.com/document/app/obtain-identity-credentials">接入文档</a>
*/
DINGTALK(20, "DINGTALK"),
/**
* 企业微信
*
* @see <a href="https://xkcoding.com/2019/08/06/use-justauth-integration-wechat-enterprise.html">接入文档</a>
*/
WECHAT_ENTERPRISE(30, "WECHAT_ENTERPRISE"),
/**
* 微信公众平台 - 移动端 H5
*
* @see <a href="https://www.cnblogs.com/juewuzhe/p/11905461.html">接入文档</a>
*/
WECHAT_MP(31, "WECHAT_MP"),
/**
* 微信开放平台 - 网站应用 PC 端扫码授权登录
*
* @see <a href="https://justauth.wiki/guide/oauth/wechat_open/#_2-申请开发者资质认证">接入文档</a>
*/
WECHAT_OPEN(32, "WECHAT_OPEN"),
/**
* 微信小程序
*
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html">接入文档</a>
*/
WECHAT_MINI_PROGRAM(34, "WECHAT_MINI_PROGRAM"),
;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(SocialTypeEnum::getType).toArray(Integer[]::new);
/**
* 类型
*/
private final Integer type;
/**
* 类型的标识
*/
private final String source;
@Override
public Integer[] array() {
return ARRAYS;
}
public static SocialTypeEnum valueOfType(Integer type) {
return ArrayUtil.firstMatch(o -> o.getType().equals(type), values());
}
}

View File

@@ -0,0 +1,27 @@
package com.zt.plat.module.system.enums.user;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 用户来源枚举
*
* @author ZT
*/
@AllArgsConstructor
@Getter
public enum UserSourceEnum {
EXTERNAL(1, "外部用户"), // 系统创建、注册等方式产生的用户
SYNC(2, "同步用户"); // 通过 UserSyncService 同步的用户
/**
* 类型
*/
private final Integer source;
/**
* 名字
*/
private final String name;
}

View File

@@ -0,0 +1,19 @@
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
FROM 172.16.46.66:10043/base-service/eclipse-temurin:21-jre
## 创建目录,并使用它作为工作目录
RUN mkdir -p /cloud-module-system-server
WORKDIR /cloud-module-system-server
## 将后端项目的 Jar 文件,复制到镜像中
COPY ./target/cloud-module-system-server.jar app.jar
## 设置 TZ 时区
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx512m"
## 暴露后端项目的 48080 端口
EXPOSE 48081
## 启动后端项目
CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

View File

@@ -0,0 +1,193 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.zt.plat</groupId>
<artifactId>zt-module-system</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>zt-module-system-server</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
system 模块下,我们放通用业务,支撑上层的核心业务。
例如说:用户、部门、权限、数据字典等等
</description>
<dependencies>
<!-- Spring Cloud 基础 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-env</artifactId>
</dependency>
<!-- 依赖服务 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-module-system-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-module-infra-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-biz-data-permission</artifactId>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-biz-tenant</artifactId>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-biz-ip</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-security</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-mybatis</artifactId>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-redis</artifactId>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-rpc</artifactId>
</dependency>
<!-- Registry 注册中心相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Config 配置中心相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- Job 定时任务相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-job</artifactId>
</dependency>
<!-- 消息队列相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-mq</artifactId>
</dependency>
<!-- 服务保障相关 TODO 芋艿:暂时去掉 -->
<!-- <dependency>-->
<!-- <groupId>com.zt.plat</groupId>-->
<!-- <artifactId>zt-spring-boot-starter-protection</artifactId>-->
<!-- </dependency>-->
<!-- Test 测试相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-excel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-monitor</artifactId>
</dependency>
<!-- 三方云服务相关 -->
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
</dependency>
<dependency>
<groupId>com.xkcoding.justauth</groupId>
<artifactId>justauth-spring-boot-starter</artifactId>
<exclusions>
<!-- 移除,避免和项目里的 hutool-all 冲突 -->
<exclusion>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-mp-spring-boot-starter</artifactId> <!-- 微信登录(公众号) -->
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-miniapp-spring-boot-starter</artifactId> <!-- 微信登录(小程序) -->
</dependency>
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>captcha-spring-boot-starter</artifactId> <!-- 验证码,一般用于登录使用 -->
</dependency>
<dependency>
<groupId>org.dromara.hutool</groupId>
<artifactId>hutool-extra</artifactId> <!-- 邮件 -->
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>zt-spring-boot-starter-mq</artifactId>
</dependency>
</dependencies>
<build>
<!-- 设置构建的 jar 包名 -->
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,30 @@
package com.zt.plat.module.system;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 项目的启动类
*
* 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
* 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
* 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
*
* @author ZT
*/
@SpringBootApplication
public class SystemServerApplication {
public static void main(String[] args) {
// 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
// 如果你碰到 启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
// 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
SpringApplication.run(SystemServerApplication.class, args);
// 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
// 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
// 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
}
}

View File

@@ -0,0 +1,110 @@
package com.zt.plat.module.system.api.dept;
import com.zt.plat.framework.common.enums.CommonStatusEnum;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.CompanyDeptInfo;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.module.system.api.dept.dto.*;
import com.zt.plat.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
import com.zt.plat.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
import com.zt.plat.module.system.dal.dataobject.dept.DeptDO;
import com.zt.plat.module.system.service.dept.DeptService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import static com.zt.plat.framework.common.pojo.CommonResult.success;
@RestController // 提供 RESTful API 接口,给 Feign 调用
@Validated
public class DeptApiImpl implements DeptApi {
@Resource
private DeptService deptService;
@Override
public CommonResult<Long> createDept(DeptSaveReqDTO createReqVO) {
DeptSaveReqVO reqVO = BeanUtils.toBean(createReqVO, DeptSaveReqVO.class);
Long deptId = deptService.createDept(reqVO);
return success(deptId);
}
@Override
public CommonResult<Boolean> updateDept(DeptSaveReqDTO updateReqVO) {
DeptSaveReqVO reqVO = BeanUtils.toBean(updateReqVO, DeptSaveReqVO.class);
deptService.updateDept(reqVO);
return success(true);
}
@Override
public CommonResult<Boolean> deleteDept(Long id) {
deptService.deleteDept(id);
return success(true);
}
@Override
public CommonResult<List<DeptDetailRespDTO>> getDeptList(DeptListReqDTO reqVO) {
DeptListReqVO listReqVO = BeanUtils.toBean(reqVO, DeptListReqVO.class);
List<DeptDO> depts = deptService.getDeptList(listReqVO);
return success(BeanUtils.toBean(depts, DeptDetailRespDTO.class));
}
@Override
public CommonResult<List<DeptSimpleRespDTO>> getSimpleDeptList() {
List<DeptDO> depts = deptService.getDeptList(
new DeptListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
return success(BeanUtils.toBean(depts, DeptSimpleRespDTO.class));
}
@Override
public CommonResult<List<DeptSimpleRespDTO>> getSimpleCompanyList() {
List<DeptDO> companies = deptService.getUserCompanyList();
return success(BeanUtils.toBean(companies, DeptSimpleRespDTO.class));
}
@Override
public CommonResult<List<DeptSimpleRespDTO>> getAllCompanyList() {
List<DeptDO> allCompanies = deptService.getAllCompanyList();
// 还需要把用户归属的公司加上
List<DeptDO> userCompanyList = deptService.getUserCompanyList();
allCompanies.addAll(userCompanyList);
// 去重
List<DeptDO> companies = allCompanies.stream().distinct().toList();
return success(BeanUtils.toBean(companies, DeptSimpleRespDTO.class));
}
@Override
public CommonResult<DeptRespDTO> getDept(Long id) {
DeptDO dept = deptService.getDept(id);
return success(BeanUtils.toBean(dept, DeptRespDTO.class));
}
@Override
public CommonResult<List<DeptRespDTO>> getDeptList(Collection<Long> ids) {
List<DeptDO> depts = deptService.getDeptList(ids);
return success(BeanUtils.toBean(depts, DeptRespDTO.class));
}
@Override
public CommonResult<Boolean> validateDeptList(Collection<Long> ids) {
deptService.validateDeptList(ids);
return success(true);
}
@Override
public CommonResult<List<DeptRespDTO>> getChildDeptList(Long id) {
List<DeptDO> depts = deptService.getChildDeptList(id);
return success(BeanUtils.toBean(depts, DeptRespDTO.class));
}
@Override
public CommonResult<Set<CompanyDeptInfoRespDTO>> getCompanyDeptInfoListByUserId(Long userId) {
Set<CompanyDeptInfo> companyDeptInfos = deptService.getCompanyDeptInfoListByUserId(userId);
return success(BeanUtils.toBean(companyDeptInfos, CompanyDeptInfoRespDTO.class));
}
}

View File

@@ -0,0 +1,75 @@
package com.zt.plat.module.system.api.dept;
import com.zt.plat.framework.common.enums.CommonStatusEnum;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.module.system.api.dept.dto.PostRespDTO;
import com.zt.plat.module.system.api.dept.dto.PostSaveReqDTO;
import com.zt.plat.module.system.api.dept.dto.PostSimpleRespDTO;
import com.zt.plat.module.system.controller.admin.dept.vo.post.PostSaveReqVO;
import com.zt.plat.module.system.dal.dataobject.dept.PostDO;
import com.zt.plat.module.system.service.dept.PostService;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static com.zt.plat.framework.common.pojo.CommonResult.success;
@RestController // 提供 RESTful API 接口,给 Feign 调用
@Validated
public class PostApiImpl implements PostApi {
@Resource
private PostService postService;
@Override
public CommonResult<Long> createPost(PostSaveReqDTO createReqVO) {
PostSaveReqVO reqVO = BeanUtils.toBean(createReqVO, PostSaveReqVO.class);
Long postId = postService.createPost(reqVO);
return success(postId);
}
@Override
public CommonResult<Boolean> updatePost(PostSaveReqDTO updateReqVO) {
PostSaveReqVO reqVO = BeanUtils.toBean(updateReqVO, PostSaveReqVO.class);
postService.updatePost(reqVO);
return success(true);
}
@Override
public CommonResult<Boolean> deletePost(Long id) {
postService.deletePost(id);
return success(true);
}
@Override
public CommonResult<PostRespDTO> getPost(Long id) {
PostDO post = postService.getPost(id);
return success(BeanUtils.toBean(post, PostRespDTO.class));
}
@Override
public CommonResult<List<PostSimpleRespDTO>> getSimplePostList() {
List<PostDO> posts = postService.getPostList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
posts.sort(Comparator.comparing(PostDO::getSort));
return success(BeanUtils.toBean(posts, PostSimpleRespDTO.class));
}
@Override
public CommonResult<Boolean> validPostList(Collection<Long> ids) {
postService.validatePostList(ids);
return success(true);
}
@Override
public CommonResult<List<PostRespDTO>> getPostList(Collection<Long> ids) {
List<PostDO> list = postService.getPostList(ids);
return success(BeanUtils.toBean(list, PostRespDTO.class));
}
}

View File

@@ -0,0 +1,76 @@
package com.zt.plat.module.system.api.dict;
import com.zt.plat.framework.common.biz.system.dict.dto.DictDataRespDTO;
import com.zt.plat.framework.common.enums.CommonStatusEnum;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.module.system.api.dict.dto.DictDataDetailRespDTO;
import com.zt.plat.module.system.api.dict.dto.DictDataSaveReqDTO;
import com.zt.plat.module.system.api.dict.dto.DictDataSimpleRespDTO;
import com.zt.plat.module.system.controller.admin.dict.vo.data.DictDataSaveReqVO;
import com.zt.plat.module.system.dal.dataobject.dict.DictDataDO;
import com.zt.plat.module.system.service.dict.DictDataService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Primary;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collection;
import java.util.List;
import static com.zt.plat.framework.common.pojo.CommonResult.success;
@RestController // 提供 RESTful API 接口,给 Feign 调用
@Validated
@Primary // 由于 DictDataCommonApi 的存在,必须声明为 @Primary Bean
public class DictDataApiImpl implements DictDataApi {
@Resource
private DictDataService dictDataService;
@Override
public CommonResult<Long> createDictData(DictDataSaveReqDTO createReqVO) {
DictDataSaveReqVO reqVO = BeanUtils.toBean(createReqVO, DictDataSaveReqVO.class);
Long dictDataId = dictDataService.createDictData(reqVO);
return success(dictDataId);
}
@Override
public CommonResult<Boolean> updateDictData(DictDataSaveReqDTO updateReqVO) {
DictDataSaveReqVO reqVO = BeanUtils.toBean(updateReqVO, DictDataSaveReqVO.class);
dictDataService.updateDictData(reqVO);
return success(true);
}
@Override
public CommonResult<Boolean> deleteDictData(Long id) {
dictDataService.deleteDictData(id);
return success(true);
}
@Override
public CommonResult<List<DictDataSimpleRespDTO>> getSimpleDictDataList() {
List<DictDataDO> list = dictDataService.getDictDataList(
CommonStatusEnum.ENABLE.getStatus(), null);
return success(BeanUtils.toBean(list, DictDataSimpleRespDTO.class));
}
@Override
public CommonResult<DictDataDetailRespDTO> getDictData(Long id) {
DictDataDO dictData = dictDataService.getDictData(id);
return success(BeanUtils.toBean(dictData, DictDataDetailRespDTO.class));
}
@Override
public CommonResult<Boolean> validateDictDataList(String dictType, Collection<String> values) {
dictDataService.validateDictDataList(dictType, values);
return success(true);
}
@Override
public CommonResult<List<DictDataRespDTO>> getDictDataList(String dictType) {
List<DictDataDO> list = dictDataService.getDictDataListByDictType(dictType);
return success(BeanUtils.toBean(list, DictDataRespDTO.class));
}
}

Some files were not shown because too many files have changed in this diff Show More