فهرست منبع

1、增加行业管理模块
2、增加职位管理模块

rayson 1 سال پیش
والد
کامیت
75957972ef
37فایلهای تغییر یافته به همراه1352 افزوده شده و 66 حذف شده
  1. 0 4
      menduner/menduner-mall-biz/src/main/java/com/citu/menduner/mall/package-info.java
  2. 1 1
      menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/MendunerMallApplication.java
  3. 4 0
      menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/package-info.java
  4. 2 2
      menduner/menduner-mall-biz/src/main/resources/bootstrap.yaml
  5. 15 0
      menduner/menduner-system-api/src/main/java/com/citu/module/menduner/system/enums/ErrorCodeConstants.java
  6. 1 1
      menduner/menduner-system-biz/Dockerfile
  7. 7 15
      menduner/menduner-system-biz/pom.xml
  8. 0 4
      menduner/menduner-system-biz/src/main/java/com/citu/menduner/system/package-info.java
  9. 1 1
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/MendunerSystemApplication.java
  10. 94 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/industry/IndustryController.java
  11. 35 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/industry/vo/IndustryPageReqVO.java
  12. 38 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/industry/vo/IndustryRespVO.java
  13. 24 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/industry/vo/IndustrySaveReqVO.java
  14. 93 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/position/PositionController.java
  15. 33 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/position/vo/PositionPageReqVO.java
  16. 48 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/position/vo/PositionRespVO.java
  17. 31 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/position/vo/PositionSaveReqVO.java
  18. 38 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/industry/IndustryDO.java
  19. 54 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/position/PositionDO.java
  20. 27 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/industry/IndustryMapper.java
  21. 28 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/position/PositionMapper.java
  22. 22 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/datapermission/config/DataPermissionConfiguration.java
  23. 4 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/datapermission/package-info.java
  24. 38 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/security/config/SecurityConfiguration.java
  25. 4 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/security/core/package-info.java
  26. 4 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/package-info.java
  27. 55 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/industry/IndustryService.java
  28. 73 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/industry/IndustryServiceImpl.java
  29. 55 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/position/PositionService.java
  30. 71 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/position/PositionServiceImpl.java
  31. 77 9
      menduner/menduner-system-biz/src/main/resources/application-dev.yaml
  32. 99 25
      menduner/menduner-system-biz/src/main/resources/application-local.yaml
  33. 1 1
      menduner/menduner-system-biz/src/main/resources/application.yaml
  34. 2 2
      menduner/menduner-system-biz/src/main/resources/bootstrap.yaml
  35. 133 0
      menduner/menduner-system-biz/src/test/java/com/citu/module/menduner/system/service/industry/IndustryServiceImplTest.java
  36. 139 0
      menduner/menduner-system-biz/src/test/java/com/citu/module/menduner/system/service/position/PositionServiceImplTest.java
  37. 1 1
      pom.xml

+ 0 - 4
menduner/menduner-mall-biz/src/main/java/com/citu/menduner/mall/package-info.java

@@ -1,4 +0,0 @@
-/**
- * menduner 求职模块
- */
-package com.citu.menduner.mall;

+ 1 - 1
menduner/menduner-mall-biz/src/main/java/com/citu/menduner/mall/MendunerMallApplication.java → menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/MendunerMallApplication.java

@@ -1,4 +1,4 @@
-package com.citu.menduner.mall;
+package com.citu.module.menduner.mall;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;

+ 4 - 0
menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/package-info.java

@@ -0,0 +1,4 @@
+/**
+ * menduner 求职模块
+ */
+package com.citu.module.menduner.mall;

+ 2 - 2
menduner/menduner-mall-biz/src/main/resources/bootstrap.yaml

@@ -1,12 +1,12 @@
 spring:
   application:
-    name: menduner-job-service
+    name: menduner-service
 
   profiles:
     active: local
 
 server:
-  port: 48100
+  port: 48200
 
 # 日志文件配置。注意,如果 logging.file.name 不放在 bootstrap.yaml 配置文件,而是放在 application.yaml 中,会导致出现 LOG_FILE_IS_UNDEFINED 文件
 logging:

+ 15 - 0
menduner/menduner-system-api/src/main/java/com/citu/module/menduner/system/enums/ErrorCodeConstants.java

@@ -0,0 +1,15 @@
+package com.citu.module.menduner.system.enums;
+
+import com.citu.framework.common.exception.ErrorCode;
+
+/**
+ * 门墩儿 后台 错误码枚举类
+ **/
+public interface ErrorCodeConstants {
+
+    // ========== 行业信息 1_100_001_000 ==========
+    ErrorCode INDUSTRY_NOT_EXISTS = new ErrorCode(1_100_001_001, "行业信息不存在");
+
+    // ========== 职位信息 1_100_002_000 ==========
+    ErrorCode POSITION_NOT_EXISTS = new ErrorCode(1_100_002_001, "职位信息不存在");
+}

+ 1 - 1
menduner/menduner-system-biz/Dockerfile

@@ -13,7 +13,7 @@ COPY ./target/menduner-system-biz.jar app.jar
 ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx512m"
 
 ## 暴露后端项目的 48080 端口
-EXPOSE 48100
+EXPOSE 48200
 
 ## 启动后端项目
 CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

+ 7 - 15
menduner/menduner-system-biz/pom.xml

@@ -32,12 +32,7 @@
         <!-- 依赖服务 -->
         <dependency>
             <groupId>com.citu</groupId>
-            <artifactId>citu-module-system-api</artifactId>
-            <version>${revision}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.citu</groupId>
-            <artifactId>citu-module-infra-api</artifactId>
+            <artifactId>menduner-system-api</artifactId>
             <version>${revision}</version>
         </dependency>
 
@@ -50,10 +45,6 @@
             <groupId>com.citu</groupId>
             <artifactId>citu-spring-boot-starter-biz-tenant</artifactId>
         </dependency>
-        <dependency>
-            <groupId>com.citu</groupId>
-            <artifactId>citu-spring-boot-starter-biz-ip</artifactId>
-        </dependency>
 
         <!-- Web 相关 -->
         <dependency>
@@ -67,11 +58,6 @@
             <artifactId>citu-spring-boot-starter-mybatis</artifactId>
         </dependency>
 
-        <dependency>
-            <groupId>com.citu</groupId>
-            <artifactId>citu-spring-boot-starter-redis</artifactId>
-        </dependency>
-
         <!-- RPC 远程调用相关 -->
         <dependency>
             <groupId>com.citu</groupId>
