瀏覽代碼

1、增加web内容管理模块
2、增加职位的相关纬度统计

rayson 7 月之前
父節點
當前提交
1287bb3e5a
共有 24 個文件被更改,包括 836 次插入33 次删除
  1. 1 1
      menduner/menduner-common/src/main/java/com/citu/module/menduner/common/dto/TimeRangeBasePageReqVO.java
  2. 6 0
      menduner/menduner-common/src/main/java/com/citu/module/menduner/common/util/TimeUtils.java
  3. 3 0
      menduner/menduner-system-api/src/main/java/com/citu/module/menduner/system/enums/ErrorCodeConstants.java
  4. 22 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/analysis/AnalysisController.java
  5. 8 1
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/analysis/HomeController.java
  6. 94 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/web/WebContentController.java
  7. 3 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/job/vo/AppJobAdvertisedHomeRespVO.java
  8. 3 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/job/vo/AppJobAdvertisedPageReqVO.java
  9. 6 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/analysis/RecruitJobAnalysisRespVO.java
  10. 25 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/web/WebContentPageReqVO.java
  11. 70 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/web/WebContentRespVO.java
  12. 51 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/web/WebContentSaveReqVO.java
  13. 14 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/web/ContentStyle.java
  14. 89 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/web/WebContentDO.java
  15. 64 8
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/job/JobAdvertisedMapper.java
  16. 1 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/job/JobCvRelMapper.java
  17. 25 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/web/WebContentMapper.java
  18. 14 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/job/JobAdvertisedService.java
  19. 60 21
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/job/JobAdvertisedServiceImpl.java
  20. 56 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/web/WebContentService.java
  21. 72 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/web/WebContentServiceImpl.java
  22. 124 0
      menduner/menduner-system-biz/src/test/java/com/citu/module/menduner/system/service/web/WebContentServiceImplTest.java
  23. 2 1
      menduner/menduner-system-biz/src/test/resources/sql/clean.sql
  24. 23 1
      menduner/menduner-system-biz/src/test/resources/sql/create_tables.sql

+ 1 - 1
menduner/menduner-common/src/main/java/com/citu/module/menduner/common/dto/TimeRangeBasePageReqVO.java

@@ -15,7 +15,7 @@ public class TimeRangeBasePageReqVO extends PageParam {
 
     /** {@link com.citu.module.menduner.common.dto.TimeRange} **/
     @Schema(description = "统计类型 -1全部|0最近7天|1上个月|2上季度|3 24小时|4每月|5每年|99自定义", required = true)
-    private String type;
+    private String type = TimeRange.ALL;
 
     @Schema(description = "自定义时间范围")
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)

+ 6 - 0
menduner/menduner-common/src/main/java/com/citu/module/menduner/common/util/TimeUtils.java

@@ -3,6 +3,7 @@ package com.citu.module.menduner.common.util;
 import com.citu.module.menduner.common.dto.TimeRange;
 import com.citu.module.menduner.common.dto.TimeRangeBasePageReqVO;
 import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
+import org.springframework.util.StringUtils;
 
 import java.time.LocalDateTime;
 
