Browse Source

feat: 增加小程序管理模块,增加小程序客服问题管理,增加小程序广告管理

luofeiyun 1 month ago
parent
commit
a4676afe95
55 changed files with 3236 additions and 0 deletions
  1. 100 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/adsense/AdsenseController.java
  2. 37 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/adsense/vo/AdsensePageReqVO.java
  3. 47 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/adsense/vo/AdsenseRespVO.java
  4. 35 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/adsense/vo/AdsenseSaveReqVO.java
  5. 28 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/adsense/vo/AdsenseSimpleRespVO.java
  6. 150 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advert/AdvertController.java
  7. 57 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advert/vo/AdvertPageReqVO.java
  8. 75 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advert/vo/AdvertRespVO.java
  9. 54 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advert/vo/AdvertSaveReqVO.java
  10. 93 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advertlog/AdvertLogController.java
  11. 43 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advertlog/vo/AdvertLogPageReqVO.java
  12. 47 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advertlog/vo/AdvertLogRespVO.java
  13. 41 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advertlog/vo/AdvertLogSaveReqVO.java
  14. 107 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problem/ProblemController.java
  15. 34 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problem/vo/ProblemPageReqVO.java
  16. 78 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problem/vo/ProblemRespVO.java
  17. 54 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problem/vo/ProblemSaveReqVO.java
  18. 109 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problemtype/ProblemTypeController.java
  19. 48 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problemtype/vo/ProblemTypePageReqVO.java
  20. 58 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problemtype/vo/ProblemTypeRespVO.java
  21. 37 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problemtype/vo/ProblemTypeSaveReqVO.java
  22. 20 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problemtype/vo/ProblemTypeSimpleRespVO.java
  23. 103 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/advert/AppAdvertController.java
  24. 30 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/advert/vo/AppAdsenseRespVO.java
  25. 41 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/advert/vo/AppAdvertLogReqVO.java
  26. 25 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/advert/vo/AppAdvertReqVO.java
  27. 15 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/advert/vo/AppAdvertRespVO.java
  28. 77 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/problem/AppProblemController.java
  29. 33 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/problem/vo/AppProblemReqVO.java
  30. 57 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/problem/vo/AppProblemRespVO.java
  31. 42 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/problem/vo/AppProblemTypeRespVO.java
  32. 29 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/convert/adsense/AdsenseConvert.java
  33. 37 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/convert/problemtype/ProblemTypeConvert.java
  34. 54 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/dataobject/adsense/AdsenseDO.java
  35. 79 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/dataobject/advert/AdvertDO.java
  36. 60 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/dataobject/advertlog/AdvertLogDO.java
  37. 85 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/dataobject/problem/ProblemDO.java
  38. 65 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/dataobject/problemtype/ProblemTypeDO.java
  39. 49 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/mysql/adsense/AdsenseMapper.java
  40. 42 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/mysql/advert/AdvertMapper.java
  41. 30 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/mysql/advertlog/AdvertLogMapper.java
  42. 41 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/mysql/problem/ProblemMapper.java
  43. 52 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/mysql/problemtype/ProblemTypeMapper.java
  44. 29 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/enums/ErrorCodeConstants.java
  45. 72 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/adsense/AdsenseService.java
  46. 122 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/adsense/AdsenseServiceImpl.java
  47. 64 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/advert/AdvertService.java
  48. 91 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/advert/AdvertServiceImpl.java
  49. 55 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/advertlog/AdvertLogService.java
  50. 72 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/advertlog/AdvertLogServiceImpl.java
  51. 60 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/problem/ProblemService.java
  52. 88 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/problem/ProblemServiceImpl.java
  53. 83 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/problemtype/ProblemTypeService.java
  54. 97 0
      ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/problemtype/ProblemTypeServiceImpl.java
  55. 5 0
      ship-server-web/pom.xml

+ 100 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/adsense/AdsenseController.java