@@ -103,6 +89,12 @@
             <artifactId>citu-spring-boot-starter-monitor</artifactId>
         </dependency>
 
+        <!-- 工具类相关 -->
+        <dependency>
+            <groupId>com.citu</groupId>
+            <artifactId>citu-spring-boot-starter-excel</artifactId>
+        </dependency>
+
 
 
     </dependencies>

+ 0 - 4
menduner/menduner-system-biz/src/main/java/com/citu/menduner/system/package-info.java

@@ -1,4 +0,0 @@
-/**
- * menduner 招聘模块
- */
-package com.citu.menduner.system;

+ 1 - 1
menduner/menduner-system-biz/src/main/java/com/citu/menduner/system/MendunerSystemApplication.java → menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/MendunerSystemApplication.java

@@ -1,4 +1,4 @@
-package com.citu.menduner.system;
+package com.citu.module.menduner.system;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;

+ 94 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/industry/IndustryController.java

@@ -0,0 +1,94 @@
+package com.citu.module.menduner.system.controller.admin.industry;
+
+import com.citu.framework.apilog.core.annotation.ApiAccessLog;
+import com.citu.framework.common.pojo.CommonResult;
+import com.citu.framework.common.pojo.PageParam;
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.common.util.object.BeanUtils;
+import com.citu.framework.excel.core.util.ExcelUtils;
+import com.citu.module.menduner.system.controller.admin.industry.vo.IndustryPageReqVO;
+import com.citu.module.menduner.system.controller.admin.industry.vo.IndustryRespVO;
+import com.citu.module.menduner.system.controller.admin.industry.vo.IndustrySaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.industry.IndustryDO;
+import com.citu.module.menduner.system.service.industry.IndustryService;
+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.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.List;
+
+import static com.citu.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
+import static com.citu.framework.common.pojo.CommonResult.success;
+
+
+@Tag(name = "管理后台 - 行业信息")
+@RestController
+@RequestMapping("/mde/industry")
+@Validated
+public class IndustryController {
+
+    @Resource
+    private IndustryService industryService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建行业信息")
+    @PreAuthorize("@ss.hasPermission('mde:industry:create')")
+    public CommonResult<Long> createIndustry(@Valid @RequestBody IndustrySaveReqVO createReqVO) {
+        return success(industryService.createIndustry(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新行业信息")
+    @PreAuthorize("@ss.hasPermission('mde:industry:update')")
+    public CommonResult<Boolean> updateIndustry(@Valid @RequestBody IndustrySaveReqVO updateReqVO) {
+        industryService.updateIndustry(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除行业信息")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('mde:industry:delete')")
+    public CommonResult<Boolean> deleteIndustry(@RequestParam("id") Long id) {
+        industryService.deleteIndustry(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得行业信息")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('mde:industry:query')")
+    public CommonResult<IndustryRespVO> getIndustry(@RequestParam("id") Long id) {
+        IndustryDO industry = industryService.getIndustry(id);
+        return success(BeanUtils.toBean(industry, IndustryRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得行业信息分页")
+    @PreAuthorize("@ss.hasPermission('mde:industry:query')")
+    public CommonResult<PageResult<IndustryRespVO>> getIndustryPage(@Valid IndustryPageReqVO pageReqVO) {
+        PageResult<IndustryDO> pageResult = industryService.getIndustryPage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, IndustryRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出行业信息 Excel")
+    @PreAuthorize("@ss.hasPermission('mde:industry:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportIndustryExcel(@Valid IndustryPageReqVO pageReqVO,
+                                    HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<IndustryDO> list = industryService.getIndustryPage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "行业信息.xls", "数据", IndustryRespVO.class,
+                BeanUtils.toBean(list, IndustryRespVO.class));
+    }
+
+}

+ 35 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/industry/vo/IndustryPageReqVO.java

@@ -0,0 +1,35 @@
+package com.citu.module.menduner.system.controller.admin.industry.vo;
+
+import com.citu.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+import static com.citu.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+/**
+ * @author rayson
+ * @description 行业信息分页 Request VO
+ * @create 2024/4/28 下午5:03
+ **/
+@Schema(description = "管理后台 - 行业信息分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class IndustryPageReqVO extends PageParam {
+
+    @Schema(description = "行业中文名称")
+    private String nameCn;
+
+    @Schema(description = "行业英文名称")
+    private String nameEn;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

+ 38 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/industry/vo/IndustryRespVO.java

@@ -0,0 +1,38 @@
+package com.citu.module.menduner.system.controller.admin.industry.vo;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import java.util.*;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+import com.alibaba.excel.annotation.*;
+
+/**
+ * @author rayson
+ * @description IndustryRespVO 行业信息 Response VO
+ * @create 2024/4/28 下午5:04
+ **/
+@Schema(description = "管理后台 - 行业信息 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class IndustryRespVO {
+
+    @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "7293")
+    @ExcelProperty("id")
+    private Long id;
+
+    @Schema(description = "行业中文名称")
+    @ExcelProperty("行业中文名称")
+    private String nameCn;
+
+    @Schema(description = "行业英文名称")
+    @ExcelProperty("行业英文名称")
+    private String nameEn;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 24 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/industry/vo/IndustrySaveReqVO.java

@@ -0,0 +1,24 @@
+package com.citu.module.menduner.system.controller.admin.industry.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * @author rayson
+ * @description IndustrySaveReqVO 行业信息新增/修改 Request VO
+ * @create 2024/4/28 下午5:06
+ **/
+@Schema(description = "管理后台 - 行业信息新增/修改 Request VO")
+@Data
+public class IndustrySaveReqVO {
+
+    @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "7293")
+    private Long id;
+
+    @Schema(description = "行业中文名称")
+    private String nameCn;
+
+    @Schema(description = "行业英文名称")
+    private String nameEn;
+
+}

+ 93 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/position/PositionController.java

@@ -0,0 +1,93 @@
+package com.citu.module.menduner.system.controller.admin.position;
+
+import com.citu.framework.apilog.core.annotation.ApiAccessLog;
+import com.citu.framework.common.pojo.CommonResult;
+import com.citu.framework.common.pojo.PageParam;
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.common.util.object.BeanUtils;
+import com.citu.framework.excel.core.util.ExcelUtils;
+import com.citu.module.menduner.system.controller.admin.position.vo.PositionPageReqVO;
+import com.citu.module.menduner.system.controller.admin.position.vo.PositionRespVO;
+import com.citu.module.menduner.system.controller.admin.position.vo.PositionSaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.position.PositionDO;
+import com.citu.module.menduner.system.service.position.PositionService;
+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.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.List;
+
+import static com.citu.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
+import static com.citu.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "管理后台 - 职位信息")
+@RestController
+@RequestMapping("/menduner.system/position")
+@Validated
+public class PositionController {
+
+    @Resource
+    private PositionService positionService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建职位信息")
+    @PreAuthorize("@ss.hasPermission('menduner.system:position:create')")
+    public CommonResult<Long> createPosition(@Valid @RequestBody PositionSaveReqVO createReqVO) {
+        return success(positionService.createPosition(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新职位信息")
+    @PreAuthorize("@ss.hasPermission('menduner.system:position:update')")
+    public CommonResult<Boolean> updatePosition(@Valid @RequestBody PositionSaveReqVO updateReqVO) {
+        positionService.updatePosition(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除职位信息")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('menduner.system:position:delete')")
+    public CommonResult<Boolean> deletePosition(@RequestParam("id") Long id) {
+        positionService.deletePosition(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得职位信息")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('menduner.system:position:query')")
+    public CommonResult<PositionRespVO> getPosition(@RequestParam("id") Long id) {
+        PositionDO position = positionService.getPosition(id);
+        return success(BeanUtils.toBean(position, PositionRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得职位信息分页")
+    @PreAuthorize("@ss.hasPermission('menduner.system:position:query')")
+    public CommonResult<PageResult<PositionRespVO>> getPositionPage(@Valid PositionPageReqVO pageReqVO) {
+        PageResult<PositionDO> pageResult = positionService.getPositionPage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, PositionRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出职位信息 Excel")
+    @PreAuthorize("@ss.hasPermission('menduner.system:position:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportPositionExcel(@Valid PositionPageReqVO pageReqVO,
+                                    HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<PositionDO> list = positionService.getPositionPage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "职位信息.xls", "数据", PositionRespVO.class,
+                BeanUtils.toBean(list, PositionRespVO.class));
+    }
+
+}

+ 33 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/position/vo/PositionPageReqVO.java

@@ -0,0 +1,33 @@
+package com.citu.module.menduner.system.controller.admin.position.vo;
+
+import lombok.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import com.citu.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+import static com.citu.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 职位信息分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class PositionPageReqVO extends PageParam {
+
+    @Schema(description = "职位中文名称")
+    private String nameCn;
+
+    @Schema(description = "职位英文名称")
+    private String nameEn;
+
+    @Schema(description = "上级id", example = "11085")
+    private Long parentId;
+
+    @Schema(description = "层级")
+    private Boolean level;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

+ 48 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/position/vo/PositionRespVO.java

@@ -0,0 +1,48 @@
+package com.citu.module.menduner.system.controller.admin.position.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import java.util.*;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+import com.alibaba.excel.annotation.*;
+
+@Schema(description = "管理后台 - 职位信息 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class PositionRespVO {
+
+    @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "27892")
+    @ExcelProperty("id")
+    private Long id;
+
+    @Schema(description = "职位中文名称")
+    @ExcelProperty("职位中文名称")
+    private String nameCn;
+
+    @Schema(description = "职位英文名称")
+    @ExcelProperty("职位英文名称")
+    private String nameEn;
+
+    @Schema(description = "上级id", example = "11085")
+    @ExcelProperty("上级id")
+    private Long parentId;
+
+    @Schema(description = "层级")
+    @ExcelProperty("层级")
+    private Boolean level;
+
+    @Schema(description = "默认职位要求")
+    @ExcelProperty("默认职位要求")
+    private String requirement;
+
+    @Schema(description = "默认职位描述内容")
+    @ExcelProperty("默认职位描述内容")
+    private String describe;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 31 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/position/vo/PositionSaveReqVO.java

@@ -0,0 +1,31 @@
+package com.citu.module.menduner.system.controller.admin.position.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - 职位信息新增/修改 Request VO")
+@Data
+public class PositionSaveReqVO {
+
+    @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "27892")
+    private Long id;
+
+    @Schema(description = "职位中文名称")
+    private String nameCn;
+
+    @Schema(description = "职位英文名称")
+    private String nameEn;
+
+    @Schema(description = "上级id", example = "11085")
+    private Long parentId;
+
+    @Schema(description = "层级")
+    private Boolean level;
+
+    @Schema(description = "默认职位要求")
+    private String requirement;
+
+    @Schema(description = "默认职位描述内容")
+    private String describe;
+
+}

+ 38 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/industry/IndustryDO.java

@@ -0,0 +1,38 @@
+package com.citu.module.menduner.system.dal.dataobject.industry;
+
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.citu.framework.mybatis.core.dataobject.BaseDO;
+import lombok.*;
+
+/**
+ * 行业信息 DO
+ *
+ * @author Rayson
+ */
+@TableName("mde_industry")
+@KeySequence("mde_industry_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class IndustryDO extends BaseDO {
+
+    /**
+     * id
+     */
+    @TableId
+    private Long id;
+    /**
+     * 行业中文名称
+     */
+    private String nameCn;
+    /**
+     * 行业英文名称
+     */
+    private String nameEn;
+
+}

+ 54 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/position/PositionDO.java

@@ -0,0 +1,54 @@
+package com.citu.module.menduner.system.dal.dataobject.position;
+
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.citu.framework.mybatis.core.dataobject.BaseDO;
+import lombok.*;
+
+/**
+ * 职位信息 DO
+ *
+ * @author Rayson
+ */
+@TableName("mde_position")
+@KeySequence("mde_position_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class PositionDO extends BaseDO {
+
+    /**
+     * id
+     */
+    @TableId
+    private Long id;
+    /**
+     * 职位中文名称
+     */
+    private String nameCn;
+    /**
+     * 职位英文名称
+     */
+    private String nameEn;
+    /**
+     * 上级id
+     */
+    private Long parentId;
+    /**
+     * 层级
+     */
+    private Boolean level;
+    /**
+     * 默认职位要求
+     */
+    private String requirement;
+    /**
+     * 默认职位描述内容
+     */
+    private String describe;
+
+}

+ 27 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/industry/IndustryMapper.java

@@ -0,0 +1,27 @@
+package com.citu.module.menduner.system.dal.mysql.industry;
+
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.mybatis.core.mapper.BaseMapperX;
+import com.citu.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.citu.module.menduner.system.controller.admin.industry.vo.IndustryPageReqVO;
+import com.citu.module.menduner.system.dal.dataobject.industry.IndustryDO;
+import org.apache.ibatis.annotations.Mapper;
+
+
+/**
+ * 行业信息 Mapper
+ *
+ * @author Rayson
+ */
+@Mapper
+public interface IndustryMapper extends BaseMapperX<IndustryDO> {
+
+    default PageResult<IndustryDO> selectPage(IndustryPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<IndustryDO>()
+                .eqIfPresent(IndustryDO::getNameCn, reqVO.getNameCn())
+                .eqIfPresent(IndustryDO::getNameEn, reqVO.getNameEn())
+                .betweenIfPresent(IndustryDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(IndustryDO::getId));
+    }
+
+}

+ 28 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/position/PositionMapper.java

@@ -0,0 +1,28 @@
+package com.citu.module.menduner.system.dal.mysql.position;
+
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.mybatis.core.mapper.BaseMapperX;
+import com.citu.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.citu.module.menduner.system.controller.admin.position.vo.PositionPageReqVO;
+import com.citu.module.menduner.system.dal.dataobject.position.PositionDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 职位信息 Mapper
+ *
+ * @author Rayson
+ */
+@Mapper
+public interface PositionMapper extends BaseMapperX<PositionDO> {
+
+    default PageResult<PositionDO> selectPage(PositionPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<PositionDO>()
+                .eqIfPresent(PositionDO::getNameCn, reqVO.getNameCn())
+                .eqIfPresent(PositionDO::getNameEn, reqVO.getNameEn())
+                .eqIfPresent(PositionDO::getParentId, reqVO.getParentId())
+                .eqIfPresent(PositionDO::getLevel, reqVO.getLevel())
+                .betweenIfPresent(PositionDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(PositionDO::getId));
+    }
+
+}

+ 22 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/datapermission/config/DataPermissionConfiguration.java

@@ -0,0 +1,22 @@
+package com.citu.module.menduner.system.framework.datapermission.config;
+
+import com.citu.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * system 模块的数据权限 Configuration
+ *
+ * @author 芋道源码
+ */
+@Configuration(proxyBeanMethods = false)
+public class DataPermissionConfiguration {
+
+    @Bean
+    public DeptDataPermissionRuleCustomizer sysDeptDataPermissionRuleCustomizer() {
+        return rule -> {
+
+        };
+    }
+
+}

+ 4 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/datapermission/package-info.java

@@ -0,0 +1,4 @@
+/**
+ * system 模块的数据权限配置
+ */
+package com.citu.module.menduner.system.framework.datapermission;

+ 38 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/security/config/SecurityConfiguration.java

@@ -0,0 +1,38 @@
+package com.citu.module.menduner.system.framework.security.config;
+
+import com.citu.framework.security.config.AuthorizeRequestsCustomizer;
+import com.citu.module.system.enums.ApiConstants;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
+
+/**
+ * menduner 模块的 Security 配置
+ */
+@Configuration("mendunerSecurityConfiguration")
+public class SecurityConfiguration {
+
+    @Bean("mendunerAuthorizeRequestsCustomizer")
+    public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
+        return new AuthorizeRequestsCustomizer() {
+
+            @Override
+            public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
+                // TODO 芋艿:这个每个项目都需要重复配置,得捉摸有没通用的方案
+                // Swagger 接口文档
+                registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据
+                        .antMatchers("/swagger-ui.html").permitAll(); // Swagger UI
+                // Druid 监控
+                registry.antMatchers("/druid/**").anonymous();
+                // Spring Boot Actuator 的安全配置
+                registry.antMatchers("/actuator").anonymous()
+                        .antMatchers("/actuator/**").anonymous();
+                // RPC 服务的安全配置
+                registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll();
+            }
+
+        };
+    }
+
+}

+ 4 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/security/core/package-info.java

@@ -0,0 +1,4 @@
+/**
+ * 占位
+ */
+package com.citu.module.menduner.system.framework.security.core;

+ 4 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/package-info.java

@@ -0,0 +1,4 @@
+/**
+ * menduner 招聘模块
+ */
+package com.citu.module.menduner.system;

+ 55 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/industry/IndustryService.java

@@ -0,0 +1,55 @@
+package com.citu.module.menduner.system.service.industry;
+
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.module.menduner.system.controller.admin.industry.vo.IndustryPageReqVO;
+import com.citu.module.menduner.system.controller.admin.industry.vo.IndustrySaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.industry.IndustryDO;
+
+import javax.validation.Valid;
+
+/**
+ * 行业信息 Service 接口
+ *
+ * @author Rayson
+ */
+public interface IndustryService {
+
+    /**
+     * 创建行业信息
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createIndustry(@Valid IndustrySaveReqVO createReqVO);
+
+    /**
+     * 更新行业信息
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateIndustry(@Valid IndustrySaveReqVO updateReqVO);
+
+    /**
+     * 删除行业信息
+     *
+     * @param id 编号
+     */
+    void deleteIndustry(Long id);
+
+    /**
+     * 获得行业信息
+     *
+     * @param id 编号
+     * @return 行业信息
+     */
+    IndustryDO getIndustry(Long id);
+
+    /**
+     * 获得行业信息分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 行业信息分页
+     */
+    PageResult<IndustryDO> getIndustryPage(IndustryPageReqVO pageReqVO);
+
+}

+ 73 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/industry/IndustryServiceImpl.java

@@ -0,0 +1,73 @@
+package com.citu.module.menduner.system.service.industry;
+
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.common.util.object.BeanUtils;
+import com.citu.module.menduner.system.controller.admin.industry.vo.IndustryPageReqVO;
+import com.citu.module.menduner.system.controller.admin.industry.vo.IndustrySaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.industry.IndustryDO;
+import com.citu.module.menduner.system.dal.mysql.industry.IndustryMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+
+import javax.annotation.Resource;
+
+import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.citu.module.menduner.system.enums.ErrorCodeConstants.INDUSTRY_NOT_EXISTS;
+
+
+/**
+ * 行业信息 Service 实现类
+ *
+ * @author Rayson
+ */
+@Service
+@Validated
+public class IndustryServiceImpl implements IndustryService {
+
+    @Resource
+    private IndustryMapper industryMapper;
+
+    @Override
+    public Long createIndustry(IndustrySaveReqVO createReqVO) {
+        // 插入
+        IndustryDO industry = BeanUtils.toBean(createReqVO, IndustryDO.class);
+        industryMapper.insert(industry);
+        // 返回
+        return industry.getId();
+    }
+
+    @Override
+    public void updateIndustry(IndustrySaveReqVO updateReqVO) {
+        // 校验存在
+        validateIndustryExists(updateReqVO.getId());
+        // 更新
+        IndustryDO updateObj = BeanUtils.toBean(updateReqVO, IndustryDO.class);
+        industryMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteIndustry(Long id) {
+        // 校验存在
+        validateIndustryExists(id);
+        // 删除
+        industryMapper.deleteById(id);
+    }
+
+    private void validateIndustryExists(Long id) {
+        if (industryMapper.selectById(id) == null) {
+            throw exception(INDUSTRY_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public IndustryDO getIndustry(Long id) {
+        return industryMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<IndustryDO> getIndustryPage(IndustryPageReqVO pageReqVO) {
+        return industryMapper.selectPage(pageReqVO);
+    }
+
+}

+ 55 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/position/PositionService.java

@@ -0,0 +1,55 @@
+package com.citu.module.menduner.system.service.position;
+
+import java.util.*;
+import javax.validation.*;
+import com.citu.module.menduner.system.controller.admin.position.vo.*;
+import com.citu.module.menduner.system.dal.dataobject.position.PositionDO;
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.common.pojo.PageParam;
+
+/**
+ * 职位信息 Service 接口
+ *
+ * @author Rayson
+ */
+public interface PositionService {
+
+    /**
+     * 创建职位信息
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createPosition(@Valid PositionSaveReqVO createReqVO);
+
+    /**
+     * 更新职位信息
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updatePosition(@Valid PositionSaveReqVO updateReqVO);
+
+    /**
+     * 删除职位信息
+     *
+     * @param id 编号
+     */
+    void deletePosition(Long id);
+
+    /**
+     * 获得职位信息
+     *
+     * @param id 编号
+     * @return 职位信息
+     */
+    PositionDO getPosition(Long id);
+
+    /**
+     * 获得职位信息分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 职位信息分页
+     */
+    PageResult<PositionDO> getPositionPage(PositionPageReqVO pageReqVO);
+
+}

+ 71 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/position/PositionServiceImpl.java

@@ -0,0 +1,71 @@
+package com.citu.module.menduner.system.service.position;
+
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.common.util.object.BeanUtils;
+import com.citu.module.menduner.system.controller.admin.position.vo.PositionPageReqVO;
+import com.citu.module.menduner.system.controller.admin.position.vo.PositionSaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.position.PositionDO;
+import com.citu.module.menduner.system.dal.mysql.position.PositionMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+
+import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.citu.module.menduner.system.enums.ErrorCodeConstants.POSITION_NOT_EXISTS;
+
+/**
+ * 职位信息 Service 实现类
+ *
+ * @author Rayson
+ */
+@Service
+@Validated
+public class PositionServiceImpl implements PositionService {
+
+    @Resource
+    private PositionMapper positionMapper;
+
+    @Override
+    public Long createPosition(PositionSaveReqVO createReqVO) {
+        // 插入
+        PositionDO position = BeanUtils.toBean(createReqVO, PositionDO.class);
+        positionMapper.insert(position);
+        // 返回
+        return position.getId();
+    }
+
+    @Override
+    public void updatePosition(PositionSaveReqVO updateReqVO) {
+        // 校验存在
+        validatePositionExists(updateReqVO.getId());
+        // 更新
+        PositionDO updateObj = BeanUtils.toBean(updateReqVO, PositionDO.class);
+        positionMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deletePosition(Long id) {
+        // 校验存在
+        validatePositionExists(id);
+        // 删除
+        positionMapper.deleteById(id);
+    }
+
+    private void validatePositionExists(Long id) {
+        if (positionMapper.selectById(id) == null) {
+            throw exception(POSITION_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public PositionDO getPosition(Long id) {
+        return positionMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<PositionDO> getPositionPage(PositionPageReqVO pageReqVO) {
+        return positionMapper.selectPage(pageReqVO);
+    }
+
+}

+ 77 - 9
menduner/menduner-system-biz/src/main/resources/application-dev.yaml

@@ -3,6 +3,7 @@ spring:
   # 数据源配置项
   autoconfigure:
     exclude:
+      - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
   datasource:
     druid: # Druid 【监控】相关的全局配置
       web-stat-filter:
@@ -51,15 +52,29 @@ spring:
           password: 3WLiVUBEwTbvAfsh
 
   # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
-  data:
-    redis:
-      host: 400-infra.server.iocoder.cn # 地址
-      port: 6379 # 端口
-      database: 1 # 数据库索引
-#      password: 123456 # 密码,建议生产环境开启
+  redis:
+    host: 400-infra.server.iocoder.cn # 地址
+    port: 6379 # 端口
+    database: 1 # 数据库索引
+#    password: 123456 # 密码,建议生产环境开启
 
 --- #################### MQ 消息队列相关配置 ####################
 
+# rocketmq 配置项,对应 RocketMQProperties 配置类
+rocketmq:
+  name-server: 127.0.0.1:9876 # RocketMQ Namesrv
+
+spring:
+  # RabbitMQ 配置项,对应 RabbitProperties 配置类
+  rabbitmq:
+    host: 127.0.0.1 # RabbitMQ 服务的地址
+    port: 5672 # RabbitMQ 服务的端口
+    username: guest # RabbitMQ 服务的账号
+    password: guest # RabbitMQ 服务的密码
+  # Kafka 配置项,对应 KafkaProperties 配置类
+  kafka:
+    bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
+
 --- #################### 定时任务相关配置 ####################
 xxl:
   job:
@@ -94,13 +109,66 @@ spring:
       # Spring Boot Admin Server 服务端的相关配置
       context-path: /admin # 配置 Spring
 
+--- #################### 微信公众号、小程序相关配置 ####################
+wx:
+  mp: # 公众号配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
+    #    app-id: wx041349c6f39b268b
+    #    secret: 5abee519483bc9f8cb37ce280e814bd0
+    app-id: wx5b23ba7a5589ecbb # 测试号
+    secret: 2a7b3b20c537e52e74afd395eb85f61f
+    # 存储配置,解决 AccessToken 的跨节点的共享
+    config-storage:
+      type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
+      key-prefix: wx # Redis Key 的前缀
+      http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
+  miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
+    #    appid: wx62056c0d5e8db250
+    #    secret: 333ae72f41552af1e998fe1f54e1584a
+    appid: wx63c280fe3248a3e7 # wenhualian的接口测试号
+    secret: 6f270509224a7ae1296bbf1c8cb97aed
+    config-storage:
+      type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
+      key-prefix: wa # Redis Key 的前缀
+      http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
+
 --- #################### 芋道相关配置 ####################
 
 # 芋道配置项,设置当前项目所有自定义的配置
 citu:
   xss:
     enable: false
-  web:
-    admin-ui:
-      url: http://dashboard.citu.iocoder.cn # Admin 管理后台 UI 的地址
+    exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
+      - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
+      - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
+  pay:
+    pay-notify-url: http://niubi.natapp1.cc/api/pay/order/notify
+    pay-return-url: http://niubi.natapp1.cc/api/pay/order/return
+    refund-notify-url: http://niubi.natapp1.cc/api/pay/refund/notify
   demo: true # 开启演示模式
+
+justauth:
+  enabled: true
+  type:
+    DINGTALK: # 钉钉
+      client-id: dingvrnreaje3yqvzhxg
+      client-secret: i8E6iZyDvZj51JIb0tYsYfVQYOks9Cq1lgryEjFRqC79P3iJcrxEwT6Qk2QvLrLI
+      ignore-check-redirect-uri: true
+    WECHAT_ENTERPRISE: # 企业微信
+      client-id: wwd411c69a39ad2e54
+      client-secret: 1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw
+      agent-id: 1000004
+      ignore-check-redirect-uri: true
+    # noinspection SpringBootApplicationYaml
+    WECHAT_MINI_APP: # 微信小程序
+      client-id: ${wx.miniapp.appid}
+      client-secret: ${wx.miniapp.secret}
+      ignore-check-redirect-uri: true
+      ignore-check-state: true # 微信小程序,不会使用到 state,所以不进行校验
+    WECHAT_MP: # 微信公众号
+      client-id: ${wx.mp.app-id}
+      client-secret: ${wx.mp.secret}
+      ignore-check-redirect-uri: true
+  cache:
+    type: REDIS
+    prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE::
+    timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟

+ 99 - 25
menduner/menduner-system-biz/src/main/resources/application-local.yaml

@@ -3,6 +3,7 @@ spring:
   # 数据源配置项
   autoconfigure:
     exclude:
+      - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
       - de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration # 禁用 Spring Boot Admin 的 Client 的自动配置
   datasource:
     druid: # Druid 【监控】相关的全局配置
@@ -39,38 +40,52 @@ spring:
       primary: master
       datasource:
         master:
-          name: ruoyi-vue-pro
-          url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
-#          url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
-#          url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.master.name} # PostgreSQL 连接的示例
-#          url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
-#          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.master.name} # SQLServer 连接的示例
+          name: citu
+          url: jdbc:mysql://192.168.3.80:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
+          #          url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
+          #          url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.master.name} # PostgreSQL 连接的示例
+          #          url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
+          #          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.master.name} # SQLServer 连接的示例
           username: root
           password: 123456
-#          username: sa
-#          password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
+        #          username: sa
+        #          password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
         slave: # 模拟从库,可根据自己需要修改
-          name: ruoyi-vue-pro
-          url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
-#          url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
-#          url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例
-#          url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
-#          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.slave.name} # SQLServer 连接的示例
+          name: citu
+          url: jdbc:mysql://192.168.3.80:3306/${spring.datasource.dynamic.datasource.slave.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
+          #          url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
+          #          url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例
+          #          url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
+          #          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.slave.name} # SQLServer 连接的示例
           username: root
           password: 123456
-#          username: sa
-#          password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
+  #          username: sa
+  #          password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
 
   # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
-  data:
-    redis:
-      host: 127.0.0.1 # 地址
-      port: 6379 # 端口
-      database: 0 # 数据库索引
-#      password: 123456 # 密码,建议生产环境开启
+  redis:
+    host: 192.168.3.80 # 地址
+    port: 6379 # 端口
+    database: 0 # 数据库索引
+#    password: 123456 # 密码,建议生产环境开启
 
 --- #################### MQ 消息队列相关配置 ####################
 
+# rocketmq 配置项,对应 RocketMQProperties 配置类
+rocketmq:
+  name-server: 127.0.0.1:9876 # RocketMQ Namesrv
+
+spring:
+  # RabbitMQ 配置项,对应 RabbitProperties 配置类
+  rabbitmq:
+    host: 127.0.0.1 # RabbitMQ 服务的地址
+    port: 5672 # RabbitMQ 服务的端口
+    username: guest # RabbitMQ 服务的账号
+    password: guest # RabbitMQ 服务的密码
+  # Kafka 配置项,对应 KafkaProperties 配置类
+  kafka:
+    bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
+
 --- #################### 定时任务相关配置 ####################
 
 xxl:
@@ -113,19 +128,78 @@ logging:
     com.citu.module.system.dal.mysql.sensitiveword.SensitiveWordMapper: INFO # 配置 SensitiveWordMapper 的日志级别为 info
     com.citu.module.system.dal.mysql.sms.SmsChannelMapper: INFO # 配置 SmsChannelMapper 的日志级别为 info
 
+--- #################### 微信公众号、小程序相关配置 ####################
+wx:
+  mp: # 公众号配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
+    #    app-id: wx041349c6f39b268b # 测试号(牛希尧提供的)
+    #    secret: 5abee519483bc9f8cb37ce280e814bd0
+    app-id: wx5b23ba7a5589ecbb # 测试号(自己的)
+    secret: 2a7b3b20c537e52e74afd395eb85f61f
+    #    app-id: wxa69ab825b163be19 # 测试号(Kongdy 提供的)
+    #    secret: bd4f9fab889591b62aeac0d7b8d8b4a0
+    # 存储配置,解决 AccessToken 的跨节点的共享
+    config-storage:
+      type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
+      key-prefix: wx # Redis Key 的前缀
+      http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
+  miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
+    #    appid: wx62056c0d5e8db250 # 测试号(牛希尧提供的)
+    #    secret: 333ae72f41552af1e998fe1f54e1584a
+    appid: wx63c280fe3248a3e7 # wenhualian的接口测试号
+    secret: 6f270509224a7ae1296bbf1c8cb97aed
+    #    appid: wxc4598c446f8a9cb3 # 测试号(Kongdy 提供的)
+    #    secret: 4a1a04e07f6a4a0751b39c3064a92c8b
+    config-storage:
+      type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
+      key-prefix: wa # Redis Key 的前缀
+      http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
+
 --- #################### 芋道相关配置 ####################
 
 # 芋道配置项,设置当前项目所有自定义的配置
 citu:
   env: # 多环境的配置项
     tag: ${HOSTNAME}
-  web:
-    admin-ui:
-      url: http://dashboard.citu.iocoder.cn # Admin 管理后台 UI 的地址
+  captcha:
+    enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试
   security:
     mock-enable: true
   xss:
     enable: false
+    exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
+      - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
+      - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
+  pay:
+    pay-notify-url: http://niubi.natapp1.cc/api/pay/order/notify
+    pay-return-url: http://niubi.natapp1.cc/api/pay/order/return
+    refund-notify-url: http://niubi.natapp1.cc/api/pay/refund/notify
   access-log: # 访问日志的配置项
     enable: false
   demo: false # 关闭演示模式
+
+justauth:
+  enabled: true
+  type:
+    DINGTALK: # 钉钉
+      client-id: dingvrnreaje3yqvzhxg
+      client-secret: i8E6iZyDvZj51JIb0tYsYfVQYOks9Cq1lgryEjFRqC79P3iJcrxEwT6Qk2QvLrLI
+      ignore-check-redirect-uri: true
+    WECHAT_ENTERPRISE: # 企业微信
+      client-id: wwd411c69a39ad2e54
+      client-secret: 1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw
+      agent-id: 1000004
+      ignore-check-redirect-uri: true
+    # noinspection SpringBootApplicationYaml
+    WECHAT_MINI_APP: # 微信小程序
+      client-id: ${wx.miniapp.appid}
+      client-secret: ${wx.miniapp.secret}
+      ignore-check-redirect-uri: true
+      ignore-check-state: true # 微信小程序,不会使用到 state,所以不进行校验
+    WECHAT_MP: # 微信公众号
+      client-id: ${wx.mp.app-id}
+      client-secret: ${wx.mp.secret}
+      ignore-check-redirect-uri: true
+  cache:
+    type: REDIS
+    prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE::
+    timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟

+ 1 - 1
menduner/menduner-system-biz/src/main/resources/application.yaml

@@ -93,7 +93,7 @@ xxl:
 citu:
   info:
     version: 1.0.0
-    base-package: com.citu.module.product
+    base-package: com.citu.module.menduner.system
   swagger:
     title: 管理后台
     description: 提供管理员管理的所有功能

+ 2 - 2
menduner/menduner-system-biz/src/main/resources/bootstrap.yaml

@@ -1,12 +1,12 @@
 spring:
   application:
-    name: menduner-recruitment-service
+    name: menduner-service
 
   profiles:
     active: local
 
 server:
-  port: 48100
+  port: 48200
 
 # 日志文件配置。注意,如果 logging.file.name 不放在 bootstrap.yaml 配置文件,而是放在 application.yaml 中,会导致出现 LOG_FILE_IS_UNDEFINED 文件
 logging:

+ 133 - 0
menduner/menduner-system-biz/src/test/java/com/citu/module/menduner/system/service/industry/IndustryServiceImplTest.java

@@ -0,0 +1,133 @@
+package com.citu.module.menduner.system.service.industry;
+
+
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.test.core.ut.BaseDbUnitTest;
+import com.citu.module.menduner.system.controller.admin.industry.vo.IndustryPageReqVO;
+import com.citu.module.menduner.system.controller.admin.industry.vo.IndustrySaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.industry.IndustryDO;
+import com.citu.module.menduner.system.dal.mysql.industry.IndustryMapper;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.annotation.Import;
+
+import javax.annotation.Resource;
+
+import static com.citu.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
+import static com.citu.framework.common.util.object.ObjectUtils.cloneIgnoreId;
+import static com.citu.framework.test.core.util.AssertUtils.assertPojoEquals;
+import static com.citu.framework.test.core.util.AssertUtils.assertServiceException;
+import static com.citu.framework.test.core.util.RandomUtils.randomLongId;
+import static com.citu.framework.test.core.util.RandomUtils.randomPojo;
+import static com.citu.module.menduner.system.enums.ErrorCodeConstants.INDUSTRY_NOT_EXISTS;
+import static org.junit.jupiter.api.Assertions.*;
+
+
+/**
+ * {@link IndustryServiceImpl} 的单元测试类
+ *
+ * @author Rayson
+ */
+@Import(IndustryServiceImpl.class)
+public class IndustryServiceImplTest extends BaseDbUnitTest {
+
+    @Resource
+    private IndustryServiceImpl industryService;
+
+    @Resource
+    private IndustryMapper industryMapper;
+
+    @Test
+    public void testCreateIndustry_success() {
+        // 准备参数
+        IndustrySaveReqVO createReqVO = randomPojo(IndustrySaveReqVO.class).setId(null);
+
+        // 调用
+        Long industryId = industryService.createIndustry(createReqVO);
+        // 断言
+        assertNotNull(industryId);
+        // 校验记录的属性是否正确
+        IndustryDO industry = industryMapper.selectById(industryId);
+        assertPojoEquals(createReqVO, industry, "id");
+    }
+
+    @Test
+    public void testUpdateIndustry_success() {
+        // mock 数据
+        IndustryDO dbIndustry = randomPojo(IndustryDO.class);
+        industryMapper.insert(dbIndustry);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        IndustrySaveReqVO updateReqVO = randomPojo(IndustrySaveReqVO.class, o -> {
+            o.setId(dbIndustry.getId()); // 设置更新的 ID
+        });
+
+        // 调用
+        industryService.updateIndustry(updateReqVO);
+        // 校验是否更新正确
+        IndustryDO industry = industryMapper.selectById(updateReqVO.getId()); // 获取最新的
+        assertPojoEquals(updateReqVO, industry);
+    }
+
+    @Test
+    public void testUpdateIndustry_notExists() {
+        // 准备参数
+        IndustrySaveReqVO updateReqVO = randomPojo(IndustrySaveReqVO.class);
+
+        // 调用, 并断言异常
+        assertServiceException(() -> industryService.updateIndustry(updateReqVO), INDUSTRY_NOT_EXISTS);
+    }
+
+    @Test
+    public void testDeleteIndustry_success() {
+        // mock 数据
+        IndustryDO dbIndustry = randomPojo(IndustryDO.class);
+        industryMapper.insert(dbIndustry);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        Long id = dbIndustry.getId();
+
+        // 调用
+        industryService.deleteIndustry(id);
+        // 校验数据不存在了
+        assertNull(industryMapper.selectById(id));
+    }
+
+    @Test
+    public void testDeleteIndustry_notExists() {
+        // 准备参数
+        Long id = randomLongId();
+
+        // 调用, 并断言异常
+        assertServiceException(() -> industryService.deleteIndustry(id), INDUSTRY_NOT_EXISTS);
+    }
+
+    @Test
+    @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
+    public void testGetIndustryPage() {
+        // mock 数据
+        IndustryDO dbIndustry = randomPojo(IndustryDO.class, o -> { // 等会查询到
+            o.setNameCn(null);
+            o.setNameEn(null);
+            o.setCreateTime(null);
+        });
+        industryMapper.insert(dbIndustry);
+        // 测试 nameCn 不匹配
+        industryMapper.insert(cloneIgnoreId(dbIndustry, o -> o.setNameCn(null)));
+        // 测试 nameEn 不匹配
+        industryMapper.insert(cloneIgnoreId(dbIndustry, o -> o.setNameEn(null)));
+        // 测试 createTime 不匹配
+        industryMapper.insert(cloneIgnoreId(dbIndustry, o -> o.setCreateTime(null)));
+        // 准备参数
+        IndustryPageReqVO reqVO = new IndustryPageReqVO();
+        reqVO.setNameCn(null);
+        reqVO.setNameEn(null);
+        reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
+
+        // 调用
+        PageResult<IndustryDO> pageResult = industryService.getIndustryPage(reqVO);
+        // 断言
+        assertEquals(1, pageResult.getTotal());
+        assertEquals(1, pageResult.getList().size());
+        assertPojoEquals(dbIndustry, pageResult.getList().get(0));
+    }
+
+}

+ 139 - 0
menduner/menduner-system-biz/src/test/java/com/citu/module/menduner/system/service/position/PositionServiceImplTest.java

@@ -0,0 +1,139 @@
+package com.citu.module.menduner.system.service.position;
+
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+import javax.annotation.Resource;
+
+import com.citu.framework.test.core.ut.BaseDbUnitTest;
+
+import com.citu.module.menduner.system.controller.admin.position.vo.*;
+import com.citu.module.menduner.system.dal.dataobject.position.PositionDO;
+import com.citu.module.menduner.system.dal.mysql.position.PositionMapper;
+import com.citu.framework.common.pojo.PageResult;
+
+import org.springframework.context.annotation.Import;
+
+import static com.citu.module.menduner.system.enums.ErrorCodeConstants.*;
+import static com.citu.framework.test.core.util.AssertUtils.*;
+import static com.citu.framework.test.core.util.RandomUtils.*;
+import static com.citu.framework.common.util.date.LocalDateTimeUtils.*;
+import static com.citu.framework.common.util.object.ObjectUtils.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * {@link PositionServiceImpl} 的单元测试类
+ *
+ * @author Rayson
+ */
+@Import(PositionServiceImpl.class)
+public class PositionServiceImplTest extends BaseDbUnitTest {
+
+    @Resource
+    private PositionServiceImpl positionService;
+
+    @Resource
+    private PositionMapper positionMapper;
+
+    @Test
+    public void testCreatePosition_success() {
+        // 准备参数
+        PositionSaveReqVO createReqVO = randomPojo(PositionSaveReqVO.class).setId(null);
+
+        // 调用
+        Long positionId = positionService.createPosition(createReqVO);
+        // 断言
+        assertNotNull(positionId);
+        // 校验记录的属性是否正确
+        PositionDO position = positionMapper.selectById(positionId);
+        assertPojoEquals(createReqVO, position, "id");
+    }
+
+    @Test
+    public void testUpdatePosition_success() {
+        // mock 数据
+        PositionDO dbPosition = randomPojo(PositionDO.class);
+        positionMapper.insert(dbPosition);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        PositionSaveReqVO updateReqVO = randomPojo(PositionSaveReqVO.class, o -> {
+            o.setId(dbPosition.getId()); // 设置更新的 ID
+        });
+
+        // 调用
+        positionService.updatePosition(updateReqVO);
+        // 校验是否更新正确
+        PositionDO position = positionMapper.selectById(updateReqVO.getId()); // 获取最新的
+        assertPojoEquals(updateReqVO, position);
+    }
+
+    @Test
+    public void testUpdatePosition_notExists() {
+        // 准备参数
+        PositionSaveReqVO updateReqVO = randomPojo(PositionSaveReqVO.class);
+
+        // 调用, 并断言异常
+        assertServiceException(() -> positionService.updatePosition(updateReqVO), POSITION_NOT_EXISTS);
+    }
+
+    @Test
+    public void testDeletePosition_success() {
+        // mock 数据
+        PositionDO dbPosition = randomPojo(PositionDO.class);
+        positionMapper.insert(dbPosition);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        Long id = dbPosition.getId();
+
+        // 调用
+        positionService.deletePosition(id);
+        // 校验数据不存在了
+        assertNull(positionMapper.selectById(id));
+    }
+
+    @Test
+    public void testDeletePosition_notExists() {
+        // 准备参数
+        Long id = randomLongId();
+
+        // 调用, 并断言异常
+        assertServiceException(() -> positionService.deletePosition(id), POSITION_NOT_EXISTS);
+    }
+
+    @Test
+    @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
+    public void testGetPositionPage() {
+        // mock 数据
+        PositionDO dbPosition = randomPojo(PositionDO.class, o -> { // 等会查询到
+            o.setNameCn(null);
+            o.setNameEn(null);
+            o.setParentId(null);
+            o.setLevel(null);
+            o.setCreateTime(null);
+        });
+        positionMapper.insert(dbPosition);
+        // 测试 nameCn 不匹配
+        positionMapper.insert(cloneIgnoreId(dbPosition, o -> o.setNameCn(null)));
+        // 测试 nameEn 不匹配
+        positionMapper.insert(cloneIgnoreId(dbPosition, o -> o.setNameEn(null)));
+        // 测试 parentId 不匹配
+        positionMapper.insert(cloneIgnoreId(dbPosition, o -> o.setParentId(null)));
+        // 测试 level 不匹配
+        positionMapper.insert(cloneIgnoreId(dbPosition, o -> o.setLevel(null)));
+        // 测试 createTime 不匹配
+        positionMapper.insert(cloneIgnoreId(dbPosition, o -> o.setCreateTime(null)));
+        // 准备参数
+        PositionPageReqVO reqVO = new PositionPageReqVO();
+        reqVO.setNameCn(null);
+        reqVO.setNameEn(null);
+        reqVO.setParentId(null);
+        reqVO.setLevel(null);
+        reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
+
+        // 调用
+        PageResult<PositionDO> pageResult = positionService.getPositionPage(reqVO);
+        // 断言
+        assertEquals(1, pageResult.getTotal());
+        assertEquals(1, pageResult.getList().size());
+        assertPojoEquals(dbPosition, pageResult.getList().get(0));
+    }
+
+}

+ 1 - 1
pom.xml

@@ -27,7 +27,7 @@
     </modules>
 
     <name>${project.artifactId}</name>
-    <description>芋道项目基础脚手架</description>
+    <description>辞图基础脚手架</description>
     <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
 
     <properties>