@@ -34,6 +35,11 @@ public class TimeUtils {
     private static LocalDateTime[] generateDateTimeRange(String type) {
         LocalDateTime[] dateTimeRange = new LocalDateTime[2];
         LocalDateTime now = LocalDateTime.now();
+        if(!StringUtils.hasText(type)) {
+            dateTimeRange[0] = null;
+            dateTimeRange[1] = null;
+            return dateTimeRange;
+        }
         switch (type) {
             case TimeRange.ALL:
                 dateTimeRange[0] = null;

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

@@ -589,4 +589,7 @@ public interface ErrorCodeConstants {
     // ========== 招聘职位扩展 1_100_057_000 ==========
     ErrorCode JOB_EXTEND_JOB_ID_NOT_NULL = new ErrorCode(1_100_057_001, "招聘职位id不能为空");
 
+    // ========== 页面内容 1_100_058_000 ==========
+    ErrorCode WEB_CONTENT_NOT_EXISTS = new ErrorCode(1_100_058_001, "页面内容不存在");
+
 }

+ 22 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/analysis/AnalysisController.java

@@ -139,6 +139,28 @@ public class AnalysisController {
         return success(jobAdvertisedService.getJobNum(reqVO));
     }
 
+    @GetMapping("/get/job/count")
+    @Operation(summary = "统计发布职位数量")
+    @PreAuthenticated
+    public CommonResult<Map<String, Object[]>> getJobCount(@Valid RecruitAnalysisPageReqVO reqVO) {
+        return success(jobAdvertisedService.getJobCount(reqVO));
+    }
+
+    @GetMapping("/get/job/position/top")
+    @Operation(summary = "前N最多人发布的职位类型")
+    @PreAuthenticated
+    public CommonResult<Map<String, Object[]>> getPositionTypeNumTop(@Valid RecruitAnalysisPageReqVO reqVO) {
+        return success(jobAdvertisedService.getPositionTypeNumTop(reqVO,10));
+    }
+
+    @GetMapping("/get/job/top")
+    @Operation(summary = "最新发布的前N个职位")
+    @PreAuthenticated
+    public CommonResult<List<RecruitJobAnalysisRespVO>> getEnterpriseUserCount(@Valid RecruitAnalysisPageReqVO reqVO) {
+        return success(jobAdvertisedService.getNewJob(reqVO,10));
+    }
+
+
     @GetMapping("/export")
     @Operation(summary = "导出统计分析 Excel")
     @ApiAccessLog(operateType = EXPORT)

+ 8 - 1
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/analysis/HomeController.java

@@ -3,8 +3,12 @@ package com.citu.module.menduner.system.controller.admin.analysis;
 import com.citu.framework.common.pojo.CommonResult;
 import com.citu.framework.security.core.annotations.PreAuthenticated;
 import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
+import com.citu.module.menduner.system.controller.base.CommonRespVO;
+import com.citu.module.menduner.system.controller.base.analysis.RecruitAnalysisPageReqVO;
+import com.citu.module.menduner.system.controller.base.analysis.RecruitJobAnalysisRespVO;
 import com.citu.module.menduner.system.service.enterprise.EnterpriseService;
 import com.citu.module.menduner.system.service.enterprise.bind.EnterpriseUserBindService;
+import com.citu.module.menduner.system.service.job.JobAdvertisedService;
 import com.citu.module.menduner.system.service.person.info.PersonInfoService;
 import com.citu.module.menduner.system.service.user.MdeUserService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -17,6 +21,7 @@ import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
+import java.util.List;
 import java.util.Map;
 
 import static com.citu.framework.common.pojo.CommonResult.success;
@@ -40,6 +45,9 @@ public class HomeController {
     @Resource
     private EnterpriseUserBindService enterpriseUserBindService;
 
+    @Resource
+    private JobAdvertisedService jobAdvertisedService;
+
     @GetMapping("/get/person/count")
     @Operation(summary = "统计新增加人才简历数量")
     @PreAuthenticated
@@ -68,5 +76,4 @@ public class HomeController {
         return success(enterpriseUserBindService.getEnterpriseUserCount(reqVO));
     }
 
-
 }

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

@@ -0,0 +1,94 @@
+package com.citu.module.menduner.system.controller.admin.web;
+
+
+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.base.web.WebContentPageReqVO;
+import com.citu.module.menduner.system.controller.base.web.WebContentRespVO;
+import com.citu.module.menduner.system.controller.base.web.WebContentSaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.web.WebContentDO;
+import com.citu.module.menduner.system.service.web.WebContentService;
+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/web-content")
+@Validated
+public class WebContentController {
+
+    @Resource
+    private WebContentService webContentService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建页面内容")
+    @PreAuthorize("@ss.hasPermission('menduner:system:web-content:create')")
+    public CommonResult<Long> createWebContent(@Valid @RequestBody WebContentSaveReqVO createReqVO) {
+        return success(webContentService.createWebContent(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新页面内容")
+    @PreAuthorize("@ss.hasPermission('menduner:system:web-content:update')")
+    public CommonResult<Boolean> updateWebContent(@Valid @RequestBody WebContentSaveReqVO updateReqVO) {
+        webContentService.updateWebContent(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除页面内容")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('menduner:system:web-content:delete')")
+    public CommonResult<Boolean> deleteWebContent(@RequestParam("id") Long id) {
+        webContentService.deleteWebContent(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得页面内容")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('menduner:system:web-content:query')")
+    public CommonResult<WebContentRespVO> getWebContent(@RequestParam("id") Long id) {
+        WebContentDO webContent = webContentService.getWebContent(id);
+        return success(BeanUtils.toBean(webContent, WebContentRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得页面内容分页")
+    @PreAuthorize("@ss.hasPermission('menduner:system:web-content:query')")
+    public CommonResult<PageResult<WebContentRespVO>> getWebContentPage(@Valid WebContentPageReqVO pageReqVO) {
+        PageResult<WebContentDO> pageResult = webContentService.getWebContentPage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, WebContentRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出页面内容 Excel")
+    @PreAuthorize("@ss.hasPermission('menduner:system:web-content:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportWebContentExcel(@Valid WebContentPageReqVO pageReqVO,
+                                      HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<WebContentDO> list = webContentService.getWebContentPage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "页面内容.xls", "数据", WebContentRespVO.class,
+                BeanUtils.toBean(list, WebContentRespVO.class));
+    }
+
+}

+ 3 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/job/vo/AppJobAdvertisedHomeRespVO.java

@@ -11,6 +11,9 @@ public class AppJobAdvertisedHomeRespVO extends AppJobAdvertisedSimpleRespVO {
     @Schema(description = "企业id", example = "123")
     private Long enterpriseId;
 
+    @Schema(description = "企业名称")
+    private String enterpriseName;
+
     @Schema(description = "企业别称", example = "xx科技")
     private String anotherName;
 

+ 3 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/job/vo/AppJobAdvertisedPageReqVO.java

@@ -39,6 +39,9 @@ public class AppJobAdvertisedPageReqVO extends PageParam {
     @Schema(description = "职位名称", example = "张三")
     private String name;
 
+    @Schema(description = "不包括什么关键字的职位名称", example = "张三")
+    private List<String> notNameList;
+
     @Schema(description = "职位类型id", example = "31707")
     private Long positionId;
 

+ 6 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/analysis/RecruitJobAnalysisRespVO.java

@@ -12,6 +12,12 @@ public class RecruitJobAnalysisRespVO extends JobAdvertisedSimpleRespVO {
     @Schema(description = "企业名称")
     private String enterpriseName;
 
+    @Schema(description = "企业别称", requiredMode = Schema.RequiredMode.REQUIRED, example = "616")
+    private String enterpriseAnotherName;
+
+    @Schema(description = "职位类型")
+    private String positionName;
+
     @Schema(description = "数量")
     private Long num;
 

+ 25 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/web/WebContentPageReqVO.java

@@ -0,0 +1,25 @@
+package com.citu.module.menduner.system.controller.base.web;
+
+
+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;
+
+@Schema(description = "管理后台 - 页面内容分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class WebContentPageReqVO extends PageParam {
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

+ 70 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/web/WebContentRespVO.java

@@ -0,0 +1,70 @@
+package com.citu.module.menduner.system.controller.base.web;
+
+
+import com.citu.module.menduner.system.dal.dataobject.web.ContentStyle;
+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 WebContentRespVO {
+
+    @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "8645")
+    @ExcelProperty("id")
+    private Long id;
+
+    @Schema(description = "pc顶部")
+    @ExcelProperty("pc顶部")
+    private List<ContentStyle> pcTop;
+
+    @Schema(description = "pc左侧")
+    @ExcelProperty("pc左侧")
+    private List<ContentStyle> pcLeft;
+
+    @Schema(description = "pc右侧")
+    @ExcelProperty("pc右侧")
+    private List<ContentStyle> pcRight;
+
+    @Schema(description = "pc广告")
+    @ExcelProperty("pc广告")
+    private List<ContentStyle> pcAdvertisement;
+
+    @Schema(description = "pc首页轮播图")
+    @ExcelProperty("pc首页轮播图")
+    private List<ContentStyle> pcHomeCarousel;
+
+    @Schema(description = "pc登录轮播图")
+    @ExcelProperty("pc登录轮播图")
+    private List<ContentStyle> pcLoginCarousel;
+
+    @Schema(description = "pc登录背景")
+    @ExcelProperty("pc登录背景")
+    private List<ContentStyle> pcLoginBackground;
+
+    @Schema(description = "pc企业端广告")
+    @ExcelProperty("pc企业端广告")
+    private List<ContentStyle> pcBackendAdvertisement;
+
+    @Schema(description = "手机端首页轮播图")
+    @ExcelProperty("手机端首页轮播图")
+    private List<ContentStyle> appHomeCarousel;
+
+    @Schema(description = "手机端广告")
+    @ExcelProperty("手机端广告")
+    private List<ContentStyle> appAdvertisement;
+
+    @Schema(description = "状态(0开启 1关闭)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+    @ExcelProperty("状态(0开启 1关闭)")
+    private String status;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 51 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/web/WebContentSaveReqVO.java

@@ -0,0 +1,51 @@
+package com.citu.module.menduner.system.controller.base.web;
+
+import com.citu.module.menduner.system.dal.dataobject.web.ContentStyle;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+@Schema(description = "管理后台 - 页面内容新增/修改 Request VO")
+@Data
+public class WebContentSaveReqVO {
+
+    @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "8645")
+    private Long id;
+
+    @Schema(description = "pc顶部")
+    private List<ContentStyle> pcTop;
+
+    @Schema(description = "pc左侧")
+    private List<ContentStyle> pcLeft;
+
+    @Schema(description = "pc右侧")
+    private List<ContentStyle> pcRight;
+
+    @Schema(description = "pc广告")
+    private List<ContentStyle> pcAdvertisement;
+
+    @Schema(description = "pc首页轮播图")
+    private List<ContentStyle> pcHomeCarousel;
+
+    @Schema(description = "pc登录轮播图")
+    private List<ContentStyle> pcLoginCarousel;
+
+    @Schema(description = "pc登录背景")
+    private List<ContentStyle> pcLoginBackground;
+
+    @Schema(description = "pc企业端广告")
+    private List<ContentStyle> pcBackendAdvertisement;
+
+    @Schema(description = "手机端首页轮播图")
+    private List<ContentStyle> appHomeCarousel;
+
+    @Schema(description = "手机端广告")
+    private List<ContentStyle> appAdvertisement;
+
+    @Schema(description = "状态(0开启 1关闭)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+    @NotEmpty(message = "状态(0开启 1关闭)不能为空")
+    private String status;
+
+}

+ 14 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/web/ContentStyle.java

@@ -0,0 +1,14 @@
+package com.citu.module.menduner.system.dal.dataobject.web;
+
+import lombok.Data;
+
+@Data
+public class ContentStyle {
+
+    /** 图片地址 **/
+    private String img;
+
+    /** 超链接 **/
+    private String link;
+
+}

+ 89 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/web/WebContentDO.java

@@ -0,0 +1,89 @@
+package com.citu.module.menduner.system.dal.dataobject.web;
+
+
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import com.citu.framework.tenant.core.db.TenantBaseDO;
+import lombok.*;
+
+import java.util.List;
+
+/**
+ * 页面内容 DO
+ *
+ * @author Rayson
+ */
+@TableName(value = "mde_web_content", autoResultMap = true)
+@KeySequence("mde_web_content_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WebContentDO extends TenantBaseDO {
+
+    /**
+     * id
+     */
+    @TableId
+    private Long id;
+    /**
+     * pc顶部
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<ContentStyle> pcTop;
+    /**
+     * pc左侧
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<ContentStyle> pcLeft;
+    /**
+     * pc右侧
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<ContentStyle> pcRight;
+    /**
+     * pc广告
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<ContentStyle> pcAdvertisement;
+    /**
+     * pc首页轮播图
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<ContentStyle> pcHomeCarousel;
+    /**
+     * pc登录轮播图
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<ContentStyle> pcLoginCarousel;
+    /**
+     * pc登录背景
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<ContentStyle> pcLoginBackground;
+    /**
+     * pc企业端广告
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<ContentStyle> pcBackendAdvertisement;
+    /**
+     * 手机端首页轮播图
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<ContentStyle> appHomeCarousel;
+    /**
+     * 手机端广告
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<ContentStyle> appAdvertisement;
+    /**
+     * 状态(0开启 1关闭)
+     */
+    private String status;
+
+}

+ 64 - 8
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/job/JobAdvertisedMapper.java

@@ -8,13 +8,14 @@ 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.framework.mybatis.core.query.MPJLambdaWrapperX;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.job.vo.AppEnterpriseJobRespVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.job.vo.AppJobAdvertisedHomeRespVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.job.vo.AppJobAdvertisedPageReqVO;
-import com.citu.module.menduner.system.controller.app.jobhunt.job.vo.AppJobAdvertisedRespVO;
 import com.citu.module.menduner.system.controller.app.recruit.job.vo.AppRecruitJobExportRespVO;
 import com.citu.module.menduner.system.controller.app.recruit.job.vo.AppRecruitJobPageReqVO;
 import com.citu.module.menduner.system.controller.app.recruit.job.vo.AppRecruitJobSimpleRespVO;
+import com.citu.module.menduner.system.controller.base.CommonRespVO;
 import com.citu.module.menduner.system.controller.base.analysis.RecruitAnalysisPageReqVO;
 import com.citu.module.menduner.system.controller.base.analysis.RecruitJobAnalysisRespVO;
 import com.citu.module.menduner.system.controller.base.job.JobAdvertisedDetailRespVO;
@@ -26,12 +27,14 @@ import com.citu.module.menduner.system.dal.dataobject.enterprise.EnterpriseDO;
 import com.citu.module.menduner.system.dal.dataobject.enterprise.EnterpriseUserBindDO;
 import com.citu.module.menduner.system.dal.dataobject.job.JobAdvertisedDO;
 import com.citu.module.menduner.system.dal.dataobject.job.JobCvRelDO;
+import com.citu.module.menduner.system.dal.dataobject.person.PersonInfoDO;
 import com.citu.module.menduner.system.dal.dataobject.person.PersonJobFavoriteDO;
 import com.citu.module.menduner.system.dal.dataobject.position.PositionDO;
 import com.citu.module.menduner.system.dal.dataobject.visits.MdeVisitsDO;
 import com.citu.module.menduner.system.enums.MendunerStatusEnum;
 import com.citu.module.menduner.system.enums.job.JobStatusEnum;
 import com.citu.module.menduner.system.enums.visits.MdeVisitsEnum;
+import com.citu.module.menduner.system.util.RecruitAnalysisUtils;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Select;
 
@@ -64,12 +67,13 @@ public interface JobAdvertisedMapper extends BaseMapperX<JobAdvertisedDO> {
                 .orderByDesc(JobAdvertisedDO::getUpdateTime));
     }
 
-    default List<JobAdvertisedDO> selectListByIds( List<Long> ids) {
+    default List<JobAdvertisedDO> selectListByIds(List<Long> ids) {
         return selectList(new LambdaQueryWrapper<JobAdvertisedDO>()
                 .in(JobAdvertisedDO::getId, ids)
                 .eq(JobAdvertisedDO::getStatus, JobStatusEnum.ENABLE.getStatus())
         );
     }
+
     /**
      * 根据查询条件查询职位信息
      **/
@@ -168,6 +172,7 @@ public interface JobAdvertisedMapper extends BaseMapperX<JobAdvertisedDO> {
         MPJLambdaWrapperX<JobAdvertisedDO> query = new MPJLambdaWrapperX<>();
         query.selectAll(JobAdvertisedDO.class);
         query.selectAll(EnterpriseDO.class);
+        query.selectAs(EnterpriseDO::getName, AppJobAdvertisedHomeRespVO::getEnterpriseName);
         query.innerJoin(EnterpriseDO.class, EnterpriseDO::getId, JobAdvertisedDO::getEnterpriseId);
 
         query.eq(JobAdvertisedDO::getStatus, JobStatusEnum.ENABLE.getStatus());
@@ -177,7 +182,12 @@ public interface JobAdvertisedMapper extends BaseMapperX<JobAdvertisedDO> {
 
         query.inIfPresent(JobAdvertisedDO::getId, reqVO.getIds());
         query.inIfPresent(JobAdvertisedDO::getPositionId, reqVO.getPositionIds());
-
+        query.eqIfPresent(JobAdvertisedDO::getHire, reqVO.getHire());
+        if (null != reqVO.getNotNameList()) {
+            for (String name : reqVO.getNotNameList()) {
+                query.notLike(JobAdvertisedDO::getName, name);
+            }
+        }
         // 置顶
         query.orderByDesc(JobAdvertisedDO::getTop);
 
@@ -293,9 +303,9 @@ public interface JobAdvertisedMapper extends BaseMapperX<JobAdvertisedDO> {
      *
      * @param enterpriseId 企业id
      * @param userId       用户id
-     * @param ids  id集合
+     * @param ids          id集合
      **/
-    default List<AppRecruitJobSimpleRespVO> list(Long enterpriseId, Long userId,List<Long> ids,String status) {
+    default List<AppRecruitJobSimpleRespVO> list(Long enterpriseId, Long userId, List<Long> ids, String status) {
         MPJLambdaWrapperX<JobAdvertisedDO> query = new MPJLambdaWrapperX<>();
         query.selectAll(JobAdvertisedDO.class);
         query.eq(JobAdvertisedDO::getEnterpriseId, enterpriseId);
@@ -320,6 +330,7 @@ public interface JobAdvertisedMapper extends BaseMapperX<JobAdvertisedDO> {
         query.selectAll(JobAdvertisedDO.class);
         query.selectSum(MdeVisitsDO::getCount, RecruitJobAnalysisRespVO::getNum);
         query.selectAs(EnterpriseDO::getName, RecruitJobAnalysisRespVO::getEnterpriseName);
+        query.selectAs(EnterpriseDO::getAnotherName, RecruitJobAnalysisRespVO::getEnterpriseAnotherName);
 
         query.eqIfPresent(JobAdvertisedDO::getEnterpriseId, reqVO.getEnterpriseId());
         query.inIfPresent(JobAdvertisedDO::getUserId, reqVO.getUserId());
@@ -382,6 +393,7 @@ public interface JobAdvertisedMapper extends BaseMapperX<JobAdvertisedDO> {
         MPJLambdaWrapperX<JobAdvertisedDO> query = new MPJLambdaWrapperX<>();
         query.selectAll(JobAdvertisedDO.class);
         query.selectAs(EnterpriseDO::getName, RecruitJobAnalysisRespVO::getEnterpriseName);
+        query.selectAs(EnterpriseDO::getAnotherName, RecruitJobAnalysisRespVO::getEnterpriseAnotherName);
 
         query.innerJoin(EnterpriseDO.class, on -> on.eq(EnterpriseDO::getId, JobAdvertisedDO::getEnterpriseId));
 
@@ -478,7 +490,7 @@ public interface JobAdvertisedMapper extends BaseMapperX<JobAdvertisedDO> {
     /**
      * 根据企业id、用户id、职位名称查询是否存在
      **/
-    default boolean existByName(Long enterpriseId,Long userId,Long id,String name) {
+    default boolean existByName(Long enterpriseId, Long userId, Long id, String name) {
         return selectCount(new LambdaQueryWrapperX<JobAdvertisedDO>()
                 .eq(JobAdvertisedDO::getEnterpriseId, enterpriseId)
                 .eq(JobAdvertisedDO::getUserId, userId)
@@ -489,10 +501,12 @@ public interface JobAdvertisedMapper extends BaseMapperX<JobAdvertisedDO> {
     }
 
 
-    /** 根据企业id和招聘类型查询职位 **/
+    /**
+     * 根据企业id和招聘类型查询职位
+     **/
     default List<JobAdvertisedDO> selectListByEnterpriseIdAndType(Long enterpriseId, List<String> types) {
 
-        LambdaQueryWrapperX<JobAdvertisedDO> query =   new LambdaQueryWrapperX<JobAdvertisedDO>()
+        LambdaQueryWrapperX<JobAdvertisedDO> query = new LambdaQueryWrapperX<JobAdvertisedDO>()
                 .eq(JobAdvertisedDO::getEnterpriseId, enterpriseId)
                 .inIfPresent(JobAdvertisedDO::getType, types)
                 .eq(JobAdvertisedDO::getStatus, JobStatusEnum.ENABLE.getStatus());
@@ -500,4 +514,46 @@ public interface JobAdvertisedMapper extends BaseMapperX<JobAdvertisedDO> {
         return selectList(query);
 
     }
+
+    /** 获取职位类型数量topN **/
+    default List<CommonRespVO> getPositionTypeNumTop(RecruitAnalysisPageReqVO reqVO, Integer topNum,
+                                                     LocalDateTime startTime, LocalDateTime endTime) {
+        MPJLambdaWrapperX<JobAdvertisedDO> wrapper = new MPJLambdaWrapperX<>();
+        wrapper.selectAs(PositionDO::getNameCn, "`key`");
+        wrapper.selectCount(JobAdvertisedDO::getId, CommonRespVO::getValue);
+        wrapper.innerJoin(PositionDO.class, on -> on.eq(PositionDO::getId, JobAdvertisedDO::getPositionId));
+
+        wrapper.betweenIfPresent(JobAdvertisedDO::getCreateTime, startTime, endTime);
+
+        wrapper.eqIfPresent(JobAdvertisedDO::getId, reqVO.getJobId());
+        wrapper.eqIfPresent(JobAdvertisedDO::getEnterpriseId, reqVO.getEnterpriseId());
+        wrapper.inIfPresent(JobAdvertisedDO::getUserId, reqVO.getUserId());
+        wrapper.eqIfPresent(JobAdvertisedDO::getStatus, reqVO.getJobStatus());
+
+        wrapper.groupBy(JobAdvertisedDO::getPositionId);
+        wrapper.orderByDesc(CommonRespVO::getValue);
+        wrapper.last("LIMIT " + topNum);
+        return selectJoinList(CommonRespVO.class, wrapper);
+    }
+
+    /**
+     * 发布职位的统计
+     **/
+    default List<CommonRespVO> getJobCount(RecruitAnalysisPageReqVO reqVO,
+                                                  LocalDateTime startTime, LocalDateTime endTime) {
+
+        MPJLambdaWrapperX<JobAdvertisedDO> wrapper = new MPJLambdaWrapperX<>();
+        wrapper.selectCount(JobAdvertisedDO::getId, CommonRespVO::getValue);
+
+        wrapper.betweenIfPresent(JobAdvertisedDO::getCreateTime, startTime, endTime);
+        wrapper.eqIfPresent(JobAdvertisedDO::getId, reqVO.getJobId());
+        wrapper.eqIfPresent(JobAdvertisedDO::getEnterpriseId, reqVO.getEnterpriseId());
+        wrapper.inIfPresent(JobAdvertisedDO::getUserId, reqVO.getUserId());
+        wrapper.eqIfPresent(JobAdvertisedDO::getStatus, reqVO.getJobStatus());
+
+        RecruitAnalysisUtils.applyTimeGrouping(wrapper, JobAdvertisedDO::getCreateTime, reqVO.getType());
+        wrapper.orderByDesc("`key`");
+
+        return selectJoinList(CommonRespVO.class, wrapper);
+    }
 }

+ 1 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/job/JobCvRelMapper.java

@@ -327,6 +327,7 @@ public interface JobCvRelMapper extends BaseMapperX<JobCvRelDO> {
         wrapper.selectAssociation("person", PersonInfoDO.class, RecruitJobCvRelAnalysisRespVO::getPerson);
         wrapper.selectAssociation("recommend", PersonInfoDO.class, RecruitJobCvRelAnalysisRespVO::getRecommendPerson);
         wrapper.selectAs(EnterpriseDO::getName, RecruitJobAnalysisRespVO::getEnterpriseName);
+        wrapper.selectAs(EnterpriseDO::getAnotherName, RecruitJobAnalysisRespVO::getEnterpriseAnotherName);
 
         wrapper.eqIfPresent(JobCvRelDO::getEnterpriseId, reqVO.getEnterpriseId());
         wrapper.inIfPresent(JobCvRelDO::getPublishUserId, reqVO.getUserId());

+ 25 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/web/WebContentMapper.java

@@ -0,0 +1,25 @@
+package com.citu.module.menduner.system.dal.mysql.web;
+
+
+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.base.web.WebContentPageReqVO;
+import com.citu.module.menduner.system.dal.dataobject.web.WebContentDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 页面内容 Mapper
+ *
+ * @author Rayson
+ */
+@Mapper
+public interface WebContentMapper extends BaseMapperX<WebContentDO> {
+
+    default PageResult<WebContentDO> selectPage(WebContentPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<WebContentDO>()
+                .betweenIfPresent(WebContentDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(WebContentDO::getId));
+    }
+
+}

+ 14 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/job/JobAdvertisedService.java

@@ -237,5 +237,19 @@ public interface JobAdvertisedService {
      */
     PageResult<RecruitJobAnalysisRespVO> getJobNum(RecruitAnalysisPageReqVO reqVO);
 
+    /**
+     * 前N最多人发布的职位类型
+     */
+    Map<String, Object[]> getPositionTypeNumTop(RecruitAnalysisPageReqVO reqVO,Integer topNum);
+
+    /**
+     * 发布职位统计
+     */
+    Map<String, Object[]> getJobCount(RecruitAnalysisPageReqVO reqVO);
+
+    /**
+     * 最新发布的前N个职位
+     */
+    List<RecruitJobAnalysisRespVO> getNewJob(RecruitAnalysisPageReqVO reqVO,Integer topNum);
 
 }

+ 60 - 21
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/job/JobAdvertisedServiceImpl.java

@@ -45,6 +45,7 @@ import javax.annotation.Resource;
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
@@ -55,6 +56,7 @@ import static com.citu.module.menduner.common.util.TimeUtils.generateDateTimeRan
 import static com.citu.module.menduner.system.dal.redis.RedisKeyConstants.JOB_SHARE;
 import static com.citu.module.menduner.system.enums.DictTypeConstants.*;
 import static com.citu.module.menduner.system.enums.ErrorCodeConstants.*;
+import static com.citu.module.menduner.system.util.RecruitAnalysisUtils.packBarCount;
 
 /**
  * 招聘职位 Service 实现类
@@ -214,21 +216,23 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
 //        pageReqVO.setAcquainted(true);
 //        pageReqVO.setTop(false);
         try {
-            if (null != LoginUserContext.getUserId2()) {
-                Long[] ids = graphApi.queryRecommendJob(GraphQueryPageDTO
-                        .builder()
-                        .id(pageReqVO.getId())
-                        .type(GraphQueryPageDTO.JOB)
-                        .current(pageReqVO.getPageNo())
-                        .size(pageReqVO.getPageSize())
-                        .userId(LoginUserContext.getUserId2())
-                        .build()
-                ).getCheckedData();
-                pageReqVO.setIds(ids);
-            } else {
-                // 取最多发布职位的职位类型id
-                pageReqVO.setPositionIds(mapper.selectTopPositionIdsByFrequency(pageParam.getPageSize()));
-            }
+//            if (null != LoginUserContext.getUserId2()) {
+//                Long[] ids = graphApi.queryRecommendJob(GraphQueryPageDTO
+//                        .builder()
+//                        .id(pageReqVO.getId())
+//                        .type(GraphQueryPageDTO.JOB)
+//                        .current(pageReqVO.getPageNo())
+//                        .size(pageReqVO.getPageSize())
+//                        .userId(LoginUserContext.getUserId2())
+//                        .build()
+//                ).getCheckedData();
+//                pageReqVO.setIds(ids);
+//            } else {
+            // 取最多发布职位的职位类型id
+            pageReqVO.setPositionIds(mapper.selectTopPositionIdsByFrequency(pageParam.getPageSize()));
+            pageReqVO.setNotNameList(List.of("厨师", "预订员", "实习生", "拉面师", "前台接待", "空调工", "楼层服务员", "礼宾员", "销售协调员"));
+            pageReqVO.setHire(false);
+//            }
         } catch (Exception ex) {
             ex.printStackTrace();
         }
@@ -453,7 +457,7 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
         }
         // 如果发布职位的job.createTime超过了24小时则不可编辑,respVO.setEdit(false);
         if (JobStatusEnum.ENABLE.getStatus().equals(existingJob.getStatus())
-                &&ChronoUnit.HOURS.between(existingJob.getCreateTime(), LocalDateTime.now()) > 24) {
+                && ChronoUnit.HOURS.between(existingJob.getCreateTime(), LocalDateTime.now()) > 24) {
             throw exception(MDE_JOB_ADVERTISED_TIME_ERROR_24);
         }
         // 如果普通职位切换成众聘职位
@@ -504,7 +508,7 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
             return;
         }
         job.setStatus(JobStatusEnum.ENABLE.getStatus());
-        if(null != expireTime) {
+        if (null != expireTime) {
             job.setExpireTime(expireTime);
         }
         mapper.updateById(job);
@@ -542,7 +546,7 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
         return mapper.list(
                 LoginUserContext.getEnterpriseId(),
                 LoginUserContext.getUserId(),
-                null,status
+                null, status
         );
     }
 
@@ -551,7 +555,7 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
         return mapper.list(
                 LoginUserContext.getEnterpriseId(),
                 LoginUserContext.getUserId(),
-                ids,null
+                ids, null
         );
     }
 
@@ -686,7 +690,7 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
                                     JobAdvertisedConvert.INSTANCE.convert(job)
                             )
             );
-        } else if (SyncConstants.UPDATE.equals(operate)){
+        } else if (SyncConstants.UPDATE.equals(operate)) {
             // es
             esProducer.send(SyncConstants.JOB, SyncConstants.UPDATE, job.getId());
             // 图数据库
@@ -698,7 +702,7 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
                                     JobAdvertisedConvert.INSTANCE.convert(job)
                             )
             );
-        }else {
+        } else {
             // es
             esProducer.send(SyncConstants.JOB, SyncConstants.DELETE, job.getId());
             // 图数据库
@@ -731,4 +735,39 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
         LocalDateTime[] timeRange = generateDateTimeRange(reqVO);
         return mapper.getJobNum(reqVO, timeRange[0], timeRange[1]);
     }
+
+    @Override
+    public Map<String, Object[]> getPositionTypeNumTop(RecruitAnalysisPageReqVO reqVO, Integer topNum) {
+        LocalDateTime[] timeRange = generateDateTimeRange(reqVO);
+        List<CommonRespVO> respList= mapper.getPositionTypeNumTop(reqVO, topNum, timeRange[0], timeRange[1]);
+        List<CommonRespVO> sortedResult = respList.stream()
+                .sorted(Comparator.comparing(c->Integer.valueOf(c.getValue().toString())))
+                .collect(Collectors.toList());
+        return packBarCount(sortedResult.stream()
+                .filter(c -> null != c.getKey())
+                .collect(Collectors.toList())
+        );
+    }
+
+    @Override
+    public Map<String, Object[]> getJobCount(RecruitAnalysisPageReqVO reqVO) {
+        LocalDateTime[] timeRange = generateDateTimeRange(reqVO);
+        List<CommonRespVO> result = mapper.getJobCount(reqVO, timeRange[0], timeRange[1]);
+        List<CommonRespVO> sortedResult = result.stream()
+                .sorted(Comparator.comparing(CommonRespVO::getKey))
+                .collect(Collectors.toList());
+        return packBarCount(sortedResult.stream()
+                .filter(c -> null != c.getKey())
+                .collect(Collectors.toList())
+        );
+    }
+
+    @Override
+    public List<RecruitJobAnalysisRespVO> getNewJob(RecruitAnalysisPageReqVO reqVO, Integer topNum) {
+        LocalDateTime[] timeRange = generateDateTimeRange(reqVO);
+        if (null != topNum) {
+            reqVO.setPageSize(topNum);
+        }
+        return mapper.getJobNum(reqVO, timeRange[0], timeRange[1]).getList();
+    }
 }

+ 56 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/web/WebContentService.java

@@ -0,0 +1,56 @@
+package com.citu.module.menduner.system.service.web;
+
+
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.module.menduner.system.controller.base.web.WebContentPageReqVO;
+import com.citu.module.menduner.system.controller.base.web.WebContentSaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.web.WebContentDO;
+
+import javax.validation.Valid;
+
+/**
+ * 页面内容 Service 接口
+ *
+ * @author Rayson
+ */
+public interface WebContentService {
+
+    /**
+     * 创建页面内容
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createWebContent(@Valid WebContentSaveReqVO createReqVO);
+
+    /**
+     * 更新页面内容
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateWebContent(@Valid WebContentSaveReqVO updateReqVO);
+
+    /**
+     * 删除页面内容
+     *
+     * @param id 编号
+     */
+    void deleteWebContent(Long id);
+
+    /**
+     * 获得页面内容
+     *
+     * @param id 编号
+     * @return 页面内容
+     */
+    WebContentDO getWebContent(Long id);
+
+    /**
+     * 获得页面内容分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 页面内容分页
+     */
+    PageResult<WebContentDO> getWebContentPage(WebContentPageReqVO pageReqVO);
+
+}

+ 72 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/web/WebContentServiceImpl.java

@@ -0,0 +1,72 @@
+package com.citu.module.menduner.system.service.web;
+
+
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.common.util.object.BeanUtils;
+import com.citu.module.menduner.system.controller.base.web.WebContentPageReqVO;
+import com.citu.module.menduner.system.controller.base.web.WebContentSaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.web.WebContentDO;
+import com.citu.module.menduner.system.dal.mysql.web.WebContentMapper;
+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.WEB_CONTENT_NOT_EXISTS;
+
+/**
+ * 页面内容 Service 实现类
+ *
+ * @author Rayson
+ */
+@Service
+@Validated
+public class WebContentServiceImpl implements WebContentService {
+
+    @Resource
+    private WebContentMapper webContentMapper;
+
+    @Override
+    public Long createWebContent(WebContentSaveReqVO createReqVO) {
+        // 插入
+        WebContentDO webContent = BeanUtils.toBean(createReqVO, WebContentDO.class);
+        webContentMapper.insert(webContent);
+        // 返回
+        return webContent.getId();
+    }
+
+    @Override
+    public void updateWebContent(WebContentSaveReqVO updateReqVO) {
+        // 校验存在
+        validateWebContentExists(updateReqVO.getId());
+        // 更新
+        WebContentDO updateObj = BeanUtils.toBean(updateReqVO, WebContentDO.class);
+        webContentMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteWebContent(Long id) {
+        // 校验存在
+        validateWebContentExists(id);
+        // 删除
+        webContentMapper.deleteById(id);
+    }
+
+    private void validateWebContentExists(Long id) {
+        if (webContentMapper.selectById(id) == null) {
+            throw exception(WEB_CONTENT_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public WebContentDO getWebContent(Long id) {
+        return webContentMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<WebContentDO> getWebContentPage(WebContentPageReqVO pageReqVO) {
+        return webContentMapper.selectPage(pageReqVO);
+    }
+
+}

+ 124 - 0
menduner/menduner-system-biz/src/test/java/com/citu/module/menduner/system/service/web/WebContentServiceImplTest.java

@@ -0,0 +1,124 @@
+package com.citu.module.menduner.system.service.web;
+
+
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.test.core.ut.BaseDbUnitTest;
+import com.citu.module.menduner.system.controller.base.web.WebContentPageReqVO;
+import com.citu.module.menduner.system.controller.base.web.WebContentSaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.web.WebContentDO;
+import com.citu.module.menduner.system.dal.mysql.web.WebContentMapper;
+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.WEB_CONTENT_NOT_EXISTS;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * {@link WebContentServiceImpl} 的单元测试类
+ *
+ * @author Rayson
+ */
+@Import(WebContentServiceImpl.class)
+public class WebContentServiceImplTest extends BaseDbUnitTest {
+
+    @Resource
+    private WebContentServiceImpl webContentService;
+
+    @Resource
+    private WebContentMapper webContentMapper;
+
+    @Test
+    public void testCreateWebContent_success() {
+        // 准备参数
+        WebContentSaveReqVO createReqVO = randomPojo(WebContentSaveReqVO.class).setId(null);
+
+        // 调用
+        Long webContentId = webContentService.createWebContent(createReqVO);
+        // 断言
+        assertNotNull(webContentId);
+        // 校验记录的属性是否正确
+        WebContentDO webContent = webContentMapper.selectById(webContentId);
+        assertPojoEquals(createReqVO, webContent, "id");
+    }
+
+    @Test
+    public void testUpdateWebContent_success() {
+        // mock 数据
+        WebContentDO dbWebContent = randomPojo(WebContentDO.class);
+        webContentMapper.insert(dbWebContent);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        WebContentSaveReqVO updateReqVO = randomPojo(WebContentSaveReqVO.class, o -> {
+            o.setId(dbWebContent.getId()); // 设置更新的 ID
+        });
+
+        // 调用
+        webContentService.updateWebContent(updateReqVO);
+        // 校验是否更新正确
+        WebContentDO webContent = webContentMapper.selectById(updateReqVO.getId()); // 获取最新的
+        assertPojoEquals(updateReqVO, webContent);
+    }
+
+    @Test
+    public void testUpdateWebContent_notExists() {
+        // 准备参数
+        WebContentSaveReqVO updateReqVO = randomPojo(WebContentSaveReqVO.class);
+
+        // 调用, 并断言异常
+        assertServiceException(() -> webContentService.updateWebContent(updateReqVO), WEB_CONTENT_NOT_EXISTS);
+    }
+
+    @Test
+    public void testDeleteWebContent_success() {
+        // mock 数据
+        WebContentDO dbWebContent = randomPojo(WebContentDO.class);
+        webContentMapper.insert(dbWebContent);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        Long id = dbWebContent.getId();
+
+        // 调用
+        webContentService.deleteWebContent(id);
+        // 校验数据不存在了
+        assertNull(webContentMapper.selectById(id));
+    }
+
+    @Test
+    public void testDeleteWebContent_notExists() {
+        // 准备参数
+        Long id = randomLongId();
+
+        // 调用, 并断言异常
+        assertServiceException(() -> webContentService.deleteWebContent(id), WEB_CONTENT_NOT_EXISTS);
+    }
+
+    @Test
+    @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
+    public void testGetWebContentPage() {
+        // mock 数据
+        WebContentDO dbWebContent = randomPojo(WebContentDO.class, o -> { // 等会查询到
+            o.setCreateTime(null);
+        });
+        webContentMapper.insert(dbWebContent);
+        // 测试 createTime 不匹配
+        webContentMapper.insert(cloneIgnoreId(dbWebContent, o -> o.setCreateTime(null)));
+        // 准备参数
+        WebContentPageReqVO reqVO = new WebContentPageReqVO();
+        reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
+
+        // 调用
+        PageResult<WebContentDO> pageResult = webContentService.getWebContentPage(reqVO);
+        // 断言
+        assertEquals(1, pageResult.getTotal());
+        assertEquals(1, pageResult.getList().size());
+        assertPojoEquals(dbWebContent, pageResult.getList().get(0));
+    }
+
+}

+ 2 - 1
menduner/menduner-system-biz/src/test/resources/sql/clean.sql

@@ -45,4 +45,5 @@ DELETE FROM "mde_user_entitlement";
 DELETE FROM "mde_enterprise_package";
 DELETE FROM "mde_enterprise_entitlement";
 DELETE FROM "mde_morning_news";
-DELETE FROM "mde_job_fair";
+DELETE FROM "mde_job_fair";
+DELETE FROM "mde_web_content";

+ 23 - 1
menduner/menduner-system-biz/src/test/resources/sql/create_tables.sql

@@ -817,4 +817,26 @@ CREATE TABLE IF NOT EXISTS "mde_job_fair" (
     "deleted" bit NOT NULL DEFAULT FALSE,
     "tenant_id" bigint NOT NULL,
     PRIMARY KEY ("id")
-) COMMENT '招聘会';
+) COMMENT '招聘会';
+
+CREATE TABLE IF NOT EXISTS "mde_web_content" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "pc_top" varchar,
+    "pc_left" varchar,
+    "pc_right" varchar,
+    "pc_advertisement" varchar,
+    "pc_home_carousel" varchar,
+    "pc_login_carousel" varchar,
+    "pc_login_background" varchar,
+    "pc_backend_advertisement" varchar,
+    "app_home_carousel" varchar,
+    "app_advertisement" varchar,
+    "status" varchar NOT NULL,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL,
+    PRIMARY KEY ("id")
+) COMMENT '页面内容';