@@ -0,0 +1,100 @@
+package com.yc.ship.module.miniapplet.controller.admin.adsense;
+
+import com.yc.ship.framework.common.pojo.CommonResult;
+import com.yc.ship.framework.common.pojo.PageParam;
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.framework.excel.core.util.ExcelUtils;
+import com.yc.ship.framework.operatelog.core.annotations.OperateLog;
+import com.yc.ship.module.miniapplet.controller.admin.adsense.vo.AdsensePageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.adsense.vo.AdsenseRespVO;
+import com.yc.ship.module.miniapplet.controller.admin.adsense.vo.AdsenseSaveReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.adsense.vo.AdsenseSimpleRespVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.adsense.AdsenseDO;
+import com.yc.ship.module.miniapplet.service.adsense.AdsenseService;
+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.yc.ship.framework.common.pojo.CommonResult.success;
+import static com.yc.ship.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
+
+
+@Tag(name = "管理后台 - 广告位管理")
+@RestController
+@RequestMapping("/applet/adsense")
+@Validated
+public class AdsenseController {
+
+    @Resource
+    private AdsenseService adsenseService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建广告位管理")
+    @PreAuthorize("@ss.hasPermission('applet:adsense:create')")
+    public CommonResult<Long> createAdsense(@Valid @RequestBody AdsenseSaveReqVO createReqVO) {
+        return success(adsenseService.createAdsense(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新广告位管理")
+    @PreAuthorize("@ss.hasPermission('applet:adsense:update')")
+    public CommonResult<Boolean> updateAdsense(@Valid @RequestBody AdsenseSaveReqVO updateReqVO) {
+        adsenseService.updateAdsense(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除广告位管理")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('applet:adsense:delete')")
+    public CommonResult<Boolean> deleteAdsense(@RequestParam("id") Long id) {
+        adsenseService.deleteAdsense(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得广告位管理")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('applet:adsense:query')")
+    public CommonResult<AdsenseRespVO> getAdsense(@RequestParam("id") Long id) {
+        AdsenseDO adsense = adsenseService.getAdsense(id);
+        return success(BeanUtils.toBean(adsense, AdsenseRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得广告位管理分页")
+    @PreAuthorize("@ss.hasPermission('applet:adsense:query')")
+    public CommonResult<PageResult<AdsenseRespVO>> getAdsensePage(@Valid AdsensePageReqVO pageReqVO) {
+        PageResult<AdsenseDO> pageResult = adsenseService.getAdsensePage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, AdsenseRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出广告位管理 Excel")
+    @PreAuthorize("@ss.hasPermission('applet:adsense:export')")
+    @OperateLog(type = EXPORT,enable = false)
+    public void exportAdsenseExcel(@Valid AdsensePageReqVO pageReqVO, HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<AdsenseDO> list = adsenseService.getAdsensePage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "广告位管理.xls", "数据", AdsenseRespVO.class, BeanUtils.toBean(list, AdsenseRespVO.class));
+    }
+
+    @GetMapping({"/list-all-simple", "/simple-list"})
+    @Operation(summary = "获取门店精简信息列表", description = "只包含被开启的门店,主要用于前端的下拉选项")
+    public CommonResult<List<AdsenseSimpleRespVO>> getSimpleList(@RequestParam("status") Integer status) {
+        List<AdsenseDO> list = adsenseService.getAdsenseListByStatus(status);
+        return success(BeanUtils.toBean(list, AdsenseSimpleRespVO.class));
+    }
+
+}

+ 37 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/adsense/vo/AdsensePageReqVO.java

@@ -0,0 +1,37 @@
+package com.yc.ship.module.miniapplet.controller.admin.adsense.vo;
+
+import com.yc.ship.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.yc.ship.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 AdsensePageReqVO extends PageParam {
+
+    @Schema(description = "广告位代码")
+    private String adsenseCode;
+
+    @Schema(description = "广告位名称", example = "芋艿")
+    private String adsenseName;
+
+    @Schema(description = "媒体类型:0单图片、1单视频、2图片轮播", example = "1")
+    private Integer adsenseType;
+
+    @Schema(description = "启用状态 0否 1是", example = "1")
+    private Integer isUse;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

+ 47 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/adsense/vo/AdsenseRespVO.java

@@ -0,0 +1,47 @@
+package com.yc.ship.module.miniapplet.controller.admin.adsense.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.yc.ship.framework.excel.core.annotations.DictFormat;
+import com.yc.ship.framework.excel.core.convert.DictConvert;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 广告位管理 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class AdsenseRespVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "19883")
+//    @ExcelProperty("主键")
+    private Long id;
+
+    @Schema(description = "广告位代码", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("广告位代码")
+    private String adsenseCode;
+
+    @Schema(description = "广告位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
+    @ExcelProperty("广告位名称")
+    private String adsenseName;
+
+    @Schema(description = "媒体类型:0单图片、1单视频、2图片轮播", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @ExcelProperty(value = "媒体类型:0单图片、1单视频、2图片轮播", converter = DictConvert.class)
+    @DictFormat("adsense_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
+    private Integer adsenseType;
+
+    @Schema(description = "启用状态 0否 1是", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @ExcelProperty(value = "启用状态 0否 1是", converter = DictConvert.class)
+    @DictFormat("use_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
+    private Integer isUse;
+
+    @Schema(description = "备注")
+    @ExcelProperty("备注")
+    private String remark;
+
+    @Schema(description = "创建时间")
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 35 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/adsense/vo/AdsenseSaveReqVO.java

@@ -0,0 +1,35 @@
+package com.yc.ship.module.miniapplet.controller.admin.adsense.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+@Schema(description = "管理后台 - 广告位管理新增/修改 Request VO")
+@Data
+public class AdsenseSaveReqVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "19883")
+    private Long id;
+
+    @Schema(description = "广告位代码", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "广告位代码不能为空")
+    private String adsenseCode;
+
+    @Schema(description = "广告位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
+    @NotEmpty(message = "广告位名称不能为空")
+    private String adsenseName;
+
+    @Schema(description = "媒体类型:0单图片、1单视频、2图片轮播", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "媒体类型:0单图片、1单视频、2图片轮播不能为空")
+    private Integer adsenseType;
+
+    @Schema(description = "启用状态 0否 1是", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "启用状态 0否 1是")
+    private Integer isUse;
+
+    @Schema(description = "备注")
+    private String remark;
+
+}

+ 28 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/adsense/vo/AdsenseSimpleRespVO.java

@@ -0,0 +1,28 @@
+package com.yc.ship.module.miniapplet.controller.admin.adsense.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.yc.ship.framework.excel.core.annotations.DictFormat;
+import com.yc.ship.framework.excel.core.convert.DictConvert;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - 广告位管理 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class AdsenseSimpleRespVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "19883")
+    @ExcelProperty("主键")
+    private Long id;
+
+    @Schema(description = "广告位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
+    @ExcelProperty("广告位名称")
+    private String adsenseName;
+
+    @Schema(description = "媒体类型:0单图片、1单视频、2图片轮播", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @ExcelProperty(value = "媒体类型:0单图片、1单视频、2图片轮播", converter = DictConvert.class)
+    @DictFormat("adsense_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
+    private Integer adsenseType;
+
+}

+ 150 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advert/AdvertController.java

@@ -0,0 +1,150 @@
+package com.yc.ship.module.miniapplet.controller.admin.advert;
+
+import com.yc.ship.framework.common.pojo.CommonResult;
+import com.yc.ship.framework.common.pojo.PageParam;
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.common.util.collection.CollectionUtils;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.framework.excel.core.util.ExcelUtils;
+import com.yc.ship.framework.operatelog.core.annotations.OperateLog;
+import com.yc.ship.module.miniapplet.controller.admin.advert.vo.AdvertPageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.advert.vo.AdvertRespVO;
+import com.yc.ship.module.miniapplet.controller.admin.advert.vo.AdvertSaveReqVO;
+import com.yc.ship.module.miniapplet.convert.adsense.AdsenseConvert;
+import com.yc.ship.module.miniapplet.dal.dataobject.adsense.AdsenseDO;
+import com.yc.ship.module.miniapplet.dal.dataobject.advert.AdvertDO;
+import com.yc.ship.module.miniapplet.service.adsense.AdsenseService;
+import com.yc.ship.module.miniapplet.service.advert.AdvertService;
+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 java.util.Map;
+import java.util.stream.Collectors;
+
+import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.yc.ship.framework.common.pojo.CommonResult.success;
+import static com.yc.ship.framework.common.util.collection.CollectionUtils.convertList;
+import static com.yc.ship.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
+import static com.yc.ship.module.miniapplet.enums.ErrorCodeConstants.*;
+
+@Tag(name = "管理后台 - 广告管理")
+@RestController
+@RequestMapping("/applet/advert")
+@Validated
+public class AdvertController {
+
+    @Resource
+    private AdsenseService adsenseService;
+
+    @Resource
+    private AdvertService advertService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建广告管理")
+    @PreAuthorize("@ss.hasPermission('applet:advert:create')")
+    public CommonResult<Long> createAdvert(@Valid @RequestBody AdvertSaveReqVO createReqVO) {
+        verifyAdsense(null, createReqVO.getAdsenseId());
+        return success(advertService.createAdvert(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新广告管理")
+    @PreAuthorize("@ss.hasPermission('applet:advert:update')")
+    public CommonResult<Boolean> updateAdvert(@Valid @RequestBody AdvertSaveReqVO updateReqVO) {
+        verifyAdsense(updateReqVO.getId(), updateReqVO.getAdsenseId());
+        advertService.updateAdvert(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除广告管理")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('applet:advert:delete')")
+    public CommonResult<Boolean> deleteAdvert(@RequestParam("id") Long id) {
+        advertService.deleteAdvert(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得广告管理")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('applet:advert:query')")
+    public CommonResult<AdvertRespVO> getAdvert(@RequestParam("id") Long id) {
+        AdvertDO advert = advertService.getAdvert(id);
+        return success(BeanUtils.toBean(advert, AdvertRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得广告管理分页")
+    @PreAuthorize("@ss.hasPermission('applet:advert:query')")
+    public CommonResult<PageResult<AdvertRespVO>> getAdvertPage(@Valid AdvertPageReqVO pageReqVO) {
+        PageResult<AdvertDO> pageResult = advertService.getAdvertPage(pageReqVO);
+        List<AdsenseDO> adsenseList = adsenseService.getAdsenseList(convertList(pageResult.getList(), AdvertDO::getAdsenseId));
+        Map<Long, AdsenseDO> adsenseMap = CollectionUtils.convertMap(adsenseList, AdsenseDO::getId);
+        return success(new PageResult<>(AdsenseConvert.INSTANCE.convertAdvertList(pageResult.getList(), adsenseMap),
+                pageResult.getTotal()));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出广告管理 Excel")
+    @PreAuthorize("@ss.hasPermission('applet:advert:export')")
+    @OperateLog(type = EXPORT,enable = false)
+    public void exportAdvertExcel(@Valid AdvertPageReqVO pageReqVO,
+                                  HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<AdvertDO> list = advertService.getAdvertPage(pageReqVO).getList();
+        List<AdsenseDO> adsenseList = adsenseService.getAdsenseList(convertList(list, AdvertDO::getAdsenseId));
+        Map<Long, AdsenseDO> adsenseMap = CollectionUtils.convertMap(adsenseList, AdsenseDO::getId);
+        List<AdvertRespVO> respList = AdsenseConvert.INSTANCE.convertAdvertList(list, adsenseMap);
+        // 导出 Excel
+        ExcelUtils.write(response, "广告管理.xls", "数据", AdvertRespVO.class,
+                respList);
+    }
+
+    /**
+     * 验证广告类型
+     *
+     * @param adsenseId 目录类型ID
+     */
+    private void verifyAdsense(Long id, Long adsenseId) {
+        AdsenseDO adsenseDO = adsenseService.getAdsense(adsenseId);
+        if (adsenseDO == null) {
+            throw exception(ADSENSE_NOT_EXISTS);
+        }
+        Integer type = adsenseDO.getAdsenseType();
+        List<AdvertDO> advertDOS = advertService.getAdvertList(adsenseId);
+        if (id != null) {
+            // 过滤出 非当前操作的内容ID
+            advertDOS = advertDOS.stream()
+                    .filter(contentDO -> !id.equals(contentDO.getId()))
+                    .collect(Collectors.toList());
+        }
+        switch (type) {
+            case 0:
+                // 单图片
+                if (!advertDOS.isEmpty()) {
+                    throw exception(ADSENSE_TYPE_EXCEED);
+                }
+                break;
+            case 1:
+                // 单视频
+                if (!advertDOS.isEmpty()) {
+                    throw exception(ADSENSE_TYPE_EXCEED);
+                }
+                break;
+            default:
+                // 2图片轮播
+
+        }
+    }
+
+}

+ 57 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advert/vo/AdvertPageReqVO.java

@@ -0,0 +1,57 @@
+package com.yc.ship.module.miniapplet.controller.admin.advert.vo;
+
+import com.yc.ship.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.yc.ship.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 AdvertPageReqVO extends PageParam {
+
+    @Schema(description = "广告位id", example = "25367")
+    private Long adsenseId;
+
+    @Schema(description = "排序号")
+    private Integer sort;
+
+    @Schema(description = "标题")
+    private String title;
+
+    @Schema(description = "副标题")
+    private String subTitle;
+
+    @Schema(description = "上传图片地址", example = "https://www.iocoder.cn")
+    private String advertUrl;
+
+    @Schema(description = "跳转地址", example = "https://www.iocoder.cn")
+    private String linkUrl;
+
+    @Schema(description = "是否投放 Ticket_Yes_No")
+    private Integer isDisplay;
+
+    @Schema(description = "有效期类型:0 永久,1限时", example = "2")
+    private Integer validType;
+
+    @Schema(description = "广告有效开始日期")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] staDate;
+
+    @Schema(description = "广告有效结束日期")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] endDate;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

+ 75 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advert/vo/AdvertRespVO.java

@@ -0,0 +1,75 @@
+package com.yc.ship.module.miniapplet.controller.admin.advert.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.yc.ship.framework.excel.core.annotations.DictFormat;
+import com.yc.ship.framework.excel.core.convert.DictConvert;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 广告管理 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class AdvertRespVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "16726")
+//    @ExcelProperty("主键")
+    private Long id;
+
+    @Schema(description = "广告位id", requiredMode = Schema.RequiredMode.REQUIRED, example = "25367")
+//    @ExcelProperty("广告位id")
+    private Long adsenseId;
+
+    @Schema(description = "广告位", requiredMode = Schema.RequiredMode.REQUIRED, example = "25367")
+    @ExcelProperty("广告位")
+    private String adsenseName;
+
+    @Schema(description = "排序号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("排序号")
+    private Integer sort;
+
+    @Schema(description = "标题")
+    @ExcelProperty("标题")
+    private String title;
+
+    @Schema(description = "副标题")
+    @ExcelProperty("副标题")
+    private String subTitle;
+
+    @Schema(description = "上传图片地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
+    @ExcelProperty("上传图片地址")
+    private String advertUrl;
+
+    @Schema(description = "链接类型 0.外部链接 1.产品 2.子产品", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+    @ExcelProperty(value = "链接类型 0.外部链接 1.产品 2.子产品 Advert_Link_Type", converter = DictConvert.class)
+    @DictFormat("advert_link_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
+    private Integer linkType;
+
+    @Schema(description = "跳转地址", example = "https://www.iocoder.cn")
+    @ExcelProperty("跳转地址")
+    private String linkUrl;
+
+    @Schema(description = "是否投放 Ticket_Yes_No")
+    @ExcelProperty(value = "是否投放 Ticket_Yes_No", converter = DictConvert.class)
+    @DictFormat("yes_no") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
+    private Integer isDisplay;
+
+    @Schema(description = "有效期类型:0 永久,1限时", example = "2")
+    @ExcelProperty("有效期类型:0 永久,1限时")
+    private Integer validType;
+
+    @Schema(description = "广告有效开始日期")
+    @ExcelProperty("广告有效开始日期")
+    private LocalDateTime staDate;
+
+    @Schema(description = "广告有效结束日期")
+    @ExcelProperty("广告有效结束日期")
+    private LocalDateTime endDate;
+
+    @Schema(description = "创建时间")
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 54 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advert/vo/AdvertSaveReqVO.java

@@ -0,0 +1,54 @@
+package com.yc.ship.module.miniapplet.controller.admin.advert.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 广告管理新增/修改 Request VO")
+@Data
+public class AdvertSaveReqVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "16726")
+    private Long id;
+
+    @Schema(description = "广告位id", requiredMode = Schema.RequiredMode.REQUIRED, example = "25367")
+    @NotNull(message = "广告位id不能为空")
+    private Long adsenseId;
+
+    @Schema(description = "排序号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "排序号不能为空")
+    private Integer sort;
+
+    @Schema(description = "标题")
+    private String title;
+
+    @Schema(description = "副标题")
+    private String subTitle;
+
+    @Schema(description = "上传图片地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
+    @NotEmpty(message = "上传图片地址不能为空")
+    private String advertUrl;
+
+    @Schema(description = "链接类型 0.外部链接 1.产品 2.子产品", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+    @NotNull(message = "链接类型不能为空")
+    private Integer linkType;
+
+    @Schema(description = "跳转地址", example = "https://www.iocoder.cn")
+    private String linkUrl;
+
+    @Schema(description = "是否投放 Ticket_Yes_No")
+    private Integer isDisplay;
+
+    @Schema(description = "有效期类型:0 永久,1限时", example = "2")
+    private Integer validType;
+
+    @Schema(description = "广告有效开始日期")
+    private LocalDateTime staDate;
+
+    @Schema(description = "广告有效结束日期")
+    private LocalDateTime endDate;
+
+}

+ 93 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advertlog/AdvertLogController.java

@@ -0,0 +1,93 @@
+package com.yc.ship.module.miniapplet.controller.admin.advertlog;
+
+import com.yc.ship.framework.common.pojo.CommonResult;
+import com.yc.ship.framework.common.pojo.PageParam;
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.framework.excel.core.util.ExcelUtils;
+import com.yc.ship.framework.operatelog.core.annotations.OperateLog;
+import com.yc.ship.module.miniapplet.controller.admin.advertlog.vo.AdvertLogPageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.advertlog.vo.AdvertLogRespVO;
+import com.yc.ship.module.miniapplet.controller.admin.advertlog.vo.AdvertLogSaveReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.advertlog.AdvertLogDO;
+import com.yc.ship.module.miniapplet.service.advertlog.AdvertLogService;
+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.yc.ship.framework.common.pojo.CommonResult.success;
+import static com.yc.ship.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
+
+@Tag(name = "管理后台 - 广告操作日志管理")
+@RestController
+@RequestMapping("/applet/advert-log")
+@Validated
+public class AdvertLogController {
+
+    @Resource
+    private AdvertLogService advertLogService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建广告操作日志管理")
+    @PreAuthorize("@ss.hasPermission('applet:advert-log:create')")
+    public CommonResult<Long> createAdvertLog(@Valid @RequestBody AdvertLogSaveReqVO createReqVO) {
+        return success(advertLogService.createAdvertLog(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新广告操作日志管理")
+    @PreAuthorize("@ss.hasPermission('applet:advert-log:update')")
+    public CommonResult<Boolean> updateAdvertLog(@Valid @RequestBody AdvertLogSaveReqVO updateReqVO) {
+        advertLogService.updateAdvertLog(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除广告操作日志管理")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('applet:advert-log:delete')")
+    public CommonResult<Boolean> deleteAdvertLog(@RequestParam("id") Long id) {
+        advertLogService.deleteAdvertLog(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得广告操作日志管理")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('applet:advert-log:query')")
+    public CommonResult<AdvertLogRespVO> getAdvertLog(@RequestParam("id") Long id) {
+        AdvertLogDO advertLog = advertLogService.getAdvertLog(id);
+        return success(BeanUtils.toBean(advertLog, AdvertLogRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得广告操作日志管理分页")
+    @PreAuthorize("@ss.hasPermission('applet:advert-log:query')")
+    public CommonResult<PageResult<AdvertLogRespVO>> getAdvertLogPage(@Valid AdvertLogPageReqVO pageReqVO) {
+        PageResult<AdvertLogDO> pageResult = advertLogService.getAdvertLogPage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, AdvertLogRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出广告操作日志管理 Excel")
+    @PreAuthorize("@ss.hasPermission('applet:advert-log:export')")
+    @OperateLog(type = EXPORT,enable = false)
+    public void exportAdvertLogExcel(@Valid AdvertLogPageReqVO pageReqVO,
+                                     HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<AdvertLogDO> list = advertLogService.getAdvertLogPage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "广告操作日志管理.xls", "数据", AdvertLogRespVO.class,
+                BeanUtils.toBean(list, AdvertLogRespVO.class));
+    }
+
+}

+ 43 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advertlog/vo/AdvertLogPageReqVO.java

@@ -0,0 +1,43 @@
+package com.yc.ship.module.miniapplet.controller.admin.advertlog.vo;
+
+import com.yc.ship.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.yc.ship.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 AdvertLogPageReqVO extends PageParam {
+
+    @Schema(description = "广告id", example = "26042")
+    private Long advertId;
+
+    @Schema(description = "副标题")
+    private String subTitle;
+
+    @Schema(description = "上传图片地址", example = "https://www.iocoder.cn")
+    private String advertUrl;
+
+    @Schema(description = "跳转地址", example = "https://www.iocoder.cn")
+    private String linkUrl;
+
+    @Schema(description = "来源")
+    private String appSource;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createDate;
+
+    @Schema(description = "微信openId", example = "19783")
+    private String openId;
+
+}

+ 47 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advertlog/vo/AdvertLogRespVO.java

@@ -0,0 +1,47 @@
+package com.yc.ship.module.miniapplet.controller.admin.advertlog.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 广告操作日志管理 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class AdvertLogRespVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "27580")
+    @ExcelProperty("主键")
+    private Long id;
+
+    @Schema(description = "广告id", requiredMode = Schema.RequiredMode.REQUIRED, example = "26042")
+    @ExcelProperty("广告id")
+    private Long advertId;
+
+    @Schema(description = "副标题")
+    @ExcelProperty("副标题")
+    private String subTitle;
+
+    @Schema(description = "上传图片地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
+    @ExcelProperty("上传图片地址")
+    private String advertUrl;
+
+    @Schema(description = "跳转地址", example = "https://www.iocoder.cn")
+    @ExcelProperty("跳转地址")
+    private String linkUrl;
+
+    @Schema(description = "来源")
+    @ExcelProperty("来源")
+    private String appSource;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createDate;
+
+    @Schema(description = "微信openId", example = "19783")
+    @ExcelProperty("微信openId")
+    private String openId;
+
+}

+ 41 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/advertlog/vo/AdvertLogSaveReqVO.java

@@ -0,0 +1,41 @@
+package com.yc.ship.module.miniapplet.controller.admin.advertlog.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 广告操作日志管理新增/修改 Request VO")
+@Data
+public class AdvertLogSaveReqVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "27580")
+    private Long id;
+
+    @Schema(description = "广告id", requiredMode = Schema.RequiredMode.REQUIRED, example = "26042")
+    @NotNull(message = "广告id不能为空")
+    private Long advertId;
+
+    @Schema(description = "副标题")
+    private String subTitle;
+
+    @Schema(description = "上传图片地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
+    @NotEmpty(message = "上传图片地址不能为空")
+    private String advertUrl;
+
+    @Schema(description = "跳转地址", example = "https://www.iocoder.cn")
+    private String linkUrl;
+
+    @Schema(description = "来源")
+    private String appSource;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "创建时间不能为空")
+    private LocalDateTime createDate;
+
+    @Schema(description = "微信openId", example = "19783")
+    private String openId;
+
+}

+ 107 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problem/ProblemController.java

@@ -0,0 +1,107 @@
+package com.yc.ship.module.miniapplet.controller.admin.problem;
+
+import com.yc.ship.framework.common.pojo.CommonResult;
+import com.yc.ship.framework.common.pojo.PageParam;
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.common.util.collection.CollectionUtils;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+
+import com.yc.ship.framework.excel.core.util.ExcelUtils;
+import com.yc.ship.framework.operatelog.core.annotations.OperateLog;
+import com.yc.ship.module.miniapplet.controller.admin.problem.vo.ProblemPageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.problem.vo.ProblemRespVO;
+import com.yc.ship.module.miniapplet.controller.admin.problem.vo.ProblemSaveReqVO;
+import com.yc.ship.module.miniapplet.convert.problemtype.ProblemTypeConvert;
+import com.yc.ship.module.miniapplet.dal.dataobject.problem.ProblemDO;
+import com.yc.ship.module.miniapplet.dal.dataobject.problemtype.ProblemTypeDO;
+import com.yc.ship.module.miniapplet.service.problem.ProblemService;
+import com.yc.ship.module.miniapplet.service.problemtype.ProblemTypeService;
+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 java.util.Map;
+
+import static com.yc.ship.framework.common.pojo.CommonResult.success;
+import static com.yc.ship.framework.common.util.collection.CollectionUtils.convertList;
+import static com.yc.ship.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
+
+
+@Tag(name = "管理后台 - 问题管理")
+@RestController
+@RequestMapping("/applet/problem")
+@Validated
+public class ProblemController {
+
+    @Resource
+    private ProblemService problemService;
+
+    @Resource
+    private ProblemTypeService problemTypeService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建问题管理")
+    @PreAuthorize("@ss.hasPermission('applet:problem:create')")
+    public CommonResult<Long> createProblem(@Valid @RequestBody ProblemSaveReqVO createReqVO) {
+        return success(problemService.createProblem(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新问题管理")
+    @PreAuthorize("@ss.hasPermission('applet:problem:update')")
+    public CommonResult<Boolean> updateProblem(@Valid @RequestBody ProblemSaveReqVO updateReqVO) {
+        problemService.updateProblem(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除问题管理")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('applet:problem:delete')")
+    public CommonResult<Boolean> deleteProblem(@RequestParam("id") Long id) {
+        problemService.deleteProblem(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得问题管理")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('applet:problem:query')")
+    public CommonResult<ProblemRespVO> getProblem(@RequestParam("id") Long id) {
+        ProblemDO problem = problemService.getProblem(id);
+        return success(BeanUtils.toBean(problem, ProblemRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得问题管理分页")
+    @PreAuthorize("@ss.hasPermission('applet:problem:query')")
+    public CommonResult<PageResult<ProblemRespVO>> getProblemPage(@Valid ProblemPageReqVO pageReqVO) {
+        PageResult<ProblemDO> pageResult = problemService.getProblemPage(pageReqVO);
+        List<ProblemTypeDO> otherList = problemTypeService.getProblemTypeList(convertList(pageResult.getList(), ProblemDO::getTypeId));
+        Map<Long, ProblemTypeDO> map = CollectionUtils.convertMap(otherList, ProblemTypeDO::getId);
+        return success(new PageResult<>(ProblemTypeConvert.INSTANCE.convertProblemList(pageResult.getList(), map), pageResult.getTotal()));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出问题管理 Excel")
+    @PreAuthorize("@ss.hasPermission('applet:problem:export')")
+    @OperateLog(type = EXPORT,enable = false)
+    public void exportProblemExcel(@Valid ProblemPageReqVO pageReqVO, HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<ProblemDO> list = problemService.getProblemPage(pageReqVO).getList();
+        List<ProblemTypeDO> otherList = problemTypeService.getProblemTypeList(convertList(list, ProblemDO::getTypeId));
+        Map<Long, ProblemTypeDO> map = CollectionUtils.convertMap(otherList, ProblemTypeDO::getId);
+        List<ProblemRespVO> respVOS = ProblemTypeConvert.INSTANCE.convertProblemList(list, map);
+        // 导出 Excel
+        ExcelUtils.write(response, "问题管理.xls", "数据", ProblemRespVO.class, respVOS);
+    }
+
+}

+ 34 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problem/vo/ProblemPageReqVO.java

@@ -0,0 +1,34 @@
+package com.yc.ship.module.miniapplet.controller.admin.problem.vo;
+
+import com.yc.ship.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+
+@Schema(description = "管理后台 - 问题管理分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class ProblemPageReqVO extends PageParam {
+
+    @Schema(description = "问题类型ID", example = "1729")
+    private Long typeId;
+
+    @Schema(description = "系统类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1729")
+    private Integer systemType;
+
+    @Schema(description = "标题")
+    private String title;
+
+    @Schema(description = "关键字")
+    private String keyword;
+
+
+    @Schema(description = "发布状态 0未发布 1已发布", example = "1")
+    private Integer releaseStatus;
+
+    @Schema(description = "启用状态 0否 1是")
+    private Integer isUse;
+}

+ 78 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problem/vo/ProblemRespVO.java

@@ -0,0 +1,78 @@
+package com.yc.ship.module.miniapplet.controller.admin.problem.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.yc.ship.framework.excel.core.annotations.DictFormat;
+import com.yc.ship.framework.excel.core.convert.DictConvert;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 问题管理 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class ProblemRespVO {
+
+    @Schema(description = "问题主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11839")
+//    @ExcelProperty("问题主键ID")
+    private Long id;
+
+    @Schema(description = "问题类型ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1729")
+//    @ExcelProperty("问题类型ID")
+    private Long typeId;
+
+    @Schema(description = "系统类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1729")
+    private Integer systemType;
+
+    @Schema(description = "问题类型", example = "22809")
+    @ExcelProperty("问题类型")
+    private String typeName;
+
+    @Schema(description = "标题")
+    @ExcelProperty("标题")
+    private String title;
+
+    @Schema(description = "文章内容")
+    @ExcelProperty("文章内容")
+    private String content;
+
+    @Schema(description = "文章简介", example = "你猜")
+    @ExcelProperty("文章简介")
+    private String remark;
+
+    @Schema(description = "关键字")
+    @ExcelProperty("关键字")
+    private String keyword;
+
+    @Schema(description = "封面图")
+    @ExcelProperty("封面图")
+    private String cover;
+
+    @Schema(description = "视频")
+    @ExcelProperty("视频")
+    private String video;
+
+    @Schema(description = "发布状态 0未发布 1已发布", example = "1")
+    @ExcelProperty(value = "发布状态 0未发布 1已发布", converter = DictConvert.class)
+    @DictFormat("release_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
+    private Integer releaseStatus;
+
+    @Schema(description = "发布时间")
+    @ExcelProperty("发布时间")
+    private LocalDateTime releaseTime;
+
+    @Schema(description = "启用状态 0否 1是")
+    @ExcelProperty(value = "启用状态 0否 1是", converter = DictConvert.class)
+    @DictFormat("use_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
+    private Integer isUse;
+
+    @Schema(description = "排序号")
+    @ExcelProperty("排序号")
+    private Integer sortNum;
+
+    @Schema(description = "创建时间")
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 54 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problem/vo/ProblemSaveReqVO.java

@@ -0,0 +1,54 @@
+package com.yc.ship.module.miniapplet.controller.admin.problem.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 问题管理新增/修改 Request VO")
+@Data
+public class ProblemSaveReqVO {
+
+    @Schema(description = "问题主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11839")
+    private Long id;
+
+    @Schema(description = "问题类型ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1729")
+    @NotNull(message = "问题类型ID不能为空")
+    private Long typeId;
+
+    @Schema(description = "系统类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1729")
+    @NotNull(message = "系统类型不能为空")
+    private Integer systemType;
+
+    @Schema(description = "标题")
+    private String title;
+
+    @Schema(description = "文章内容")
+    private String content;
+
+    @Schema(description = "文章简介", example = "你猜")
+    private String remark;
+
+    @Schema(description = "关键字")
+    private String keyword;
+
+    @Schema(description = "封面图")
+    private String cover;
+
+    @Schema(description = "视频")
+    private String video;
+
+    @Schema(description = "发布状态 0未发布 1已发布", example = "1")
+    private Integer releaseStatus;
+
+    @Schema(description = "发布时间")
+    private LocalDateTime releaseTime;
+
+    @Schema(description = "启用状态 0否 1是")
+    private Integer isUse;
+
+    @Schema(description = "排序号")
+    private Integer sortNum;
+
+}

+ 109 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problemtype/ProblemTypeController.java

@@ -0,0 +1,109 @@
+package com.yc.ship.module.miniapplet.controller.admin.problemtype;
+
+import com.yc.ship.framework.common.pojo.CommonResult;
+
+import com.yc.ship.framework.common.pojo.PageParam;
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.common.util.collection.CollectionUtils;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.framework.excel.core.util.ExcelUtils;
+import com.yc.ship.framework.operatelog.core.annotations.OperateLog;
+import com.yc.ship.module.miniapplet.controller.admin.problemtype.vo.ProblemTypePageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.problemtype.vo.ProblemTypeRespVO;
+import com.yc.ship.module.miniapplet.controller.admin.problemtype.vo.ProblemTypeSaveReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.problemtype.vo.ProblemTypeSimpleRespVO;
+import com.yc.ship.module.miniapplet.convert.problemtype.ProblemTypeConvert;
+import com.yc.ship.module.miniapplet.dal.dataobject.problemtype.ProblemTypeDO;
+import com.yc.ship.module.miniapplet.service.problemtype.ProblemTypeService;
+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 java.util.Map;
+
+import static com.yc.ship.framework.common.pojo.CommonResult.success;
+import static com.yc.ship.framework.common.util.collection.CollectionUtils.convertList;
+import static com.yc.ship.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
+
+@Tag(name = "管理后台 - 问题类型")
+@RestController
+@RequestMapping("/applet/problem-type")
+@Validated
+public class ProblemTypeController {
+
+    @Resource
+    private ProblemTypeService problemTypeService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建问题类型")
+    @PreAuthorize("@ss.hasPermission('applet:problem-type:create')")
+    public CommonResult<Long> createProblemType(@Valid @RequestBody ProblemTypeSaveReqVO createReqVO) {
+        return success(problemTypeService.createProblemType(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新问题类型")
+    @PreAuthorize("@ss.hasPermission('applet:problem-type:update')")
+    public CommonResult<Boolean> updateProblemType(@Valid @RequestBody ProblemTypeSaveReqVO updateReqVO) {
+        problemTypeService.updateProblemType(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除问题类型")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('applet:problem-type:delete')")
+    public CommonResult<Boolean> deleteProblemType(@RequestParam("id") Long id) {
+        problemTypeService.deleteProblemType(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得问题类型")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('applet:problem-type:query')")
+    public CommonResult<ProblemTypeRespVO> getProblemType(@RequestParam("id") Long id) {
+        ProblemTypeDO problemType = problemTypeService.getProblemType(id);
+        return success(BeanUtils.toBean(problemType, ProblemTypeRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得问题类型分页")
+    @PreAuthorize("@ss.hasPermission('applet:problem-type:query')")
+    public CommonResult<PageResult<ProblemTypeRespVO>> getProblemTypePage(@Valid ProblemTypePageReqVO pageReqVO) {
+        PageResult<ProblemTypeDO> pageResult = problemTypeService.getProblemTypePage(pageReqVO);
+        List<ProblemTypeDO> otherList = problemTypeService.getProblemTypeList(convertList(pageResult.getList(), ProblemTypeDO::getParentId));
+        Map<Long, ProblemTypeDO> map = CollectionUtils.convertMap(otherList, ProblemTypeDO::getId);
+        return success(new PageResult<>(ProblemTypeConvert.INSTANCE.convertProblemTypeList(pageResult.getList(), map), pageResult.getTotal()));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出问题类型 Excel")
+    @PreAuthorize("@ss.hasPermission('applet:problem-type:export')")
+    @OperateLog(type = EXPORT,enable = false)
+    public void exportProblemTypeExcel(@Valid ProblemTypePageReqVO pageReqVO, HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<ProblemTypeDO> list = problemTypeService.getProblemTypePage(pageReqVO).getList();
+        List<ProblemTypeDO> otherList = problemTypeService.getProblemTypeList(convertList(list, ProblemTypeDO::getParentId));
+        Map<Long, ProblemTypeDO> map = CollectionUtils.convertMap(otherList, ProblemTypeDO::getId);
+        List<ProblemTypeRespVO> respVOS = ProblemTypeConvert.INSTANCE.convertProblemTypeList(list, map);
+        // 导出 Excel
+        ExcelUtils.write(response, "问题类型.xls", "数据", ProblemTypeRespVO.class, respVOS);
+    }
+
+    @GetMapping({"/list-all-simple", "/simple-list"})
+    @Operation(summary = "获取精简信息列表", description = "只包含被开启的点位类型,主要用于前端的下拉选项")
+    public CommonResult<List<ProblemTypeSimpleRespVO>> getSimpleList(ProblemTypePageReqVO pageReqVO) {
+        List<ProblemTypeDO> list = problemTypeService.getProblemTypeListByStatus(pageReqVO.getSystemType(), pageReqVO.getIsUse());
+        return success(BeanUtils.toBean(list, ProblemTypeSimpleRespVO.class));
+    }
+
+}

+ 48 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problemtype/vo/ProblemTypePageReqVO.java

@@ -0,0 +1,48 @@
+package com.yc.ship.module.miniapplet.controller.admin.problemtype.vo;
+
+import com.yc.ship.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.yc.ship.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 ProblemTypePageReqVO extends PageParam {
+
+    @Schema(description = "问题名称", example = "张三")
+    private String name;
+
+    @Schema(description = "问题编码")
+    private String code;
+
+    @Schema(description = "系统类型 0.运营小程序 1.导游小程序")
+    private Integer systemType;
+
+    @Schema(description = "父级问题类型", example = "22809")
+    private Long parentId;
+
+    @Schema(description = "问题Icon图标")
+    private String logo;
+
+    @Schema(description = "备注", example = "随便")
+    private String remark;
+
+    @Schema(description = "启用状态 0否 1是")
+    private Integer isUse;
+
+    @Schema(description = "排序号")
+    private Integer sortNum;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

+ 58 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problemtype/vo/ProblemTypeRespVO.java

@@ -0,0 +1,58 @@
+package com.yc.ship.module.miniapplet.controller.admin.problemtype.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.yc.ship.framework.excel.core.annotations.DictFormat;
+import com.yc.ship.framework.excel.core.convert.DictConvert;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 问题类型 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class ProblemTypeRespVO {
+
+    @Schema(description = "问题类型主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "7385")
+//    @ExcelProperty("问题类型主键ID")
+    private Long id;
+
+    @Schema(description = "问题名称", example = "张三")
+    @ExcelProperty("问题名称")
+    private String name;
+
+    @Schema(description = "问题编码")
+    @ExcelProperty("问题编码")
+    private String code;
+
+    @Schema(description = "父级问题类型", example = "22809")
+//    @ExcelProperty("父级问题类型")
+    private Long parentId;
+
+    @Schema(description = "父级问题类型", example = "22809")
+    @ExcelProperty("父级问题类型")
+    private String parentName;
+
+    @Schema(description = "问题Icon图标")
+    @ExcelProperty("问题Icon图标")
+    private String logo;
+
+    @Schema(description = "备注", example = "随便")
+    @ExcelProperty("备注")
+    private String remark;
+
+    @Schema(description = "启用状态 0否 1是")
+    @ExcelProperty(value = "启用状态 0否 1是", converter = DictConvert.class)
+    @DictFormat("use_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
+    private Integer isUse;
+
+    @Schema(description = "排序号")
+    @ExcelProperty("排序号")
+    private Integer sortNum;
+
+    @Schema(description = "创建时间")
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 37 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problemtype/vo/ProblemTypeSaveReqVO.java

@@ -0,0 +1,37 @@
+package com.yc.ship.module.miniapplet.controller.admin.problemtype.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - 问题类型新增/修改 Request VO")
+@Data
+public class ProblemTypeSaveReqVO {
+
+    @Schema(description = "问题类型主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "7385")
+    private Long id;
+
+    @Schema(description = "问题名称", example = "张三")
+    private String name;
+
+    @Schema(description = "问题编码")
+    private String code;
+
+    @Schema(description = "系统类型 0.运营小程序 1.导游小程序")
+    private Integer systemType;
+
+    @Schema(description = "父级问题类型", example = "22809")
+    private Long parentId;
+
+    @Schema(description = "问题Icon图标")
+    private String logo;
+
+    @Schema(description = "备注", example = "随便")
+    private String remark;
+
+    @Schema(description = "启用状态 0否 1是")
+    private Integer isUse;
+
+    @Schema(description = "排序号")
+    private Integer sortNum;
+
+}

+ 20 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/admin/problemtype/vo/ProblemTypeSimpleRespVO.java

@@ -0,0 +1,20 @@
+package com.yc.ship.module.miniapplet.controller.admin.problemtype.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - 问题类型 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class ProblemTypeSimpleRespVO {
+
+    @Schema(description = "问题类型主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "7385")
+    private Long id;
+
+    @Schema(description = "问题名称", example = "张三")
+    private String name;
+
+    @Schema(description = "父级问题类型", example = "22809")
+    private Long parentId;
+}

+ 103 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/advert/AppAdvertController.java

@@ -0,0 +1,103 @@
+package com.yc.ship.module.miniapplet.controller.app.advert;
+
+import com.yc.ship.framework.common.pojo.CommonResult;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.module.miniapplet.controller.admin.advertlog.vo.AdvertLogSaveReqVO;
+import com.yc.ship.module.miniapplet.controller.app.advert.vo.AppAdsenseRespVO;
+import com.yc.ship.module.miniapplet.controller.app.advert.vo.AppAdvertLogReqVO;
+import com.yc.ship.module.miniapplet.controller.app.advert.vo.AppAdvertReqVO;
+import com.yc.ship.module.miniapplet.controller.app.advert.vo.AppAdvertRespVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.adsense.AdsenseDO;
+import com.yc.ship.module.miniapplet.dal.dataobject.advert.AdvertDO;
+import com.yc.ship.module.miniapplet.service.adsense.AdsenseService;
+import com.yc.ship.module.miniapplet.service.advert.AdvertService;
+import com.yc.ship.module.miniapplet.service.advertlog.AdvertLogService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.yc.ship.framework.common.pojo.CommonResult.success;
+
+/**
+ * @author :yaochao
+ * @description :TODO
+ * @date :2024/8/19 17:13
+ */
+@Tag(name = "用户 APP - 广告")
+@RestController
+@RequestMapping("/app/applet/advert")
+@Validated
+@Slf4j
+public class AppAdvertController {
+
+    @Resource
+    private AdsenseService adsenseService;
+
+    @Resource
+    private AdvertService advertService;
+
+    @Resource
+    private AdvertLogService advertLogService;
+
+    @PostMapping("/adsenseList")
+    public CommonResult<List<AppAdsenseRespVO>> catalogueList(@RequestBody @Valid AppAdvertReqVO reqVO) {
+        List<AdsenseDO> adsenseDOS = adsenseService.getAdsenseList(reqVO);
+        List<AppAdsenseRespVO> respVOS = BeanUtils.toBean(adsenseDOS, AppAdsenseRespVO.class);
+        return success(respVOS);
+    }
+
+    @PostMapping("/adsense")
+    public CommonResult<AppAdsenseRespVO> catalogue(@RequestBody @Valid AppAdvertReqVO reqVO) {
+        AdsenseDO adsenseDO = adsenseService.getAdsenseByCode(reqVO.getAdsenseCode());
+        AppAdsenseRespVO respVO = BeanUtils.toBean(adsenseDO, AppAdsenseRespVO.class);
+        return success(respVO);
+    }
+
+    @PostMapping("/advertList")
+    public CommonResult<List<AppAdvertRespVO>> contentList(@RequestBody @Valid AppAdvertReqVO reqVO) {
+        List<AppAdvertRespVO> respVOS = new ArrayList<>(3);
+        if (reqVO.getAdsenseId() == null) {
+            AdsenseDO adsenseDO = adsenseService.getAdsenseByCode(reqVO.getAdsenseCode());
+            if (adsenseDO != null) {
+                reqVO.setAdsenseId(adsenseDO.getId());
+            } else {
+                return success(respVOS);
+            }
+        }
+        List<AdvertDO> advertDOS = advertService.getAdvertList(reqVO.getAdsenseId());
+        LocalDateTime now = LocalDateTime.now();
+        advertDOS = advertDOS.stream()
+                .filter(advert -> advert.getIsDisplay() == 1 && (advert.getValidType() == 0 || (advert.getValidType() == 1 && (now.isAfter(advert.getStaDate()) && now.isBefore(advert.getEndDate())))))
+                .collect(Collectors.toList());
+        respVOS = BeanUtils.toBean(advertDOS, AppAdvertRespVO.class);
+        return success(respVOS);
+    }
+
+    @PostMapping("/advert")
+    public CommonResult<AppAdvertRespVO> content(@RequestBody @Valid AppAdvertReqVO reqVO) {
+        AdvertDO advertDO = advertService.getAdvert(reqVO.getAdvertId());
+        AppAdvertRespVO respVO = BeanUtils.toBean(advertDO, AppAdvertRespVO.class);
+        return success(respVO);
+    }
+
+    @PostMapping("/recordAdvertLog")
+    @Operation(summary = "记录广告操作日志")
+    public CommonResult<Long> content(@RequestBody @Valid AppAdvertLogReqVO reqVO) {
+        AdvertLogSaveReqVO createReqVO = BeanUtils.toBean(reqVO, AdvertLogSaveReqVO.class);
+        Long logId = advertLogService.createAdvertLog(createReqVO);
+        return success(logId);
+    }
+
+}

+ 30 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/advert/vo/AppAdsenseRespVO.java

@@ -0,0 +1,30 @@
+package com.yc.ship.module.miniapplet.controller.app.advert.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "小程序接口 - 目录内容 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class AppAdsenseRespVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "19883")
+    private Long id;
+
+    @Schema(description = "广告位代码", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String adsenseCode;
+
+    @Schema(description = "广告位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
+    private String adsenseName;
+
+    @Schema(description = "媒体类型:0单图片、1单视频、2图片轮播", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Integer adsenseType;
+
+    @Schema(description = "启用状态 0否 1是", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Integer isUse;
+
+    @Schema(description = "备注")
+    private String remark;
+
+}

+ 41 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/advert/vo/AppAdvertLogReqVO.java

@@ -0,0 +1,41 @@
+package com.yc.ship.module.miniapplet.controller.app.advert.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+@Schema(description = "小程序 - 查询广告位请求参数")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class AppAdvertLogReqVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "27580")
+    private Long id;
+
+    @Schema(description = "广告id", requiredMode = Schema.RequiredMode.REQUIRED, example = "26042")
+    @NotNull(message = "广告id不能为空")
+    private Long advertId;
+
+    @Schema(description = "副标题")
+    private String subTitle;
+
+    @Schema(description = "上传图片地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
+    @NotEmpty(message = "上传图片地址不能为空")
+    private String advertUrl;
+
+    @Schema(description = "跳转地址", example = "https://www.iocoder.cn")
+    private String linkUrl;
+
+    @Schema(description = "来源")
+    private String appSource;
+
+    @Schema(description = "微信openId", example = "19783")
+    private String openId;
+}

+ 25 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/advert/vo/AppAdvertReqVO.java

@@ -0,0 +1,25 @@
+package com.yc.ship.module.miniapplet.controller.app.advert.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Schema(description = "小程序 - 查询广告相关请求参数")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class AppAdvertReqVO {
+
+    @Schema(description = "广告id", requiredMode = Schema.RequiredMode.REQUIRED, example = "25367")
+    private Long advertId;
+
+    @Schema(description = "广告位id", requiredMode = Schema.RequiredMode.REQUIRED, example = "25367")
+    private Long adsenseId;
+
+    @Schema(description = "广告位代码", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String adsenseCode;
+
+}

+ 15 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/advert/vo/AppAdvertRespVO.java

@@ -0,0 +1,15 @@
+package com.yc.ship.module.miniapplet.controller.app.advert.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.yc.ship.module.miniapplet.controller.admin.advert.vo.AdvertRespVO;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Schema(description = "小程序接口 - 广告 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class AppAdvertRespVO extends AdvertRespVO {
+
+}

+ 77 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/problem/AppProblemController.java

@@ -0,0 +1,77 @@
+package com.yc.ship.module.miniapplet.controller.app.problem;
+
+import com.yc.ship.framework.common.pojo.CommonResult;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.module.miniapplet.controller.app.problem.vo.AppProblemReqVO;
+import com.yc.ship.module.miniapplet.controller.app.problem.vo.AppProblemRespVO;
+import com.yc.ship.module.miniapplet.controller.app.problem.vo.AppProblemTypeRespVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.problem.ProblemDO;
+import com.yc.ship.module.miniapplet.dal.dataobject.problemtype.ProblemTypeDO;
+import com.yc.ship.module.miniapplet.service.problem.ProblemService;
+import com.yc.ship.module.miniapplet.service.problemtype.ProblemTypeService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
+
+import static com.yc.ship.framework.common.pojo.CommonResult.success;
+
+/**
+ * @author :yaochao
+ * @description :TODO
+ * @date :2024/8/19 17:13
+ */
+@Tag(name = "用户 APP - 问题类型/问题")
+@RestController
+@RequestMapping("/app/applet/problem")
+@Validated
+@Slf4j
+public class AppProblemController {
+
+    @Resource
+    private ProblemTypeService problemTypeService;
+
+    @Resource
+    private ProblemService problemService;
+
+    @PostMapping("/problemTypeList")
+    @Operation(summary = "获取问题类型列表")
+    public CommonResult<List<AppProblemTypeRespVO>> problemTypeList(@RequestBody @Valid AppProblemReqVO reqVO) {
+        List<ProblemTypeDO> problemTypeDOS = problemTypeService.getProblemTypeListByApp(reqVO);
+        List<AppProblemTypeRespVO> respVOS = BeanUtils.toBean(problemTypeDOS, AppProblemTypeRespVO.class);
+        return success(respVOS);
+    }
+
+    @PostMapping("/problemType")
+    @Operation(summary = "获取问题类型详情")
+    public CommonResult<AppProblemTypeRespVO> problemType(@RequestBody @Valid AppProblemReqVO reqVO) {
+        ProblemTypeDO problemTypeDO = problemTypeService.getProblemType(reqVO.getProblemTypeId());
+        AppProblemTypeRespVO respVO = BeanUtils.toBean(problemTypeDO, AppProblemTypeRespVO.class);
+        return success(respVO);
+    }
+
+    @PostMapping("/problemList")
+    @Operation(summary = "获取问题列表")
+    public CommonResult<List<AppProblemRespVO>> problemList(@RequestBody @Valid AppProblemReqVO reqVO) {
+        List<ProblemDO> problemDOS = problemService.getProblemList(reqVO);
+        List<AppProblemRespVO> respVOS = BeanUtils.toBean(problemDOS, AppProblemRespVO.class);
+        return success(respVOS);
+    }
+
+    @PostMapping("/problem")
+    @Operation(summary = "获取问题详情")
+    public CommonResult<AppProblemRespVO> problem(@RequestBody @Valid AppProblemReqVO reqVO) {
+        ProblemDO problemDO = problemService.getProblem(reqVO.getProblemId());
+        AppProblemRespVO respVO = BeanUtils.toBean(problemDO, AppProblemRespVO.class);
+        return success(respVO);
+    }
+
+}

+ 33 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/problem/vo/AppProblemReqVO.java

@@ -0,0 +1,33 @@
+package com.yc.ship.module.miniapplet.controller.app.problem.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Schema(description = "APP - 点位线路请求参数")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class AppProblemReqVO {
+
+    @Schema(description = "问题ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1729")
+    private Long problemId;
+
+    @Schema(description = "问题名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1729")
+    private String problemName;
+
+    @Schema(description = "问题编码")
+    private String code;
+
+    @Schema(description = "系统类型 0.运营小程序 1.导游小程序")
+    private Integer systemType;
+
+    @Schema(description = "问题类型ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1729")
+    private Long problemTypeId;
+
+    @Schema(description = "问题类型父级ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1729")
+    private Long problemTypeParentId;
+}

+ 57 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/problem/vo/AppProblemRespVO.java

@@ -0,0 +1,57 @@
+package com.yc.ship.module.miniapplet.controller.app.problem.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "小程序接口 - 线路 Response VO")
+@Data
+public class AppProblemRespVO {
+
+    @Schema(description = "问题主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11839")
+    private Long id;
+
+    @Schema(description = "问题类型ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1729")
+    private Long typeId;
+
+    @Schema(description = "系统类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1729")
+    private Integer systemType;
+
+    @Schema(description = "问题类型", example = "22809")
+    private String typeName;
+
+    @Schema(description = "标题")
+    private String title;
+
+    @Schema(description = "文章内容")
+    private String content;
+
+    @Schema(description = "文章简介", example = "你猜")
+    private String remark;
+
+    @Schema(description = "关键字")
+    private String keyword;
+
+    @Schema(description = "封面图")
+    private String cover;
+
+    @Schema(description = "视频")
+    private String video;
+
+    @Schema(description = "发布状态 0未发布 1已发布", example = "1")
+    private Integer releaseStatus;
+
+    @Schema(description = "发布时间")
+    private LocalDateTime releaseTime;
+
+    @Schema(description = "启用状态 0否 1是")
+    private Integer isUse;
+
+    @Schema(description = "排序号")
+    private Integer sortNum;
+
+    @Schema(description = "创建时间")
+    private LocalDateTime createTime;
+
+}

+ 42 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/controller/app/problem/vo/AppProblemTypeRespVO.java

@@ -0,0 +1,42 @@
+package com.yc.ship.module.miniapplet.controller.app.problem.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 问题类型 Response VO")
+@Data
+public class AppProblemTypeRespVO {
+
+    @Schema(description = "问题类型主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "7385")
+    private Long id;
+
+    @Schema(description = "问题名称", example = "张三")
+    private String name;
+
+    @Schema(description = "问题编码")
+    private String code;
+
+    @Schema(description = "父级问题类型", example = "22809")
+    private Long parentId;
+
+    @Schema(description = "父级问题类型", example = "22809")
+    private String parentName;
+
+    @Schema(description = "问题Icon图标")
+    private String logo;
+
+    @Schema(description = "备注", example = "随便")
+    private String remark;
+
+    @Schema(description = "启用状态 0否 1是")
+    private Integer isUse;
+
+    @Schema(description = "排序号")
+    private Integer sortNum;
+
+    @Schema(description = "创建时间")
+    private LocalDateTime createTime;
+
+}

+ 29 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/convert/adsense/AdsenseConvert.java

@@ -0,0 +1,29 @@
+package com.yc.ship.module.miniapplet.convert.adsense;
+
+import com.yc.ship.framework.common.util.collection.CollectionUtils;
+import com.yc.ship.framework.common.util.collection.MapUtils;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.module.miniapplet.controller.admin.advert.vo.AdvertRespVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.adsense.AdsenseDO;
+import com.yc.ship.module.miniapplet.dal.dataobject.advert.AdvertDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface AdsenseConvert {
+
+    AdsenseConvert INSTANCE = Mappers.getMapper(AdsenseConvert.class);
+
+    default List<AdvertRespVO> convertAdvertList(List<AdvertDO> list, Map<Long, AdsenseDO> adsenseMap) {
+        return CollectionUtils.convertList(list, advert -> {
+            AdvertRespVO advertVO = BeanUtils.toBean(advert, AdvertRespVO.class);
+            MapUtils.findAndThen(adsenseMap, advert.getAdsenseId(), c -> advertVO.setAdsenseName(c.getAdsenseName()));
+            return advertVO;
+        });
+    }
+
+
+}

+ 37 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/convert/problemtype/ProblemTypeConvert.java

@@ -0,0 +1,37 @@
+package com.yc.ship.module.miniapplet.convert.problemtype;
+
+import com.yc.ship.framework.common.util.collection.CollectionUtils;
+import com.yc.ship.framework.common.util.collection.MapUtils;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.module.miniapplet.controller.admin.problem.vo.ProblemRespVO;
+import com.yc.ship.module.miniapplet.controller.admin.problemtype.vo.ProblemTypeRespVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.problem.ProblemDO;
+import com.yc.ship.module.miniapplet.dal.dataobject.problemtype.ProblemTypeDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface ProblemTypeConvert {
+
+    ProblemTypeConvert INSTANCE = Mappers.getMapper(ProblemTypeConvert.class);
+
+    default List<ProblemTypeRespVO> convertProblemTypeList(List<ProblemTypeDO> list, Map<Long, ProblemTypeDO> map) {
+        return CollectionUtils.convertList(list, problemType -> {
+            ProblemTypeRespVO problemTypeVO = BeanUtils.toBean(problemType, ProblemTypeRespVO.class);
+            MapUtils.findAndThen(map, problemType.getParentId(), c -> problemTypeVO.setParentName(c.getName()));
+            return problemTypeVO;
+        });
+    }
+
+    default List<ProblemRespVO> convertProblemList(List<ProblemDO> list, Map<Long, ProblemTypeDO> map) {
+        return CollectionUtils.convertList(list, problem -> {
+            ProblemRespVO problemVO = BeanUtils.toBean(problem, ProblemRespVO.class);
+            MapUtils.findAndThen(map, problem.getTypeId(), c -> problemVO.setTypeName(c.getName()));
+            return problemVO;
+        });
+    }
+
+}

+ 54 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/dataobject/adsense/AdsenseDO.java

@@ -0,0 +1,54 @@
+package com.yc.ship.module.miniapplet.dal.dataobject.adsense;
+
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.sun.xml.bind.v2.TODO;
+import com.yc.ship.framework.tenant.core.db.TenantBaseDO;
+import lombok.*;
+
+/**
+ * 广告位管理 DO
+ *
+ * @author 管理员
+ */
+@TableName("applet_adsense")
+@KeySequence("applet_adsense_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class AdsenseDO extends TenantBaseDO {
+
+    /**
+     * 主键
+     */
+    @TableId
+    private Long id;
+    /**
+     * 广告位代码
+     */
+    private String adsenseCode;
+    /**
+     * 广告位名称
+     */
+    private String adsenseName;
+    /**
+     * 媒体类型:0单图片、1单视频、2图片轮播
+     * <p>
+     * 枚举 {@link TODO adsense_type 对应的类}
+     */
+    private Integer adsenseType;
+
+    /**
+     * 启用状态 0否 1是
+     */
+    private Integer isUse;
+    /**
+     * 备注
+     */
+    private String remark;
+
+}

+ 79 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/dataobject/advert/AdvertDO.java

@@ -0,0 +1,79 @@
+package com.yc.ship.module.miniapplet.dal.dataobject.advert;
+
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.sun.xml.bind.v2.TODO;
+import com.yc.ship.framework.tenant.core.db.TenantBaseDO;
+import lombok.*;
+
+import java.time.LocalDateTime;
+
+/**
+ * 广告管理 DO
+ *
+ * @author 管理员
+ */
+@TableName("applet_advert")
+@KeySequence("applet_advert_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class AdvertDO extends TenantBaseDO {
+
+    /**
+     * 主键
+     */
+    @TableId
+    private Long id;
+    /**
+     * 广告位id
+     */
+    private Long adsenseId;
+    /**
+     * 排序号
+     */
+    private Integer sort;
+    /**
+     * 标题
+     */
+    private String title;
+    /**
+     * 副标题
+     */
+    private String subTitle;
+    /**
+     * 上传图片地址
+     */
+    private String advertUrl;
+    /**
+     * 链接类型 0.外部链接 1.产品 2.子产品
+     */
+    private Integer linkType;
+    /**
+     * 跳转地址
+     */
+    private String linkUrl;
+    /**
+     * 是否投放 Ticket_Yes_No
+     * <p>
+     * 枚举 {@link TODO yes_no 对应的类}
+     */
+    private Integer isDisplay;
+    /**
+     * 有效期类型:0 永久,1限时
+     */
+    private Integer validType;
+    /**
+     * 广告有效开始日期
+     */
+    private LocalDateTime staDate;
+    /**
+     * 广告有效结束日期
+     */
+    private LocalDateTime endDate;
+
+}

+ 60 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/dataobject/advertlog/AdvertLogDO.java

@@ -0,0 +1,60 @@
+package com.yc.ship.module.miniapplet.dal.dataobject.advertlog;
+
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.yc.ship.framework.tenant.core.db.TenantBaseDO;
+import lombok.*;
+
+import java.time.LocalDateTime;
+
+/**
+ * 广告操作日志管理 DO
+ *
+ * @author 管理员
+ */
+@TableName("applet_advert_log")
+@KeySequence("applet_advert_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class AdvertLogDO extends TenantBaseDO {
+
+    /**
+     * 主键
+     */
+    @TableId
+    private Long id;
+    /**
+     * 广告id
+     */
+    private Long advertId;
+    /**
+     * 副标题
+     */
+    private String subTitle;
+    /**
+     * 上传图片地址
+     */
+    private String advertUrl;
+    /**
+     * 跳转地址
+     */
+    private String linkUrl;
+    /**
+     * 来源
+     */
+    private String appSource;
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createDate;
+    /**
+     * 微信openId
+     */
+    private String openId;
+
+}

+ 85 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/dataobject/problem/ProblemDO.java

@@ -0,0 +1,85 @@
+package com.yc.ship.module.miniapplet.dal.dataobject.problem;
+
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.sun.xml.bind.v2.TODO;
+import com.yc.ship.framework.tenant.core.db.TenantBaseDO;
+import lombok.*;
+
+import java.time.LocalDateTime;
+
+/**
+ * 问题管理 DO
+ *
+ * @author 管理员
+ */
+@TableName("applet_problem")
+@KeySequence("applet_problem_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ProblemDO extends TenantBaseDO {
+
+    /**
+     * 问题主键ID
+     */
+    @TableId
+    private Long id;
+    /**
+     * 问题类型ID
+     */
+    private Long typeId;
+    /**
+     * 系统类型 0.运营小程序 1.导游小程序
+     */
+    private Integer systemType;
+    /**
+     * 标题
+     */
+    private String title;
+    /**
+     * 文章内容
+     */
+    private String content;
+    /**
+     * 文章简介
+     */
+    private String remark;
+    /**
+     * 关键字
+     */
+    private String keyword;
+    /**
+     * 封面图
+     */
+    private String cover;
+    /**
+     * 视频
+     */
+    private String video;
+    /**
+     * 发布状态 0未发布 1已发布
+     * <p>
+     * 枚举 {@link TODO release_status 对应的类}
+     */
+    private Integer releaseStatus;
+    /**
+     * 发布时间
+     */
+    private LocalDateTime releaseTime;
+    /**
+     * 启用状态 0否 1是
+     * <p>
+     * 枚举 {@link TODO use_status 对应的类}
+     */
+    private Integer isUse;
+    /**
+     * 排序号
+     */
+    private Integer sortNum;
+
+}

+ 65 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/dataobject/problemtype/ProblemTypeDO.java

@@ -0,0 +1,65 @@
+package com.yc.ship.module.miniapplet.dal.dataobject.problemtype;
+
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.sun.xml.bind.v2.TODO;
+import com.yc.ship.framework.tenant.core.db.TenantBaseDO;
+import lombok.*;
+
+/**
+ * 问题类型 DO
+ *
+ * @author 管理员
+ */
+@TableName("applet_problem_type")
+@KeySequence("applet_problem_type_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ProblemTypeDO extends TenantBaseDO {
+
+    /**
+     * 问题类型主键ID
+     */
+    @TableId
+    private Long id;
+    /**
+     * 问题名称
+     */
+    private String name;
+    /**
+     * 问题编码
+     */
+    private String code;
+    /**
+     * 系统类型 0.运营小程序 1.导游小程序
+     */
+    private Integer systemType;
+    /**
+     * 父级问题类型
+     */
+    private Long parentId;
+    /**
+     * 问题Icon图标
+     */
+    private String logo;
+    /**
+     * 备注
+     */
+    private String remark;
+    /**
+     * 启用状态 0否 1是
+     * <p>
+     * 枚举 {@link TODO use_status 对应的类}
+     */
+    private Integer isUse;
+    /**
+     * 排序号
+     */
+    private Integer sortNum;
+
+}

+ 49 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/mysql/adsense/AdsenseMapper.java

@@ -0,0 +1,49 @@
+package com.yc.ship.module.miniapplet.dal.mysql.adsense;
+
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.mybatis.core.mapper.BaseMapperX;
+import com.yc.ship.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.yc.ship.module.miniapplet.controller.admin.adsense.vo.AdsensePageReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.adsense.AdsenseDO;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 广告位管理 Mapper
+ *
+ * @author 管理员
+ */
+@Mapper
+public interface AdsenseMapper extends BaseMapperX<AdsenseDO> {
+
+    default PageResult<AdsenseDO> selectPage(AdsensePageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<AdsenseDO>()
+                .eqIfPresent(AdsenseDO::getAdsenseCode, reqVO.getAdsenseCode())
+                .likeIfPresent(AdsenseDO::getAdsenseName, reqVO.getAdsenseName())
+                .eqIfPresent(AdsenseDO::getAdsenseType, reqVO.getAdsenseType())
+                .betweenIfPresent(AdsenseDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(AdsenseDO::getId));
+    }
+
+    default List<AdsenseDO> selectList(Integer status) {
+        LambdaQueryWrapperX<AdsenseDO> queryWrapper = new LambdaQueryWrapperX<>();
+        queryWrapper.eq(AdsenseDO::getIsUse, status);
+        queryWrapper.orderByDesc(AdsenseDO::getCreateTime);
+        return selectList(queryWrapper);
+    }
+
+    default List<AdsenseDO> getAdsenseList(Long id, String code) {
+        LambdaQueryWrapperX<AdsenseDO> queryWrapper = new LambdaQueryWrapperX<>();
+        if (id != null) {
+            queryWrapper.eq(AdsenseDO::getId, id);
+        }
+        if (StringUtils.isNotBlank(code)) {
+            queryWrapper.eq(AdsenseDO::getAdsenseCode, code);
+        }
+        queryWrapper.eq(AdsenseDO::getIsUse, 1);
+        queryWrapper.orderByDesc(AdsenseDO::getCreateTime);
+        return selectList(queryWrapper);
+    }
+}

+ 42 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/mysql/advert/AdvertMapper.java

@@ -0,0 +1,42 @@
+package com.yc.ship.module.miniapplet.dal.mysql.advert;
+
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.mybatis.core.mapper.BaseMapperX;
+import com.yc.ship.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.yc.ship.module.miniapplet.controller.admin.advert.vo.AdvertPageReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.advert.AdvertDO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 广告管理 Mapper
+ *
+ * @author 管理员
+ */
+@Mapper
+public interface AdvertMapper extends BaseMapperX<AdvertDO> {
+
+    default PageResult<AdvertDO> selectPage(AdvertPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<AdvertDO>()
+                .eqIfPresent(AdvertDO::getAdsenseId, reqVO.getAdsenseId())
+                .eqIfPresent(AdvertDO::getSort, reqVO.getSort())
+                .eqIfPresent(AdvertDO::getTitle, reqVO.getTitle())
+                .eqIfPresent(AdvertDO::getSubTitle, reqVO.getSubTitle())
+                .eqIfPresent(AdvertDO::getAdvertUrl, reqVO.getAdvertUrl())
+                .eqIfPresent(AdvertDO::getLinkUrl, reqVO.getLinkUrl())
+                .eqIfPresent(AdvertDO::getIsDisplay, reqVO.getIsDisplay())
+                .eqIfPresent(AdvertDO::getValidType, reqVO.getValidType())
+                .betweenIfPresent(AdvertDO::getStaDate, reqVO.getStaDate())
+                .betweenIfPresent(AdvertDO::getEndDate, reqVO.getEndDate())
+                .betweenIfPresent(AdvertDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(AdvertDO::getId));
+    }
+
+    default List<AdvertDO> selectAdvertList(Long adsenseId) {
+        LambdaQueryWrapperX<AdvertDO> wrapperX = new LambdaQueryWrapperX<>();
+        wrapperX.eqIfPresent(AdvertDO::getAdsenseId, adsenseId);
+        wrapperX.orderByDesc(AdvertDO::getSort);
+        return selectList(wrapperX);
+    }
+}

+ 30 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/mysql/advertlog/AdvertLogMapper.java

@@ -0,0 +1,30 @@
+package com.yc.ship.module.miniapplet.dal.mysql.advertlog;
+
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.mybatis.core.mapper.BaseMapperX;
+import com.yc.ship.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.yc.ship.module.miniapplet.controller.admin.advertlog.vo.AdvertLogPageReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.advertlog.AdvertLogDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 广告操作日志管理 Mapper
+ *
+ * @author 管理员
+ */
+@Mapper
+public interface AdvertLogMapper extends BaseMapperX<AdvertLogDO> {
+
+    default PageResult<AdvertLogDO> selectPage(AdvertLogPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<AdvertLogDO>()
+                .eqIfPresent(AdvertLogDO::getAdvertId, reqVO.getAdvertId())
+                .eqIfPresent(AdvertLogDO::getSubTitle, reqVO.getSubTitle())
+                .eqIfPresent(AdvertLogDO::getAdvertUrl, reqVO.getAdvertUrl())
+                .eqIfPresent(AdvertLogDO::getLinkUrl, reqVO.getLinkUrl())
+                .eqIfPresent(AdvertLogDO::getAppSource, reqVO.getAppSource())
+                .betweenIfPresent(AdvertLogDO::getCreateDate, reqVO.getCreateDate())
+                .eqIfPresent(AdvertLogDO::getOpenId, reqVO.getOpenId())
+                .orderByDesc(AdvertLogDO::getId));
+    }
+
+}

+ 41 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/mysql/problem/ProblemMapper.java

@@ -0,0 +1,41 @@
+package com.yc.ship.module.miniapplet.dal.mysql.problem;
+
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.mybatis.core.mapper.BaseMapperX;
+import com.yc.ship.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.yc.ship.module.miniapplet.controller.admin.problem.vo.ProblemPageReqVO;
+import com.yc.ship.module.miniapplet.controller.app.problem.vo.AppProblemReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.problem.ProblemDO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 问题管理 Mapper
+ *
+ * @author 管理员
+ */
+@Mapper
+public interface ProblemMapper extends BaseMapperX<ProblemDO> {
+
+    default PageResult<ProblemDO> selectPage(ProblemPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<ProblemDO>()
+                .eqIfPresent(ProblemDO::getTypeId, reqVO.getTypeId())
+                .eqIfPresent(ProblemDO::getTitle, reqVO.getTitle())
+                .eqIfPresent(ProblemDO::getKeyword, reqVO.getKeyword())
+                .eqIfPresent(ProblemDO::getSystemType, reqVO.getSystemType())
+                .eqIfPresent(ProblemDO::getReleaseStatus, reqVO.getReleaseStatus())
+                .eqIfPresent(ProblemDO::getIsUse, reqVO.getIsUse())
+                .orderByDesc(ProblemDO::getId));
+    }
+
+    default List<ProblemDO> getProblemList(AppProblemReqVO reqVO) {
+        return selectList(new LambdaQueryWrapperX<ProblemDO>()
+                .eqIfPresent(ProblemDO::getTypeId, reqVO.getProblemTypeId())
+                .likeIfPresent(ProblemDO::getTitle, reqVO.getProblemName())
+                .eqIfPresent(ProblemDO::getSystemType, reqVO.getSystemType())
+                .eqIfPresent(ProblemDO::getIsUse, 1)
+                .orderByDesc(ProblemDO::getSortNum, ProblemDO::getId));
+    }
+
+}

+ 52 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/dal/mysql/problemtype/ProblemTypeMapper.java

@@ -0,0 +1,52 @@
+package com.yc.ship.module.miniapplet.dal.mysql.problemtype;
+
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.mybatis.core.mapper.BaseMapperX;
+import com.yc.ship.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.yc.ship.module.miniapplet.controller.admin.problemtype.vo.ProblemTypePageReqVO;
+import com.yc.ship.module.miniapplet.controller.app.problem.vo.AppProblemReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.problemtype.ProblemTypeDO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 问题类型 Mapper
+ *
+ * @author 管理员
+ */
+@Mapper
+public interface ProblemTypeMapper extends BaseMapperX<ProblemTypeDO> {
+
+    default PageResult<ProblemTypeDO> selectPage(ProblemTypePageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<ProblemTypeDO>()
+                .likeIfPresent(ProblemTypeDO::getName, reqVO.getName())
+                .eqIfPresent(ProblemTypeDO::getCode, reqVO.getCode())
+                .eqIfPresent(ProblemTypeDO::getParentId, reqVO.getParentId())
+                .eqIfPresent(ProblemTypeDO::getLogo, reqVO.getLogo())
+                .eqIfPresent(ProblemTypeDO::getSystemType, reqVO.getSystemType())
+                .eqIfPresent(ProblemTypeDO::getRemark, reqVO.getRemark())
+                .eqIfPresent(ProblemTypeDO::getIsUse, reqVO.getIsUse())
+                .eqIfPresent(ProblemTypeDO::getSortNum, reqVO.getSortNum())
+                .betweenIfPresent(ProblemTypeDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(ProblemTypeDO::getId));
+    }
+
+    default List<ProblemTypeDO> getProblemTypeListByStatus(Integer systemType, Integer status) {
+        return selectList(new LambdaQueryWrapperX<ProblemTypeDO>()
+                .eqIfPresent(ProblemTypeDO::getSystemType, systemType)
+                .eqIfPresent(ProblemTypeDO::getIsUse, status)
+                .orderByDesc(ProblemTypeDO::getCreateTime));
+    }
+
+    default List<ProblemTypeDO> getProblemTypeListByApp(AppProblemReqVO reqVO) {
+        return selectList(new LambdaQueryWrapperX<ProblemTypeDO>()
+                .eqIfPresent(ProblemTypeDO::getIsUse, 1)
+                .eqIfPresent(ProblemTypeDO::getId, reqVO.getProblemTypeId())
+                .eqIfPresent(ProblemTypeDO::getParentId, reqVO.getProblemTypeParentId())
+                .eqIfPresent(ProblemTypeDO::getSystemType, reqVO.getSystemType())
+                .eqIfPresent(ProblemTypeDO::getCode, reqVO.getCode())
+                .orderByDesc(ProblemTypeDO::getSortNum, ProblemTypeDO::getId)
+        );
+    }
+}

+ 29 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/enums/ErrorCodeConstants.java

@@ -0,0 +1,29 @@
+package com.yc.ship.module.miniapplet.enums;
+
+import com.yc.ship.framework.common.exception.ErrorCode;
+
+/**
+ * Member 错误码枚举类
+ * <p>
+ * member 系统,使用 1-004-000-000 段
+ */
+public interface ErrorCodeConstants {
+
+
+    ErrorCode ADSENSE_NOT_EXISTS = new ErrorCode(30_001, "广告位不存在");
+
+    ErrorCode ADSENSE_NOT_DELETE = new ErrorCode(30_002, "广告位已被使用,不能删除");
+
+    ErrorCode ADSENSE_TYPE_EXCEED = new ErrorCode(30_003, "广告位类型为单图片/单视频,绑定广告超出限制");
+
+    ErrorCode ADSENSE_CODE_EXISTS = new ErrorCode(30_004, "广告位代码已存在");
+
+    ErrorCode ADVERT_NOT_EXISTS = new ErrorCode(40_001, "广告不存在");
+
+    ErrorCode ADVERT_LOG_NOT_EXISTS = new ErrorCode(50_001, "广告日志不存在");
+
+    ErrorCode PROBLEM_NOT_EXISTS = new ErrorCode(90_001, "问题不存在");
+
+    ErrorCode PROBLEM_TYPE_NOT_EXISTS = new ErrorCode(90_002, "问题类型不存在");
+
+}

+ 72 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/adsense/AdsenseService.java

@@ -0,0 +1,72 @@
+package com.yc.ship.module.miniapplet.service.adsense;
+
+
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.module.miniapplet.controller.admin.adsense.vo.AdsensePageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.adsense.vo.AdsenseSaveReqVO;
+import com.yc.ship.module.miniapplet.controller.app.advert.vo.AppAdvertReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.adsense.AdsenseDO;
+
+import javax.validation.Valid;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 广告位管理 Service 接口
+ *
+ * @author 管理员
+ */
+public interface AdsenseService {
+
+    /**
+     * 创建广告位管理
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createAdsense(@Valid AdsenseSaveReqVO createReqVO);
+
+    /**
+     * 更新广告位管理
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateAdsense(@Valid AdsenseSaveReqVO updateReqVO);
+
+    /**
+     * 删除广告位管理
+     *
+     * @param id 编号
+     */
+    void deleteAdsense(Long id);
+
+    /**
+     * 获得广告位管理
+     *
+     * @param id 编号
+     * @return 广告位管理
+     */
+    AdsenseDO getAdsense(Long id);
+
+    /**
+     * 获得广告位管理分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 广告位管理分页
+     */
+    PageResult<AdsenseDO> getAdsensePage(AdsensePageReqVO pageReqVO);
+
+    List<AdsenseDO> getAdsenseListByStatus(Integer status);
+
+    List<AdsenseDO> getAdsenseList(Collection<Long> ids);
+
+    List<AdsenseDO> getAdsenseList(AppAdvertReqVO reqVO);
+
+    /**
+     * 获得广告位
+     *
+     * @param code 广告位编码
+     * @return 广告位管理
+     */
+    AdsenseDO getAdsenseByCode(String code);
+}

+ 122 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/adsense/AdsenseServiceImpl.java

@@ -0,0 +1,122 @@
+package com.yc.ship.module.miniapplet.service.adsense;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.module.miniapplet.controller.admin.adsense.vo.AdsensePageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.adsense.vo.AdsenseSaveReqVO;
+import com.yc.ship.module.miniapplet.controller.app.advert.vo.AppAdvertReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.adsense.AdsenseDO;
+import com.yc.ship.module.miniapplet.dal.dataobject.advert.AdvertDO;
+import com.yc.ship.module.miniapplet.dal.mysql.adsense.AdsenseMapper;
+import com.yc.ship.module.miniapplet.service.advert.AdvertService;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.yc.ship.module.miniapplet.enums.ErrorCodeConstants.*;
+
+
+/**
+ * 广告位管理 Service 实现类
+ *
+ * @author 管理员
+ */
+@Service
+@Validated
+public class AdsenseServiceImpl implements AdsenseService {
+
+    @Resource
+    private AdvertService advertService;
+
+    @Resource
+    private AdsenseMapper adsenseMapper;
+
+    @Override
+    public Long createAdsense(AdsenseSaveReqVO createReqVO) {
+        // 插入
+        AdsenseDO adsense = BeanUtils.toBean(createReqVO, AdsenseDO.class);
+        adsense.setId(IdWorker.getId(adsense));
+        AdsenseDO adsenseDO = getAdsenseByCode(createReqVO.getAdsenseCode());
+        if (adsenseDO != null) {
+            throw exception(ADSENSE_CODE_EXISTS);
+        }
+        adsenseMapper.insert(adsense);
+        // 返回
+        return adsense.getId();
+    }
+
+    @Override
+    public void updateAdsense(AdsenseSaveReqVO updateReqVO) {
+        // 校验存在
+        validateAdsenseExists(updateReqVO.getId());
+        // 更新
+        AdsenseDO updateObj = BeanUtils.toBean(updateReqVO, AdsenseDO.class);
+        AdsenseDO adsenseDO = getAdsenseByCode(updateReqVO.getAdsenseCode());
+        if (adsenseDO != null) {
+            if (!Objects.equals(adsenseDO.getId(), updateReqVO.getId())) {
+                throw exception(ADSENSE_CODE_EXISTS);
+            }
+        }
+        adsenseMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteAdsense(Long id) {
+        // 校验存在
+        validateAdsenseExists(id);
+        List<AdvertDO> advertList = advertService.getAdvertList(id);
+        if (!advertList.isEmpty()) {
+            throw exception(ADSENSE_NOT_DELETE);
+        }
+        // 删除
+        adsenseMapper.deleteById(id);
+    }
+
+    private void validateAdsenseExists(Long id) {
+        if (adsenseMapper.selectById(id) == null) {
+            throw exception(ADSENSE_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public AdsenseDO getAdsense(Long id) {
+        return adsenseMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<AdsenseDO> getAdsensePage(AdsensePageReqVO pageReqVO) {
+        return adsenseMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    public List<AdsenseDO> getAdsenseListByStatus(Integer status) {
+        return adsenseMapper.selectList(status);
+    }
+
+    @Override
+    public List<AdsenseDO> getAdsenseList(Collection<Long> ids) {
+        if (CollUtil.isEmpty(ids)) {
+            return Collections.emptyList();
+        }
+        return adsenseMapper.selectBatchIds(ids);
+    }
+
+    @Override
+    public List<AdsenseDO> getAdsenseList(AppAdvertReqVO reqVO) {
+        return adsenseMapper.getAdsenseList(reqVO.getAdsenseId(), reqVO.getAdsenseCode());
+    }
+
+    @Override
+    public AdsenseDO getAdsenseByCode(String code) {
+        return adsenseMapper.selectOne("adsense_code", code);
+    }
+
+}

+ 64 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/advert/AdvertService.java

@@ -0,0 +1,64 @@
+package com.yc.ship.module.miniapplet.service.advert;
+
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.module.miniapplet.controller.admin.advert.vo.AdvertPageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.advert.vo.AdvertSaveReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.advert.AdvertDO;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 广告管理 Service 接口
+ *
+ * @author 管理员
+ */
+public interface AdvertService {
+
+    /**
+     * 创建广告管理
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createAdvert(@Valid AdvertSaveReqVO createReqVO);
+
+    /**
+     * 更新广告管理
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateAdvert(@Valid AdvertSaveReqVO updateReqVO);
+
+    /**
+     * 删除广告管理
+     *
+     * @param id 编号
+     */
+    void deleteAdvert(Long id);
+
+    /**
+     * 获得广告管理
+     *
+     * @param id 编号
+     * @return 广告管理
+     */
+    AdvertDO getAdvert(Long id);
+
+    /**
+     * 获得广告管理分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 广告管理分页
+     */
+    PageResult<AdvertDO> getAdvertPage(AdvertPageReqVO pageReqVO);
+
+    /**
+     * 根据广告位查广告
+     *
+     * @param adsenseId
+     * @return
+     */
+    List<AdvertDO> getAdvertList(Long adsenseId);
+
+}

+ 91 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/advert/AdvertServiceImpl.java

@@ -0,0 +1,91 @@
+package com.yc.ship.module.miniapplet.service.advert;
+
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.module.miniapplet.controller.admin.advert.vo.AdvertPageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.advert.vo.AdvertSaveReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.advert.AdvertDO;
+import com.yc.ship.module.miniapplet.dal.mysql.advert.AdvertMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.util.List;
+
+import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.yc.ship.module.miniapplet.enums.ErrorCodeConstants.ADVERT_NOT_EXISTS;
+
+
+/**
+ * 广告管理 Service 实现类
+ *
+ * @author 管理员
+ */
+@Service
+@Validated
+public class AdvertServiceImpl implements AdvertService {
+
+    @Resource
+    private AdvertMapper advertMapper;
+
+    @Override
+    public Long createAdvert(AdvertSaveReqVO createReqVO) {
+        if (createReqVO.getValidType() == 1) {
+            LocalDateTime endDate = createReqVO.getEndDate();
+            endDate = endDate.withHour(23).withMinute(59).withSecond(59);
+            createReqVO.setEndDate(endDate);
+        }
+        // 插入
+        AdvertDO advert = BeanUtils.toBean(createReqVO, AdvertDO.class);
+        advert.setId(IdWorker.getId(advert));
+        advertMapper.insert(advert);
+        // 返回
+        return advert.getId();
+    }
+
+    @Override
+    public void updateAdvert(AdvertSaveReqVO updateReqVO) {
+        // 校验存在
+        validateAdvertExists(updateReqVO.getId());
+        if (updateReqVO.getValidType() == 1) {
+            LocalDateTime endDate = updateReqVO.getEndDate();
+            endDate = endDate.withHour(23).withMinute(59).withSecond(59);
+            updateReqVO.setEndDate(endDate);
+        }
+        // 更新
+        AdvertDO updateObj = BeanUtils.toBean(updateReqVO, AdvertDO.class);
+        advertMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteAdvert(Long id) {
+        // 校验存在
+        validateAdvertExists(id);
+        // 删除
+        advertMapper.deleteById(id);
+    }
+
+    private void validateAdvertExists(Long id) {
+        if (advertMapper.selectById(id) == null) {
+            throw exception(ADVERT_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public AdvertDO getAdvert(Long id) {
+        return advertMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<AdvertDO> getAdvertPage(AdvertPageReqVO pageReqVO) {
+        return advertMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    public List<AdvertDO> getAdvertList(Long adsenseId) {
+        return advertMapper.selectAdvertList(adsenseId);
+    }
+
+}

+ 55 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/advertlog/AdvertLogService.java

@@ -0,0 +1,55 @@
+package com.yc.ship.module.miniapplet.service.advertlog;
+
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.module.miniapplet.controller.admin.advertlog.vo.AdvertLogPageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.advertlog.vo.AdvertLogSaveReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.advertlog.AdvertLogDO;
+
+import javax.validation.Valid;
+
+/**
+ * 广告操作日志管理 Service 接口
+ *
+ * @author 管理员
+ */
+public interface AdvertLogService {
+
+    /**
+     * 创建广告操作日志管理
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createAdvertLog(@Valid AdvertLogSaveReqVO createReqVO);
+
+    /**
+     * 更新广告操作日志管理
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateAdvertLog(@Valid AdvertLogSaveReqVO updateReqVO);
+
+    /**
+     * 删除广告操作日志管理
+     *
+     * @param id 编号
+     */
+    void deleteAdvertLog(Long id);
+
+    /**
+     * 获得广告操作日志管理
+     *
+     * @param id 编号
+     * @return 广告操作日志管理
+     */
+    AdvertLogDO getAdvertLog(Long id);
+
+    /**
+     * 获得广告操作日志管理分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 广告操作日志管理分页
+     */
+    PageResult<AdvertLogDO> getAdvertLogPage(AdvertLogPageReqVO pageReqVO);
+
+}

+ 72 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/advertlog/AdvertLogServiceImpl.java

@@ -0,0 +1,72 @@
+package com.yc.ship.module.miniapplet.service.advertlog;
+
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.module.miniapplet.controller.admin.advertlog.vo.AdvertLogPageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.advertlog.vo.AdvertLogSaveReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.advertlog.AdvertLogDO;
+import com.yc.ship.module.miniapplet.dal.mysql.advertlog.AdvertLogMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+
+import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.yc.ship.module.miniapplet.enums.ErrorCodeConstants.ADVERT_LOG_NOT_EXISTS;
+
+
+/**
+ * 广告操作日志管理 Service 实现类
+ *
+ * @author 管理员
+ */
+@Service
+@Validated
+public class AdvertLogServiceImpl implements AdvertLogService {
+
+    @Resource
+    private AdvertLogMapper advertLogMapper;
+
+    @Override
+    public Long createAdvertLog(AdvertLogSaveReqVO createReqVO) {
+        // 插入
+        AdvertLogDO advertLog = BeanUtils.toBean(createReqVO, AdvertLogDO.class);
+        advertLogMapper.insert(advertLog);
+        // 返回
+        return advertLog.getId();
+    }
+
+    @Override
+    public void updateAdvertLog(AdvertLogSaveReqVO updateReqVO) {
+        // 校验存在
+        validateAdvertLogExists(updateReqVO.getId());
+        // 更新
+        AdvertLogDO updateObj = BeanUtils.toBean(updateReqVO, AdvertLogDO.class);
+        advertLogMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteAdvertLog(Long id) {
+        // 校验存在
+        validateAdvertLogExists(id);
+        // 删除
+        advertLogMapper.deleteById(id);
+    }
+
+    private void validateAdvertLogExists(Long id) {
+        if (advertLogMapper.selectById(id) == null) {
+            throw exception(ADVERT_LOG_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public AdvertLogDO getAdvertLog(Long id) {
+        return advertLogMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<AdvertLogDO> getAdvertLogPage(AdvertLogPageReqVO pageReqVO) {
+        return advertLogMapper.selectPage(pageReqVO);
+    }
+
+}

+ 60 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/problem/ProblemService.java

@@ -0,0 +1,60 @@
+package com.yc.ship.module.miniapplet.service.problem;
+
+
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.module.miniapplet.controller.admin.problem.vo.ProblemPageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.problem.vo.ProblemSaveReqVO;
+import com.yc.ship.module.miniapplet.controller.app.problem.vo.AppProblemReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.problem.ProblemDO;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 问题管理 Service 接口
+ *
+ * @author 管理员
+ */
+public interface ProblemService {
+
+    /**
+     * 创建问题管理
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createProblem(@Valid ProblemSaveReqVO createReqVO);
+
+    /**
+     * 更新问题管理
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateProblem(@Valid ProblemSaveReqVO updateReqVO);
+
+    /**
+     * 删除问题管理
+     *
+     * @param id 编号
+     */
+    void deleteProblem(Long id);
+
+    /**
+     * 获得问题管理
+     *
+     * @param id 编号
+     * @return 问题管理
+     */
+    ProblemDO getProblem(Long id);
+
+    /**
+     * 获得问题管理分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 问题管理分页
+     */
+    PageResult<ProblemDO> getProblemPage(ProblemPageReqVO pageReqVO);
+
+    List<ProblemDO> getProblemList(AppProblemReqVO reqVO);
+
+}

+ 88 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/problem/ProblemServiceImpl.java

@@ -0,0 +1,88 @@
+package com.yc.ship.module.miniapplet.service.problem;
+
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.module.miniapplet.controller.admin.problem.vo.ProblemPageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.problem.vo.ProblemSaveReqVO;
+import com.yc.ship.module.miniapplet.controller.app.problem.vo.AppProblemReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.problem.ProblemDO;
+import com.yc.ship.module.miniapplet.dal.mysql.problem.ProblemMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.util.List;
+
+import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.yc.ship.module.miniapplet.enums.ErrorCodeConstants.PROBLEM_NOT_EXISTS;
+
+
+/**
+ * 问题管理 Service 实现类
+ *
+ * @author 管理员
+ */
+@Service
+@Validated
+public class ProblemServiceImpl implements ProblemService {
+
+    @Resource
+    private ProblemMapper problemMapper;
+
+    @Override
+    public Long createProblem(ProblemSaveReqVO createReqVO) {
+        // 插入
+        ProblemDO problem = BeanUtils.toBean(createReqVO, ProblemDO.class);
+        problem.setId(IdWorker.getId(problem));
+        if (problem.getReleaseStatus() == 1) {
+            problem.setReleaseTime(LocalDateTime.now());
+        }
+        problemMapper.insert(problem);
+        // 返回
+        return problem.getId();
+    }
+
+    @Override
+    public void updateProblem(ProblemSaveReqVO updateReqVO) {
+        // 校验存在
+        validateProblemExists(updateReqVO.getId());
+        // 更新
+        ProblemDO updateObj = BeanUtils.toBean(updateReqVO, ProblemDO.class);
+        if (updateObj.getReleaseStatus() == 1) {
+            updateObj.setReleaseTime(LocalDateTime.now());
+        }
+        problemMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteProblem(Long id) {
+        // 校验存在
+        validateProblemExists(id);
+        // 删除
+        problemMapper.deleteById(id);
+    }
+
+    private void validateProblemExists(Long id) {
+        if (problemMapper.selectById(id) == null) {
+            throw exception(PROBLEM_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public ProblemDO getProblem(Long id) {
+        return problemMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<ProblemDO> getProblemPage(ProblemPageReqVO pageReqVO) {
+        return problemMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    public List<ProblemDO> getProblemList(AppProblemReqVO reqVO) {
+        return problemMapper.getProblemList(reqVO);
+    }
+
+}

+ 83 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/problemtype/ProblemTypeService.java

@@ -0,0 +1,83 @@
+package com.yc.ship.module.miniapplet.service.problemtype;
+
+
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.module.miniapplet.controller.admin.problemtype.vo.ProblemTypePageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.problemtype.vo.ProblemTypeSaveReqVO;
+import com.yc.ship.module.miniapplet.controller.app.problem.vo.AppProblemReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.problemtype.ProblemTypeDO;
+
+import javax.validation.Valid;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 问题类型 Service 接口
+ *
+ * @author 管理员
+ */
+public interface ProblemTypeService {
+
+    /**
+     * 创建问题类型
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createProblemType(@Valid ProblemTypeSaveReqVO createReqVO);
+
+    /**
+     * 更新问题类型
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateProblemType(@Valid ProblemTypeSaveReqVO updateReqVO);
+
+    /**
+     * 删除问题类型
+     *
+     * @param id 编号
+     */
+    void deleteProblemType(Long id);
+
+    /**
+     * 获得问题类型
+     *
+     * @param id 编号
+     * @return 问题类型
+     */
+    ProblemTypeDO getProblemType(Long id);
+
+    /**
+     * 获得问题类型分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 问题类型分页
+     */
+    PageResult<ProblemTypeDO> getProblemTypePage(ProblemTypePageReqVO pageReqVO);
+
+    /**
+     * 查询问题类型
+     *
+     * @param ids
+     * @return
+     */
+    List<ProblemTypeDO> getProblemTypeList(Collection<Long> ids);
+
+    /**
+     * 查询问题类型
+     *
+     * @param
+     * @return
+     */
+    List<ProblemTypeDO> getProblemTypeListByStatus(Integer systemType,Integer status);
+
+    /**
+     * 查询问题类型
+     *
+     * @param
+     * @return
+     */
+    List<ProblemTypeDO> getProblemTypeListByApp(AppProblemReqVO reqVO);
+
+}

+ 97 - 0
ship-module-miniapplet/src/main/java/com/yc/ship/module/miniapplet/service/problemtype/ProblemTypeServiceImpl.java

@@ -0,0 +1,97 @@
+package com.yc.ship.module.miniapplet.service.problemtype;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.module.miniapplet.controller.admin.problemtype.vo.ProblemTypePageReqVO;
+import com.yc.ship.module.miniapplet.controller.admin.problemtype.vo.ProblemTypeSaveReqVO;
+import com.yc.ship.module.miniapplet.controller.app.problem.vo.AppProblemReqVO;
+import com.yc.ship.module.miniapplet.dal.dataobject.problemtype.ProblemTypeDO;
+import com.yc.ship.module.miniapplet.dal.mysql.problemtype.ProblemTypeMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.yc.ship.module.miniapplet.enums.ErrorCodeConstants.PROBLEM_TYPE_NOT_EXISTS;
+
+
+/**
+ * 问题类型 Service 实现类
+ *
+ * @author 管理员
+ */
+@Service
+@Validated
+public class ProblemTypeServiceImpl implements ProblemTypeService {
+
+    @Resource
+    private ProblemTypeMapper problemTypeMapper;
+
+    @Override
+    public Long createProblemType(ProblemTypeSaveReqVO createReqVO) {
+        // 插入
+        ProblemTypeDO problemType = BeanUtils.toBean(createReqVO, ProblemTypeDO.class);
+        problemType.setId(IdWorker.getId(problemType));
+        problemTypeMapper.insert(problemType);
+        // 返回
+        return problemType.getId();
+    }
+
+    @Override
+    public void updateProblemType(ProblemTypeSaveReqVO updateReqVO) {
+        // 校验存在
+        validateProblemTypeExists(updateReqVO.getId());
+        // 更新
+        ProblemTypeDO updateObj = BeanUtils.toBean(updateReqVO, ProblemTypeDO.class);
+        problemTypeMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteProblemType(Long id) {
+        // 校验存在
+        validateProblemTypeExists(id);
+        // 删除
+        problemTypeMapper.deleteById(id);
+    }
+
+    private void validateProblemTypeExists(Long id) {
+        if (problemTypeMapper.selectById(id) == null) {
+            throw exception(PROBLEM_TYPE_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public ProblemTypeDO getProblemType(Long id) {
+        return problemTypeMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<ProblemTypeDO> getProblemTypePage(ProblemTypePageReqVO pageReqVO) {
+        return problemTypeMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    public List<ProblemTypeDO> getProblemTypeList(Collection<Long> ids) {
+        if (CollUtil.isEmpty(ids)) {
+            return Collections.emptyList();
+        }
+        return problemTypeMapper.selectBatchIds(ids);
+    }
+
+    @Override
+    public List<ProblemTypeDO> getProblemTypeListByStatus(Integer systemType,Integer status) {
+        return problemTypeMapper.getProblemTypeListByStatus(systemType,status);
+    }
+
+    @Override
+    public List<ProblemTypeDO> getProblemTypeListByApp(AppProblemReqVO reqVO) {
+        return problemTypeMapper.getProblemTypeListByApp(reqVO);
+    }
+
+}

+ 5 - 0
ship-server-web/pom.xml

@@ -73,6 +73,11 @@
             <artifactId>ship-module-marketing-biz</artifactId>
             <version>${revision}</version>
         </dependency>
+        <dependency>
+            <groupId>com.yc.ship</groupId>
+            <artifactId>ship-module-miniapplet</artifactId>
+            <version>${revision}</version>
+        </dependency>
 
         <!-- 业务组件 -->
         <dependency>