diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-api/src/main/java/cn/yskj/linghe/module/acdr/enums/ErrorCodeConstants.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-api/src/main/java/cn/yskj/linghe/module/acdr/enums/ErrorCodeConstants.java index d2d958d8..e63a8b91 100644 --- a/acdr-admin/yskj-module-acdr/yskj-module-acdr-api/src/main/java/cn/yskj/linghe/module/acdr/enums/ErrorCodeConstants.java +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-api/src/main/java/cn/yskj/linghe/module/acdr/enums/ErrorCodeConstants.java @@ -57,4 +57,8 @@ public interface ErrorCodeConstants { ErrorCode PET_EXPERT_CERTIFICATION_NOT_EXISTS = new ErrorCode(1_008_009_001, "宠托师审核不存在"); + ErrorCode NOTIFICATIONS_NOT_EXISTS = new ErrorCode(1_008_009_002, "通知不存在"); + + ErrorCode AD_NOT_EXISTS = new ErrorCode(1_008_009_003, "推广不存在"); + } diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/ad/AdController.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/ad/AdController.java new file mode 100644 index 00000000..f454e11d --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/ad/AdController.java @@ -0,0 +1,95 @@ +package cn.yskj.linghe.module.acdr.controller.admin.ad; + +import org.springframework.web.bind.annotation.*; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import jakarta.validation.constraints.*; +import jakarta.validation.*; +import jakarta.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.yskj.linghe.framework.common.pojo.PageParam; +import cn.yskj.linghe.framework.common.pojo.PageResult; +import cn.yskj.linghe.framework.common.pojo.CommonResult; +import cn.yskj.linghe.framework.common.util.object.BeanUtils; +import static cn.yskj.linghe.framework.common.pojo.CommonResult.success; + +import cn.yskj.linghe.framework.excel.core.util.ExcelUtils; + +import cn.yskj.linghe.framework.apilog.core.annotation.ApiAccessLog; +import static cn.yskj.linghe.framework.apilog.core.enums.OperateTypeEnum.*; + +import cn.yskj.linghe.module.acdr.controller.admin.ad.vo.*; +import cn.yskj.linghe.module.acdr.dal.dataobject.ad.AdDO; +import cn.yskj.linghe.module.acdr.service.ad.AdService; + +@Tag(name = "管理后台 - 推广") +@RestController +@RequestMapping("/acdr/ad") +@Validated +public class AdController { + + @Resource + private AdService adService; + + @PostMapping("/create") + @Operation(summary = "创建推广") + @PreAuthorize("@ss.hasPermission('acdr:ad:create')") + public CommonResult createAd(@Valid @RequestBody AdSaveReqVO createReqVO) { + return success(adService.createAd(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新推广") + @PreAuthorize("@ss.hasPermission('acdr:ad:update')") + public CommonResult updateAd(@Valid @RequestBody AdSaveReqVO updateReqVO) { + adService.updateAd(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除推广") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('acdr:ad:delete')") + public CommonResult deleteAd(@RequestParam("id") Long id) { + adService.deleteAd(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得推广") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('acdr:ad:query')") + public CommonResult getAd(@RequestParam("id") Long id) { + AdDO ad = adService.getAd(id); + return success(BeanUtils.toBean(ad, AdRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得推广分页") + @PreAuthorize("@ss.hasPermission('acdr:ad:query')") + public CommonResult> getAdPage(@Valid AdPageReqVO pageReqVO) { + PageResult pageResult = adService.getAdPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, AdRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出推广 Excel") + @PreAuthorize("@ss.hasPermission('acdr:ad:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportAdExcel(@Valid AdPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = adService.getAdPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "推广.xls", "数据", AdRespVO.class, + BeanUtils.toBean(list, AdRespVO.class)); + } + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/ad/vo/AdPageReqVO.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/ad/vo/AdPageReqVO.java new file mode 100644 index 00000000..053b3d85 --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/ad/vo/AdPageReqVO.java @@ -0,0 +1,34 @@ +package cn.yskj.linghe.module.acdr.controller.admin.ad.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.yskj.linghe.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.yskj.linghe.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 AdPageReqVO extends PageParam { + + @Schema(description = "资源类型", example = "2") + private Integer type; + + @Schema(description = "图片路径", example = "https://www.iocoder.cn") + private String imageUrl; + + @Schema(description = "推广语") + private String content; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + + @Schema(description = "资源路径", example = "https://www.iocoder.cn") + private String pagesUrl; + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/ad/vo/AdRespVO.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/ad/vo/AdRespVO.java new file mode 100644 index 00000000..dcc38024 --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/ad/vo/AdRespVO.java @@ -0,0 +1,42 @@ +package cn.yskj.linghe.module.acdr.controller.admin.ad.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; +import cn.yskj.linghe.framework.excel.core.annotations.DictFormat; +import cn.yskj.linghe.framework.excel.core.convert.DictConvert; + +@Schema(description = "管理后台 - 推广 Response VO") +@Data +@ExcelIgnoreUnannotated +public class AdRespVO { + + @Schema(description = "推广ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "18022") + @ExcelProperty("推广ID") + private Long id; + + @Schema(description = "资源类型", example = "2") + @ExcelProperty(value = "资源类型", converter = DictConvert.class) + @DictFormat("promotion_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private Integer type; + + @Schema(description = "图片路径", example = "https://www.iocoder.cn") + @ExcelProperty("图片路径") + private String imageUrl; + + @Schema(description = "推广语") + @ExcelProperty("推广语") + private String content; + + @Schema(description = "创建时间") + @ExcelProperty("创建时间") + private LocalDateTime createTime; + + @Schema(description = "资源路径", example = "https://www.iocoder.cn") + @ExcelProperty("资源路径") + private String pagesUrl; + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/ad/vo/AdSaveReqVO.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/ad/vo/AdSaveReqVO.java new file mode 100644 index 00000000..1afed959 --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/ad/vo/AdSaveReqVO.java @@ -0,0 +1,27 @@ +package cn.yskj.linghe.module.acdr.controller.admin.ad.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import jakarta.validation.constraints.*; + +@Schema(description = "管理后台 - 推广新增/修改 Request VO") +@Data +public class AdSaveReqVO { + + @Schema(description = "推广ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "18022") + private Long id; + + @Schema(description = "资源类型", example = "2") + private Integer type; + + @Schema(description = "图片路径", example = "https://www.iocoder.cn") + private String imageUrl; + + @Schema(description = "推广语") + private String content; + + @Schema(description = "资源路径", example = "https://www.iocoder.cn") + private String pagesUrl; + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/notifications/NotificationsController.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/notifications/NotificationsController.java new file mode 100644 index 00000000..aae322d8 --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/notifications/NotificationsController.java @@ -0,0 +1,95 @@ +package cn.yskj.linghe.module.acdr.controller.admin.notifications; + +import org.springframework.web.bind.annotation.*; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import jakarta.validation.constraints.*; +import jakarta.validation.*; +import jakarta.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.yskj.linghe.framework.common.pojo.PageParam; +import cn.yskj.linghe.framework.common.pojo.PageResult; +import cn.yskj.linghe.framework.common.pojo.CommonResult; +import cn.yskj.linghe.framework.common.util.object.BeanUtils; +import static cn.yskj.linghe.framework.common.pojo.CommonResult.success; + +import cn.yskj.linghe.framework.excel.core.util.ExcelUtils; + +import cn.yskj.linghe.framework.apilog.core.annotation.ApiAccessLog; +import static cn.yskj.linghe.framework.apilog.core.enums.OperateTypeEnum.*; + +import cn.yskj.linghe.module.acdr.controller.admin.notifications.vo.*; +import cn.yskj.linghe.module.acdr.dal.dataobject.notifications.NotificationsDO; +import cn.yskj.linghe.module.acdr.service.notifications.NotificationsService; + +@Tag(name = "管理后台 - 通知") +@RestController +@RequestMapping("/acdr/notifications") +@Validated +public class NotificationsController { + + @Resource + private NotificationsService notificationsService; + + @PostMapping("/create") + @Operation(summary = "创建通知") + @PreAuthorize("@ss.hasPermission('acdr:notifications:create')") + public CommonResult createNotifications(@Valid @RequestBody NotificationsSaveReqVO createReqVO) { + return success(notificationsService.createNotifications(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新通知") + @PreAuthorize("@ss.hasPermission('acdr:notifications:update')") + public CommonResult updateNotifications(@Valid @RequestBody NotificationsSaveReqVO updateReqVO) { + notificationsService.updateNotifications(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除通知") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('acdr:notifications:delete')") + public CommonResult deleteNotifications(@RequestParam("id") Long id) { + notificationsService.deleteNotifications(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得通知") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('acdr:notifications:query')") + public CommonResult getNotifications(@RequestParam("id") Long id) { + NotificationsDO notifications = notificationsService.getNotifications(id); + return success(BeanUtils.toBean(notifications, NotificationsRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得通知分页") + @PreAuthorize("@ss.hasPermission('acdr:notifications:query')") + public CommonResult> getNotificationsPage(@Valid NotificationsPageReqVO pageReqVO) { + PageResult pageResult = notificationsService.getNotificationsPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, NotificationsRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出通知 Excel") + @PreAuthorize("@ss.hasPermission('acdr:notifications:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportNotificationsExcel(@Valid NotificationsPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = notificationsService.getNotificationsPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "通知.xls", "数据", NotificationsRespVO.class, + BeanUtils.toBean(list, NotificationsRespVO.class)); + } + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/notifications/vo/NotificationsPageReqVO.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/notifications/vo/NotificationsPageReqVO.java new file mode 100644 index 00000000..9041871e --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/notifications/vo/NotificationsPageReqVO.java @@ -0,0 +1,43 @@ +package cn.yskj.linghe.module.acdr.controller.admin.notifications.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.yskj.linghe.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.yskj.linghe.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 NotificationsPageReqVO extends PageParam { + + @Schema(description = "内容") + private String content; + + @Schema(description = "需要跳转的页面", example = "https://www.iocoder.cn") + private String url; + + @Schema(description = "消息创建状态", example = "1") + private Integer status; + + @Schema(description = "消息类型", example = "1") + private String type; + + @Schema(description = "消息创建者", example = "1848") + private Long userId; + + @Schema(description = "消息接受范围") + private String receiverScope; + + @Schema(description = "标题") + private String title; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/notifications/vo/NotificationsRespVO.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/notifications/vo/NotificationsRespVO.java new file mode 100644 index 00000000..142f88aa --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/notifications/vo/NotificationsRespVO.java @@ -0,0 +1,51 @@ +package cn.yskj.linghe.module.acdr.controller.admin.notifications.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 通知 Response VO") +@Data +@ExcelIgnoreUnannotated +public class NotificationsRespVO { + + @Schema(description = "消息主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "15467") + @ExcelProperty("消息主键") + private Long id; + + @Schema(description = "内容") + @ExcelProperty("内容") + private String content; + + @Schema(description = "需要跳转的页面", example = "https://www.iocoder.cn") + @ExcelProperty("需要跳转的页面") + private String url; + + @Schema(description = "消息创建状态", example = "1") + @ExcelProperty("消息创建状态") + private Integer status; + + @Schema(description = "消息类型", example = "1") + @ExcelProperty("消息类型") + private String type; + + @Schema(description = "消息创建者", example = "1848") + @ExcelProperty("消息创建者") + private Long userId; + + @Schema(description = "消息接受范围") + @ExcelProperty("消息接受范围") + private String receiverScope; + + @Schema(description = "标题") + @ExcelProperty("标题") + private String title; + + @Schema(description = "创建时间") + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/notifications/vo/NotificationsSaveReqVO.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/notifications/vo/NotificationsSaveReqVO.java new file mode 100644 index 00000000..02cba603 --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/controller/admin/notifications/vo/NotificationsSaveReqVO.java @@ -0,0 +1,36 @@ +package cn.yskj.linghe.module.acdr.controller.admin.notifications.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import jakarta.validation.constraints.*; + +@Schema(description = "管理后台 - 通知新增/修改 Request VO") +@Data +public class NotificationsSaveReqVO { + + @Schema(description = "消息主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "15467") + private Long id; + + @Schema(description = "内容") + private String content; + + @Schema(description = "需要跳转的页面", example = "https://www.iocoder.cn") + private String url; + + @Schema(description = "消息创建状态", example = "1") + private Integer status; + + @Schema(description = "消息类型", example = "1") + private String type; + + @Schema(description = "消息创建者", example = "1848") + private Long userId; + + @Schema(description = "消息接受范围") + private String receiverScope; + + @Schema(description = "标题") + private String title; + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/dal/dataobject/ad/AdDO.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/dal/dataobject/ad/AdDO.java new file mode 100644 index 00000000..7275d3df --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/dal/dataobject/ad/AdDO.java @@ -0,0 +1,49 @@ +package cn.yskj.linghe.module.acdr.dal.dataobject.ad; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.yskj.linghe.framework.mybatis.core.dataobject.BaseDO; + +/** + * 推广 DO + * + * @author 芋道源码 + */ +@TableName("acdr_ad") +@KeySequence("acdr_ad_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AdDO extends BaseDO { + + /** + * 推广ID + */ + @TableId + private Long id; + /** + * 资源类型 + * + * 枚举 {@link TODO promotion_type 对应的类} + */ + private Integer type; + /** + * 图片路径 + */ + private String imageUrl; + /** + * 推广语 + */ + private String content; + /** + * 资源路径 + */ + private String pagesUrl; + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/dal/dataobject/notifications/NotificationsDO.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/dal/dataobject/notifications/NotificationsDO.java new file mode 100644 index 00000000..fff54f39 --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/dal/dataobject/notifications/NotificationsDO.java @@ -0,0 +1,59 @@ +package cn.yskj.linghe.module.acdr.dal.dataobject.notifications; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.yskj.linghe.framework.mybatis.core.dataobject.BaseDO; + +/** + * 通知 DO + * + * @author 林河 + */ +@TableName("acdr_notifications") +@KeySequence("acdr_notifications_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class NotificationsDO extends BaseDO { + + /** + * 消息主键 + */ + @TableId + private Long id; + /** + * 内容 + */ + private String content; + /** + * 需要跳转的页面 + */ + private String url; + /** + * 消息创建状态 + */ + private Integer status; + /** + * 消息类型 + */ + private String type; + /** + * 消息创建者 + */ + private Long userId; + /** + * 消息接受范围 + */ + private String receiverScope; + /** + * 标题 + */ + private String title; + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/dal/mysql/ad/AdMapper.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/dal/mysql/ad/AdMapper.java new file mode 100644 index 00000000..bc733134 --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/dal/mysql/ad/AdMapper.java @@ -0,0 +1,30 @@ +package cn.yskj.linghe.module.acdr.dal.mysql.ad; + +import java.util.*; + +import cn.yskj.linghe.framework.common.pojo.PageResult; +import cn.yskj.linghe.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.yskj.linghe.framework.mybatis.core.mapper.BaseMapperX; +import cn.yskj.linghe.module.acdr.dal.dataobject.ad.AdDO; +import org.apache.ibatis.annotations.Mapper; +import cn.yskj.linghe.module.acdr.controller.admin.ad.vo.*; + +/** + * 推广 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface AdMapper extends BaseMapperX { + + default PageResult selectPage(AdPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(AdDO::getType, reqVO.getType()) + .eqIfPresent(AdDO::getImageUrl, reqVO.getImageUrl()) + .eqIfPresent(AdDO::getContent, reqVO.getContent()) + .betweenIfPresent(AdDO::getCreateTime, reqVO.getCreateTime()) + .eqIfPresent(AdDO::getPagesUrl, reqVO.getPagesUrl()) + .orderByDesc(AdDO::getId)); + } + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/dal/mysql/notifications/NotificationsMapper.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/dal/mysql/notifications/NotificationsMapper.java new file mode 100644 index 00000000..dd22b5ac --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/dal/mysql/notifications/NotificationsMapper.java @@ -0,0 +1,33 @@ +package cn.yskj.linghe.module.acdr.dal.mysql.notifications; + +import java.util.*; + +import cn.yskj.linghe.framework.common.pojo.PageResult; +import cn.yskj.linghe.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.yskj.linghe.framework.mybatis.core.mapper.BaseMapperX; +import cn.yskj.linghe.module.acdr.dal.dataobject.notifications.NotificationsDO; +import org.apache.ibatis.annotations.Mapper; +import cn.yskj.linghe.module.acdr.controller.admin.notifications.vo.*; + +/** + * 通知 Mapper + * + * @author 林河 + */ +@Mapper +public interface NotificationsMapper extends BaseMapperX { + + default PageResult selectPage(NotificationsPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(NotificationsDO::getContent, reqVO.getContent()) + .eqIfPresent(NotificationsDO::getUrl, reqVO.getUrl()) + .eqIfPresent(NotificationsDO::getStatus, reqVO.getStatus()) + .eqIfPresent(NotificationsDO::getType, reqVO.getType()) + .eqIfPresent(NotificationsDO::getUserId, reqVO.getUserId()) + .eqIfPresent(NotificationsDO::getReceiverScope, reqVO.getReceiverScope()) + .eqIfPresent(NotificationsDO::getTitle, reqVO.getTitle()) + .betweenIfPresent(NotificationsDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(NotificationsDO::getId)); + } + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/service/ad/AdService.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/service/ad/AdService.java new file mode 100644 index 00000000..e094ea9e --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/service/ad/AdService.java @@ -0,0 +1,55 @@ +package cn.yskj.linghe.module.acdr.service.ad; + +import java.util.*; +import jakarta.validation.*; +import cn.yskj.linghe.module.acdr.controller.admin.ad.vo.*; +import cn.yskj.linghe.module.acdr.dal.dataobject.ad.AdDO; +import cn.yskj.linghe.framework.common.pojo.PageResult; +import cn.yskj.linghe.framework.common.pojo.PageParam; + +/** + * 推广 Service 接口 + * + * @author 芋道源码 + */ +public interface AdService { + + /** + * 创建推广 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createAd(@Valid AdSaveReqVO createReqVO); + + /** + * 更新推广 + * + * @param updateReqVO 更新信息 + */ + void updateAd(@Valid AdSaveReqVO updateReqVO); + + /** + * 删除推广 + * + * @param id 编号 + */ + void deleteAd(Long id); + + /** + * 获得推广 + * + * @param id 编号 + * @return 推广 + */ + AdDO getAd(Long id); + + /** + * 获得推广分页 + * + * @param pageReqVO 分页查询 + * @return 推广分页 + */ + PageResult getAdPage(AdPageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/service/ad/AdServiceImpl.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/service/ad/AdServiceImpl.java new file mode 100644 index 00000000..2e5e3766 --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/service/ad/AdServiceImpl.java @@ -0,0 +1,74 @@ +package cn.yskj.linghe.module.acdr.service.ad; + +import org.springframework.stereotype.Service; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.yskj.linghe.module.acdr.controller.admin.ad.vo.*; +import cn.yskj.linghe.module.acdr.dal.dataobject.ad.AdDO; +import cn.yskj.linghe.framework.common.pojo.PageResult; +import cn.yskj.linghe.framework.common.pojo.PageParam; +import cn.yskj.linghe.framework.common.util.object.BeanUtils; + +import cn.yskj.linghe.module.acdr.dal.mysql.ad.AdMapper; + +import static cn.yskj.linghe.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.yskj.linghe.module.acdr.enums.ErrorCodeConstants.*; + +/** + * 推广 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class AdServiceImpl implements AdService { + + @Resource + private AdMapper adMapper; + + @Override + public Long createAd(AdSaveReqVO createReqVO) { + // 插入 + AdDO ad = BeanUtils.toBean(createReqVO, AdDO.class); + adMapper.insert(ad); + // 返回 + return ad.getId(); + } + + @Override + public void updateAd(AdSaveReqVO updateReqVO) { + // 校验存在 + validateAdExists(updateReqVO.getId()); + // 更新 + AdDO updateObj = BeanUtils.toBean(updateReqVO, AdDO.class); + adMapper.updateById(updateObj); + } + + @Override + public void deleteAd(Long id) { + // 校验存在 + validateAdExists(id); + // 删除 + adMapper.deleteById(id); + } + + private void validateAdExists(Long id) { + if (adMapper.selectById(id) == null) { + throw exception(AD_NOT_EXISTS); + } + } + + @Override + public AdDO getAd(Long id) { + return adMapper.selectById(id); + } + + @Override + public PageResult getAdPage(AdPageReqVO pageReqVO) { + return adMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/service/notifications/NotificationsService.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/service/notifications/NotificationsService.java new file mode 100644 index 00000000..6ebd4c76 --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/service/notifications/NotificationsService.java @@ -0,0 +1,55 @@ +package cn.yskj.linghe.module.acdr.service.notifications; + +import java.util.*; +import jakarta.validation.*; +import cn.yskj.linghe.module.acdr.controller.admin.notifications.vo.*; +import cn.yskj.linghe.module.acdr.dal.dataobject.notifications.NotificationsDO; +import cn.yskj.linghe.framework.common.pojo.PageResult; +import cn.yskj.linghe.framework.common.pojo.PageParam; + +/** + * 通知 Service 接口 + * + * @author 林河 + */ +public interface NotificationsService { + + /** + * 创建通知 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createNotifications(@Valid NotificationsSaveReqVO createReqVO); + + /** + * 更新通知 + * + * @param updateReqVO 更新信息 + */ + void updateNotifications(@Valid NotificationsSaveReqVO updateReqVO); + + /** + * 删除通知 + * + * @param id 编号 + */ + void deleteNotifications(Long id); + + /** + * 获得通知 + * + * @param id 编号 + * @return 通知 + */ + NotificationsDO getNotifications(Long id); + + /** + * 获得通知分页 + * + * @param pageReqVO 分页查询 + * @return 通知分页 + */ + PageResult getNotificationsPage(NotificationsPageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/service/notifications/NotificationsServiceImpl.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/service/notifications/NotificationsServiceImpl.java new file mode 100644 index 00000000..76f64e9c --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/java/cn/yskj/linghe/module/acdr/service/notifications/NotificationsServiceImpl.java @@ -0,0 +1,74 @@ +package cn.yskj.linghe.module.acdr.service.notifications; + +import org.springframework.stereotype.Service; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.yskj.linghe.module.acdr.controller.admin.notifications.vo.*; +import cn.yskj.linghe.module.acdr.dal.dataobject.notifications.NotificationsDO; +import cn.yskj.linghe.framework.common.pojo.PageResult; +import cn.yskj.linghe.framework.common.pojo.PageParam; +import cn.yskj.linghe.framework.common.util.object.BeanUtils; + +import cn.yskj.linghe.module.acdr.dal.mysql.notifications.NotificationsMapper; + +import static cn.yskj.linghe.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.yskj.linghe.module.acdr.enums.ErrorCodeConstants.*; + +/** + * 通知 Service 实现类 + * + * @author 林河 + */ +@Service +@Validated +public class NotificationsServiceImpl implements NotificationsService { + + @Resource + private NotificationsMapper notificationsMapper; + + @Override + public Long createNotifications(NotificationsSaveReqVO createReqVO) { + // 插入 + NotificationsDO notifications = BeanUtils.toBean(createReqVO, NotificationsDO.class); + notificationsMapper.insert(notifications); + // 返回 + return notifications.getId(); + } + + @Override + public void updateNotifications(NotificationsSaveReqVO updateReqVO) { + // 校验存在 + validateNotificationsExists(updateReqVO.getId()); + // 更新 + NotificationsDO updateObj = BeanUtils.toBean(updateReqVO, NotificationsDO.class); + notificationsMapper.updateById(updateObj); + } + + @Override + public void deleteNotifications(Long id) { + // 校验存在 + validateNotificationsExists(id); + // 删除 + notificationsMapper.deleteById(id); + } + + private void validateNotificationsExists(Long id) { + if (notificationsMapper.selectById(id) == null) { + throw exception(NOTIFICATIONS_NOT_EXISTS); + } + } + + @Override + public NotificationsDO getNotifications(Long id) { + return notificationsMapper.selectById(id); + } + + @Override + public PageResult getNotificationsPage(NotificationsPageReqVO pageReqVO) { + return notificationsMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/resources/mapper/ad/AdMapper.xml b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/resources/mapper/ad/AdMapper.xml new file mode 100644 index 00000000..a716367e --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/resources/mapper/ad/AdMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/resources/mapper/notifications/NotificationsMapper.xml b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/resources/mapper/notifications/NotificationsMapper.xml new file mode 100644 index 00000000..31017913 --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/main/resources/mapper/notifications/NotificationsMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/test/java/cn/yskj/linghe/module/acdr/service/ad/AdServiceImplTest.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/test/java/cn/yskj/linghe/module/acdr/service/ad/AdServiceImplTest.java new file mode 100644 index 00000000..8acd5c40 --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/test/java/cn/yskj/linghe/module/acdr/service/ad/AdServiceImplTest.java @@ -0,0 +1,146 @@ +package cn.yskj.linghe.module.acdr.service.ad; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + +import jakarta.annotation.Resource; + +import cn.yskj.linghe.framework.test.core.ut.BaseDbUnitTest; + +import cn.yskj.linghe.module.acdr.controller.admin.ad.vo.*; +import cn.yskj.linghe.module.acdr.dal.dataobject.ad.AdDO; +import cn.yskj.linghe.module.acdr.dal.mysql.ad.AdMapper; +import cn.yskj.linghe.framework.common.pojo.PageResult; + +import jakarta.annotation.Resource; +import org.springframework.context.annotation.Import; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.yskj.linghe.module.acdr.enums.ErrorCodeConstants.*; +import static cn.yskj.linghe.framework.test.core.util.AssertUtils.*; +import static cn.yskj.linghe.framework.test.core.util.RandomUtils.*; +import static cn.yskj.linghe.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.yskj.linghe.framework.common.util.object.ObjectUtils.*; +import static cn.yskj.linghe.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link AdServiceImpl} 的单元测试类 + * + * @author 芋道源码 + */ +@Import(AdServiceImpl.class) +public class AdServiceImplTest extends BaseDbUnitTest { + + @Resource + private AdServiceImpl adService; + + @Resource + private AdMapper adMapper; + + @Test + public void testCreateAd_success() { + // 准备参数 + AdSaveReqVO createReqVO = randomPojo(AdSaveReqVO.class).setId(null); + + // 调用 + Long adId = adService.createAd(createReqVO); + // 断言 + assertNotNull(adId); + // 校验记录的属性是否正确 + AdDO ad = adMapper.selectById(adId); + assertPojoEquals(createReqVO, ad, "id"); + } + + @Test + public void testUpdateAd_success() { + // mock 数据 + AdDO dbAd = randomPojo(AdDO.class); + adMapper.insert(dbAd);// @Sql: 先插入出一条存在的数据 + // 准备参数 + AdSaveReqVO updateReqVO = randomPojo(AdSaveReqVO.class, o -> { + o.setId(dbAd.getId()); // 设置更新的 ID + }); + + // 调用 + adService.updateAd(updateReqVO); + // 校验是否更新正确 + AdDO ad = adMapper.selectById(updateReqVO.getId()); // 获取最新的 + assertPojoEquals(updateReqVO, ad); + } + + @Test + public void testUpdateAd_notExists() { + // 准备参数 + AdSaveReqVO updateReqVO = randomPojo(AdSaveReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> adService.updateAd(updateReqVO), AD_NOT_EXISTS); + } + + @Test + public void testDeleteAd_success() { + // mock 数据 + AdDO dbAd = randomPojo(AdDO.class); + adMapper.insert(dbAd);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbAd.getId(); + + // 调用 + adService.deleteAd(id); + // 校验数据不存在了 + assertNull(adMapper.selectById(id)); + } + + @Test + public void testDeleteAd_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> adService.deleteAd(id), AD_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetAdPage() { + // mock 数据 + AdDO dbAd = randomPojo(AdDO.class, o -> { // 等会查询到 + o.setType(null); + o.setImageUrl(null); + o.setContent(null); + o.setCreateTime(null); + o.setPagesUrl(null); + }); + adMapper.insert(dbAd); + // 测试 type 不匹配 + adMapper.insert(cloneIgnoreId(dbAd, o -> o.setType(null))); + // 测试 imageUrl 不匹配 + adMapper.insert(cloneIgnoreId(dbAd, o -> o.setImageUrl(null))); + // 测试 content 不匹配 + adMapper.insert(cloneIgnoreId(dbAd, o -> o.setContent(null))); + // 测试 createTime 不匹配 + adMapper.insert(cloneIgnoreId(dbAd, o -> o.setCreateTime(null))); + // 测试 pagesUrl 不匹配 + adMapper.insert(cloneIgnoreId(dbAd, o -> o.setPagesUrl(null))); + // 准备参数 + AdPageReqVO reqVO = new AdPageReqVO(); + reqVO.setType(null); + reqVO.setImageUrl(null); + reqVO.setContent(null); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + reqVO.setPagesUrl(null); + + // 调用 + PageResult pageResult = adService.getAdPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbAd, pageResult.getList().get(0)); + } + +} \ No newline at end of file diff --git a/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/test/java/cn/yskj/linghe/module/acdr/service/notifications/NotificationsServiceImplTest.java b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/test/java/cn/yskj/linghe/module/acdr/service/notifications/NotificationsServiceImplTest.java new file mode 100644 index 00000000..5c27adfc --- /dev/null +++ b/acdr-admin/yskj-module-acdr/yskj-module-acdr-biz/src/test/java/cn/yskj/linghe/module/acdr/service/notifications/NotificationsServiceImplTest.java @@ -0,0 +1,158 @@ +package cn.yskj.linghe.module.acdr.service.notifications; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + +import jakarta.annotation.Resource; + +import cn.yskj.linghe.framework.test.core.ut.BaseDbUnitTest; + +import cn.yskj.linghe.module.acdr.controller.admin.notifications.vo.*; +import cn.yskj.linghe.module.acdr.dal.dataobject.notifications.NotificationsDO; +import cn.yskj.linghe.module.acdr.dal.mysql.notifications.NotificationsMapper; +import cn.yskj.linghe.framework.common.pojo.PageResult; + +import jakarta.annotation.Resource; +import org.springframework.context.annotation.Import; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.yskj.linghe.module.acdr.enums.ErrorCodeConstants.*; +import static cn.yskj.linghe.framework.test.core.util.AssertUtils.*; +import static cn.yskj.linghe.framework.test.core.util.RandomUtils.*; +import static cn.yskj.linghe.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.yskj.linghe.framework.common.util.object.ObjectUtils.*; +import static cn.yskj.linghe.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link NotificationsServiceImpl} 的单元测试类 + * + * @author 林河 + */ +@Import(NotificationsServiceImpl.class) +public class NotificationsServiceImplTest extends BaseDbUnitTest { + + @Resource + private NotificationsServiceImpl notificationsService; + + @Resource + private NotificationsMapper notificationsMapper; + + @Test + public void testCreateNotifications_success() { + // 准备参数 + NotificationsSaveReqVO createReqVO = randomPojo(NotificationsSaveReqVO.class).setId(null); + + // 调用 + Long notificationsId = notificationsService.createNotifications(createReqVO); + // 断言 + assertNotNull(notificationsId); + // 校验记录的属性是否正确 + NotificationsDO notifications = notificationsMapper.selectById(notificationsId); + assertPojoEquals(createReqVO, notifications, "id"); + } + + @Test + public void testUpdateNotifications_success() { + // mock 数据 + NotificationsDO dbNotifications = randomPojo(NotificationsDO.class); + notificationsMapper.insert(dbNotifications);// @Sql: 先插入出一条存在的数据 + // 准备参数 + NotificationsSaveReqVO updateReqVO = randomPojo(NotificationsSaveReqVO.class, o -> { + o.setId(dbNotifications.getId()); // 设置更新的 ID + }); + + // 调用 + notificationsService.updateNotifications(updateReqVO); + // 校验是否更新正确 + NotificationsDO notifications = notificationsMapper.selectById(updateReqVO.getId()); // 获取最新的 + assertPojoEquals(updateReqVO, notifications); + } + + @Test + public void testUpdateNotifications_notExists() { + // 准备参数 + NotificationsSaveReqVO updateReqVO = randomPojo(NotificationsSaveReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> notificationsService.updateNotifications(updateReqVO), NOTIFICATIONS_NOT_EXISTS); + } + + @Test + public void testDeleteNotifications_success() { + // mock 数据 + NotificationsDO dbNotifications = randomPojo(NotificationsDO.class); + notificationsMapper.insert(dbNotifications);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbNotifications.getId(); + + // 调用 + notificationsService.deleteNotifications(id); + // 校验数据不存在了 + assertNull(notificationsMapper.selectById(id)); + } + + @Test + public void testDeleteNotifications_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> notificationsService.deleteNotifications(id), NOTIFICATIONS_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetNotificationsPage() { + // mock 数据 + NotificationsDO dbNotifications = randomPojo(NotificationsDO.class, o -> { // 等会查询到 + o.setContent(null); + o.setUrl(null); + o.setStatus(null); + o.setType(null); + o.setUserId(null); + o.setReceiverScope(null); + o.setTitle(null); + o.setCreateTime(null); + }); + notificationsMapper.insert(dbNotifications); + // 测试 content 不匹配 + notificationsMapper.insert(cloneIgnoreId(dbNotifications, o -> o.setContent(null))); + // 测试 url 不匹配 + notificationsMapper.insert(cloneIgnoreId(dbNotifications, o -> o.setUrl(null))); + // 测试 status 不匹配 + notificationsMapper.insert(cloneIgnoreId(dbNotifications, o -> o.setStatus(null))); + // 测试 type 不匹配 + notificationsMapper.insert(cloneIgnoreId(dbNotifications, o -> o.setType(null))); + // 测试 userId 不匹配 + notificationsMapper.insert(cloneIgnoreId(dbNotifications, o -> o.setUserId(null))); + // 测试 receiverScope 不匹配 + notificationsMapper.insert(cloneIgnoreId(dbNotifications, o -> o.setReceiverScope(null))); + // 测试 title 不匹配 + notificationsMapper.insert(cloneIgnoreId(dbNotifications, o -> o.setTitle(null))); + // 测试 createTime 不匹配 + notificationsMapper.insert(cloneIgnoreId(dbNotifications, o -> o.setCreateTime(null))); + // 准备参数 + NotificationsPageReqVO reqVO = new NotificationsPageReqVO(); + reqVO.setContent(null); + reqVO.setUrl(null); + reqVO.setStatus(null); + reqVO.setType(null); + reqVO.setUserId(null); + reqVO.setReceiverScope(null); + reqVO.setTitle(null); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + + // 调用 + PageResult pageResult = notificationsService.getNotificationsPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbNotifications, pageResult.getList().get(0)); + } + +} \ No newline at end of file diff --git a/acdr-admin/yskj-ui/yskj-ui-admin-vue2/src/api/acdr/notifications/index.js b/acdr-admin/yskj-ui/yskj-ui-admin-vue2/src/api/acdr/notifications/index.js new file mode 100644 index 00000000..935b76b9 --- /dev/null +++ b/acdr-admin/yskj-ui/yskj-ui-admin-vue2/src/api/acdr/notifications/index.js @@ -0,0 +1,53 @@ +import request from '@/utils/request' + +// 创建通知 +export function createNotifications(data) { + return request({ + url: '/acdr/notifications/create', + method: 'post', + data: data + }) +} + +// 更新通知 +export function updateNotifications(data) { + return request({ + url: '/acdr/notifications/update', + method: 'put', + data: data + }) +} + +// 删除通知 +export function deleteNotifications(id) { + return request({ + url: '/acdr/notifications/delete?id=' + id, + method: 'delete' + }) +} + +// 获得通知 +export function getNotifications(id) { + return request({ + url: '/acdr/notifications/get?id=' + id, + method: 'get' + }) +} + +// 获得通知分页 +export function getNotificationsPage(params) { + return request({ + url: '/acdr/notifications/page', + method: 'get', + params + }) +} +// 导出通知 Excel +export function exportNotificationsExcel(params) { + return request({ + url: '/acdr/notifications/export-excel', + method: 'get', + params, + responseType: 'blob' + }) +} \ No newline at end of file diff --git a/acdr-admin/yskj-ui/yskj-ui-admin-vue2/src/views/acdr/notifications/NotificationsForm.vue b/acdr-admin/yskj-ui/yskj-ui-admin-vue2/src/views/acdr/notifications/NotificationsForm.vue new file mode 100644 index 00000000..1c0d3ef1 --- /dev/null +++ b/acdr-admin/yskj-ui/yskj-ui-admin-vue2/src/views/acdr/notifications/NotificationsForm.vue @@ -0,0 +1,130 @@ + + + \ No newline at end of file diff --git a/acdr-admin/yskj-ui/yskj-ui-admin-vue2/src/views/acdr/notifications/index.vue b/acdr-admin/yskj-ui/yskj-ui-admin-vue2/src/views/acdr/notifications/index.vue new file mode 100644 index 00000000..790e3b2b --- /dev/null +++ b/acdr-admin/yskj-ui/yskj-ui-admin-vue2/src/views/acdr/notifications/index.vue @@ -0,0 +1,175 @@ + + + \ No newline at end of file diff --git a/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/api/acdr/ad/index.ts b/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/api/acdr/ad/index.ts new file mode 100644 index 00000000..a5c27369 --- /dev/null +++ b/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/api/acdr/ad/index.ts @@ -0,0 +1,43 @@ +import request from '@/config/axios' + +// 推广 VO +export interface AdVO { + id: number // 推广ID + type: number // 资源类型 + imageUrl: string // 图片路径 + content: string // 推广语 + pagesUrl: string // 资源路径 +} + +// 推广 API +export const AdApi = { + // 查询推广分页 + getAdPage: async (params: any) => { + return await request.get({ url: `/acdr/ad/page`, params }) + }, + + // 查询推广详情 + getAd: async (id: number) => { + return await request.get({ url: `/acdr/ad/get?id=` + id }) + }, + + // 新增推广 + createAd: async (data: AdVO) => { + return await request.post({ url: `/acdr/ad/create`, data }) + }, + + // 修改推广 + updateAd: async (data: AdVO) => { + return await request.put({ url: `/acdr/ad/update`, data }) + }, + + // 删除推广 + deleteAd: async (id: number) => { + return await request.delete({ url: `/acdr/ad/delete?id=` + id }) + }, + + // 导出推广 Excel + exportAd: async (params) => { + return await request.download({ url: `/acdr/ad/export-excel`, params }) + }, +} \ No newline at end of file diff --git a/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/api/acdr/notifications/index.ts b/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/api/acdr/notifications/index.ts new file mode 100644 index 00000000..0f2ad6cd --- /dev/null +++ b/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/api/acdr/notifications/index.ts @@ -0,0 +1,46 @@ +import request from '@/config/axios' + +// 通知 VO +export interface NotificationsVO { + id: number // 消息主键 + content: string // 内容 + url: string // 需要跳转的页面 + status: number // 消息创建状态 + type: string // 消息类型 + userId: number // 消息创建者 + receiverScope: string // 消息接受范围 + title: string // 标题 +} + +// 通知 API +export const NotificationsApi = { + // 查询通知分页 + getNotificationsPage: async (params: any) => { + return await request.get({ url: `/acdr/notifications/page`, params }) + }, + + // 查询通知详情 + getNotifications: async (id: number) => { + return await request.get({ url: `/acdr/notifications/get?id=` + id }) + }, + + // 新增通知 + createNotifications: async (data: NotificationsVO) => { + return await request.post({ url: `/acdr/notifications/create`, data }) + }, + + // 修改通知 + updateNotifications: async (data: NotificationsVO) => { + return await request.put({ url: `/acdr/notifications/update`, data }) + }, + + // 删除通知 + deleteNotifications: async (id: number) => { + return await request.delete({ url: `/acdr/notifications/delete?id=` + id }) + }, + + // 导出通知 Excel + exportNotifications: async (params) => { + return await request.download({ url: `/acdr/notifications/export-excel`, params }) + }, +} \ No newline at end of file diff --git a/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/views/acdr/ad/AdForm.vue b/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/views/acdr/ad/AdForm.vue new file mode 100644 index 00000000..c3917b55 --- /dev/null +++ b/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/views/acdr/ad/AdForm.vue @@ -0,0 +1,114 @@ + + \ No newline at end of file diff --git a/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/views/acdr/ad/index.vue b/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/views/acdr/ad/index.vue new file mode 100644 index 00000000..b68dadd7 --- /dev/null +++ b/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/views/acdr/ad/index.vue @@ -0,0 +1,213 @@ + + + \ No newline at end of file diff --git a/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/views/acdr/notifications/NotificationsForm.vue b/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/views/acdr/notifications/NotificationsForm.vue new file mode 100644 index 00000000..5fa3b0d3 --- /dev/null +++ b/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/views/acdr/notifications/NotificationsForm.vue @@ -0,0 +1,125 @@ + + \ No newline at end of file diff --git a/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/views/acdr/notifications/index.vue b/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/views/acdr/notifications/index.vue new file mode 100644 index 00000000..8a484516 --- /dev/null +++ b/acdr-admin/yskj-ui/yskj-ui-admin-vue3/src/views/acdr/notifications/index.vue @@ -0,0 +1,246 @@ + + + \ No newline at end of file diff --git a/acdr-ui/.vscode/settings.json b/acdr-ui/.vscode/settings.json index 32c7ef4e..73e24eca 100644 --- a/acdr-ui/.vscode/settings.json +++ b/acdr-ui/.vscode/settings.json @@ -62,5 +62,8 @@ "vite.config.ts": "tsconfig.*.json,uno.config.ts,tsconfig.json,uni-pages.d.ts", "manifest.config.ts": "manifest.config.ts,pages.config.ts" }, - "vue3snippets.enable-compile-vue-file-on-did-save-code": true + "vue3snippets.enable-compile-vue-file-on-did-save-code": true, + "[python]": { + "editor.defaultFormatter": "ms-python.black-formatter" + } } diff --git a/acdr-ui/src/pages/certification/index.vue b/acdr-ui/src/pages/certification/index.vue index 3ecb62e3..347e0ce8 100644 --- a/acdr-ui/src/pages/certification/index.vue +++ b/acdr-ui/src/pages/certification/index.vue @@ -16,7 +16,11 @@ :src="'/static/certification/certification_bg.png'" mode="aspectFill" > - + + 您还未认证,加入我们成为宠托师! + + + {{ applyStateData }} + + { show.value = false @@ -94,7 +107,21 @@ const handleJoin = () => { // 获取认证状态和证书信息 const getCertificationStatus = async () => { - certificate.value = await httpGet('/petInfo/getExpertInfo') + const res = await httpGet('/petInfo/getExpertInfo') + if (res.code == 200) { + certificate.value = res.data + } + // 如果返回值不是两百就表示该角色没有宠托师信息,获取申请状态 + else { + const stateRes = await httpGet('/petInfo/getApplyState') + if (stateRes.code == 200) { + // 这里是显示申请进度的地方 + applyState.value = true + applyStateData.value = stateRes.data + } else { + // 这里跳转到申请界面, 好吧这里就是申请界面了,啥都不用干 + } + } } // 格式化日期 diff --git a/acdr-ui/tootls/代码生成工具.py b/acdr-ui/tootls/代码生成工具.py index c9ea7650..054d5b09 100644 --- a/acdr-ui/tootls/代码生成工具.py +++ b/acdr-ui/tootls/代码生成工具.py @@ -2,33 +2,55 @@ import os import shutil import pymysql import tkinter as tk -from tkinter import filedialog, messagebox, StringVar +from tkinter import filedialog, messagebox, StringVar, BooleanVar +import configparser + # 执行 SQL 文件 def execute_sql_file(sql_file_path, db_config): + connection = None + cursor = None try: # 连接 MySQL 数据库 connection = pymysql.connect( - host=db_config['host'], - user=db_config['user'], - password=db_config['password'], - database=db_config['database'], - port=int(db_config['port']) + host=db_config["host"], + user=db_config["user"], + password=db_config["password"], + database=db_config["database"], + port=int(db_config["port"]), ) cursor = connection.cursor() - with open(sql_file_path, 'r', encoding='utf-8') as file: + + # 读取并处理 SQL 文件 + with open(sql_file_path, "r", encoding="utf-8") as file: sql_script = file.read() - cursor.execute(sql_script) + + # 拆分 SQL 语句 + statements = sql_script.split(";") + for statement in statements: + # 去除空的语句 + if statement.strip(): + cursor.execute(statement) + print(f"执行 SQL 语句: {statement.strip()}") + + # 提交事务 connection.commit() messagebox.showinfo("SQL执行成功", f"SQL文件 {sql_file_path} 已成功执行") except Exception as e: messagebox.showerror("SQL执行失败", f"执行SQL文件时出错: {e}") + if connection: + connection.rollback() finally: - cursor.close() - connection.close() + if cursor: + cursor.close() + if connection: + connection.close() + # 处理解压后的文件 -def handle_extracted_files(temp_extract_dir, output_dir, ui_dir, db_config): +def handle_extracted_files( + temp_extract_dir, output_dir, ui_dir, db_config, execute_sql +): for root_dir, dirs, files in os.walk(temp_extract_dir): for file in files: src_file_path = os.path.join(root_dir, file) @@ -41,7 +63,7 @@ def handle_extracted_files(temp_extract_dir, output_dir, ui_dir, db_config): shutil.copy2(src_file_path, dest_file_path) print(f"复制文件 {src_file_path} 到 {dest_file_path}") - elif "sql" in top_level_dir and file == "sql.sql": + elif "sql" in top_level_dir and file == "sql.sql" and execute_sql: execute_sql_file(src_file_path, db_config) print(f"执行SQL文件: {src_file_path}") @@ -51,18 +73,37 @@ def handle_extracted_files(temp_extract_dir, output_dir, ui_dir, db_config): shutil.copy2(src_file_path, dest_file_path) print(f"复制文件 {src_file_path} 到 {dest_file_path}") + # 选择zip文件 def select_zip_file(): zip_file_path.set(filedialog.askopenfilename(filetypes=[("ZIP files", "*.zip")])) + # 选择输出目录 def select_output_dir(): output_dir.set(filedialog.askdirectory()) + # 选择UI目录 def select_ui_dir(): ui_dir.set(filedialog.askdirectory()) + +# 保存配置信息到 .ini 文件 +def save_config_to_ini(): + config = configparser.ConfigParser() + config["DATABASE"] = { + "host": host_var.get(), + "user": user_var.get(), + "password": password_var.get(), + "database": db_var.get(), + "port": port_var.get(), + } + with open("config.ini", "w") as configfile: + config.write(configfile) + messagebox.showinfo("保存成功", "数据库配置信息已保存到 config.ini 文件中") + + # 解压并处理文件 def extract_and_process_files(): if not zip_file_path.get() or not output_dir.get() or not ui_dir.get(): @@ -71,23 +112,31 @@ def extract_and_process_files(): # 设置数据库连接参数 db_config = { - 'host': host_var.get() or 'localhost', - 'user': user_var.get() or 'root', - 'password': password_var.get() or 'root', - 'database': db_var.get() or 'cwet', - 'port': port_var.get() or 3306 + "host": host_var.get() or "localhost", + "user": user_var.get() or "root", + "password": password_var.get() or "root", + "database": db_var.get() or "cwet", + "port": port_var.get() or 3306, } - # 解压ZIP文件 - temp_extract_dir = os.path.join(output_dir.get(), "temp_extracted") - shutil.unpack_archive(zip_file_path.get(), temp_extract_dir) + # 检查是否选择了执行 SQL + if execute_sql_var.get(): + # 解压ZIP文件并执行 SQL + temp_extract_dir = os.path.join(output_dir.get(), "temp_extracted") + shutil.unpack_archive(zip_file_path.get(), temp_extract_dir) - # 处理解压后的文件 - handle_extracted_files(temp_extract_dir, output_dir.get(), ui_dir.get(), db_config) + # 处理解压后的文件 + handle_extracted_files( + temp_extract_dir, output_dir.get(), ui_dir.get(), db_config, True + ) + + # 清理临时文件夹 + shutil.rmtree(temp_extract_dir) + messagebox.showinfo("完成", "文件处理完成!") + else: + # 保存配置到 ini 文件 + save_config_to_ini() - # 清理临时文件夹 - shutil.rmtree(temp_extract_dir) - messagebox.showinfo("完成", "文件处理完成!") # 创建主窗口 root = tk.Tk() @@ -99,24 +148,35 @@ output_dir = StringVar() ui_dir = StringVar() # 数据库连接参数 -host_var = StringVar(value='localhost') -user_var = StringVar(value='root') -password_var = StringVar(value='root') -db_var = StringVar(value='cwet') -port_var = StringVar(value='3306') +host_var = StringVar(value="localhost") +user_var = StringVar(value="root") +password_var = StringVar(value="root") +db_var = StringVar(value="cwet") +port_var = StringVar(value="3306") + +# 是否执行 SQL 的选择 +execute_sql_var = BooleanVar(value=True) # GUI布局 tk.Label(root, text="选择ZIP文件:").grid(row=0, column=0, padx=10, pady=5) -tk.Entry(root, textvariable=zip_file_path, width=50).grid(row=0, column=1, padx=10, pady=5) -tk.Button(root, text="选择ZIP文件", command=select_zip_file).grid(row=0, column=2, padx=10, pady=5) +tk.Entry(root, textvariable=zip_file_path, width=50).grid( + row=0, column=1, padx=10, pady=5 +) +tk.Button(root, text="选择ZIP文件", command=select_zip_file).grid( + row=0, column=2, padx=10, pady=5 +) tk.Label(root, text="选择输出目录:").grid(row=1, column=0, padx=10, pady=5) tk.Entry(root, textvariable=output_dir, width=50).grid(row=1, column=1, padx=10, pady=5) -tk.Button(root, text="选择输出目录", command=select_output_dir).grid(row=1, column=2, padx=10, pady=5) +tk.Button(root, text="选择输出目录", command=select_output_dir).grid( + row=1, column=2, padx=10, pady=5 +) tk.Label(root, text="选择UI目录:").grid(row=2, column=0, padx=10, pady=5) tk.Entry(root, textvariable=ui_dir, width=50).grid(row=2, column=1, padx=10, pady=5) -tk.Button(root, text="选择UI目录", command=select_ui_dir).grid(row=2, column=2, padx=10, pady=5) +tk.Button(root, text="选择UI目录", command=select_ui_dir).grid( + row=2, column=2, padx=10, pady=5 +) # 数据库设置 tk.Label(root, text="数据库主机:").grid(row=3, column=0, padx=10, pady=5) @@ -134,7 +194,15 @@ tk.Entry(root, textvariable=db_var).grid(row=6, column=1, padx=10, pady=5) tk.Label(root, text="端口:").grid(row=7, column=0, padx=10, pady=5) tk.Entry(root, textvariable=port_var).grid(row=7, column=1, padx=10, pady=5) -tk.Button(root, text="开始处理", command=extract_and_process_files).grid(row=8, column=1, padx=10, pady=20) +# 执行 SQL 的复选框 +tk.Checkbutton(root, text="执行SQL语句", variable=execute_sql_var).grid( + row=8, column=0, columnspan=2, padx=10, pady=5 +) + +# 开始处理按钮 +tk.Button(root, text="开始处理", command=extract_and_process_files).grid( + row=9, column=1, padx=10, pady=20 +) # 运行应用 root.mainloop() diff --git a/acdr/src/main/java/com/yskj/acdr/common/mybatis/TableToEntityConstructor.java b/acdr/src/main/java/com/yskj/acdr/common/mybatis/TableToEntityConstructor.java index a688a4b3..b0c3baf8 100644 --- a/acdr/src/main/java/com/yskj/acdr/common/mybatis/TableToEntityConstructor.java +++ b/acdr/src/main/java/com/yskj/acdr/common/mybatis/TableToEntityConstructor.java @@ -16,7 +16,7 @@ public class TableToEntityConstructor { // 新版本的代码生成器 public static void AutoTable(String moduleName, String entityPackage, String mapperPackage, String servicePackage, String... tables) { FastAutoGenerator.create( - "jdbc:mysql://localhost:3306/acdr?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false", + "jdbc:mysql://localhost:3306/cwet?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false", "root", "root") .globalConfig(builder -> { @@ -74,7 +74,7 @@ public class TableToEntityConstructor { } public static void main(String[] args) { - AutoTable("chat", "", "", "", - "acdr_chat_message"); + AutoTable("ad", "", "", "", + "acdr_ad"); } } diff --git a/acdr/src/main/java/com/yskj/acdr/master/ad/controller/AdController.java b/acdr/src/main/java/com/yskj/acdr/master/ad/controller/AdController.java new file mode 100644 index 00000000..16e2939f --- /dev/null +++ b/acdr/src/main/java/com/yskj/acdr/master/ad/controller/AdController.java @@ -0,0 +1,71 @@ +package com.yskj.acdr.master.ad.controller; + +import com.yskj.acdr.common.response.GlobalResponse; +import com.yskj.acdr.master.ad.entity.Ad; +import com.yskj.acdr.master.ad.service.IAdService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import jakarta.validation.groups.Default; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + *

+ * 推广表 前端控制器 + *

+ * + * @author 林河 + * @since 2024-09-12 + */ +@Api(tags = "推广表") +@RestController +@RequestMapping("/ad") +public class AdController { + + @Autowired + private IAdService service; + + @ApiOperation(value = "推广表分页列表", response = Ad.class) + @PostMapping(value = "/page") + public GlobalResponse list(GlobalResponse page) { + return service.lambdaQuery().page(page); + } + + @ApiOperation(value = "推广表详情", response = Ad.class) + @GetMapping(value = "/info/{id}") + public GlobalResponse info(@Validated({GetMapping.class}) @PathVariable Long id) { + Ad ad = service.getById(id); + return GlobalResponse.success(ad); + } + + @ApiOperation(value = "推广表新增") + @PostMapping(value = "/add") + public GlobalResponse add(@Validated({PostMapping.class, Default.class}) @RequestBody Ad param) { + service.save(param); + return GlobalResponse.success("推广表新增成功!"); + } + + @ApiOperation(value = "推广表修改") + @PostMapping(value = "/modify") + public GlobalResponse modify(@Validated({PutMapping.class, Default.class}) @RequestBody Ad param) { + service.updateById(param); + return GlobalResponse.success("推广表修改成功!"); + } + + @ApiOperation(value = "推广表删除(单个条目)") + @GetMapping(value = "/remove/{id}") + public GlobalResponse remove(@Validated({DeleteMapping.class}) @PathVariable Long id) { + service.removeById(id); + return GlobalResponse.success("推广表删除(单个条目)!"); + } + + @ApiOperation(value = "推广表删除(多个条目)") + @PostMapping(value = "/removes") + public GlobalResponse removes(@RequestBody List ids) { + service.removeBatchByIds(ids); + return GlobalResponse.success("推广表删除(多个条目)!"); + } +} diff --git a/acdr/src/main/java/com/yskj/acdr/master/ad/entity/Ad.java b/acdr/src/main/java/com/yskj/acdr/master/ad/entity/Ad.java new file mode 100644 index 00000000..26e3ca50 --- /dev/null +++ b/acdr/src/main/java/com/yskj/acdr/master/ad/entity/Ad.java @@ -0,0 +1,52 @@ +package com.yskj.acdr.master.ad.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.yskj.acdr.master.common.ExtendEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 推广表 + *

+ * + * @author 林河 + * @since 2024-09-12 + */ +@Getter +@Setter +@ToString +@Accessors(chain = true) +@TableName("acdr_ad") +@ApiModel(value = "Ad对象", description = "推广表") +public class Ad extends ExtendEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("推广ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + @ApiModelProperty("资源类型") + @TableField("type") + private Integer type; + + @ApiModelProperty("图片路径") + @TableField("image_url") + private String imageUrl; + + @ApiModelProperty("推广语") + @TableField("content") + private String content; + + @ApiModelProperty("资源路径") + @TableField("pages_url") + private String pagesUrl; +} diff --git a/acdr/src/main/java/com/yskj/acdr/master/ad/mapper/AdMapper.java b/acdr/src/main/java/com/yskj/acdr/master/ad/mapper/AdMapper.java new file mode 100644 index 00000000..85ce9511 --- /dev/null +++ b/acdr/src/main/java/com/yskj/acdr/master/ad/mapper/AdMapper.java @@ -0,0 +1,18 @@ +package com.yskj.acdr.master.ad.mapper; + +import com.yskj.acdr.master.ad.entity.Ad; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 推广表 Mapper 接口 + *

+ * + * @author 林河 + * @since 2024-09-12 + */ +@Mapper +public interface AdMapper extends BaseMapper { + +} diff --git a/acdr/src/main/java/com/yskj/acdr/master/ad/mapper/xml/AdMapper.xml b/acdr/src/main/java/com/yskj/acdr/master/ad/mapper/xml/AdMapper.xml new file mode 100644 index 00000000..28226e90 --- /dev/null +++ b/acdr/src/main/java/com/yskj/acdr/master/ad/mapper/xml/AdMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/acdr/src/main/java/com/yskj/acdr/master/ad/service/IAdService.java b/acdr/src/main/java/com/yskj/acdr/master/ad/service/IAdService.java new file mode 100644 index 00000000..91a44e47 --- /dev/null +++ b/acdr/src/main/java/com/yskj/acdr/master/ad/service/IAdService.java @@ -0,0 +1,16 @@ +package com.yskj.acdr.master.ad.service; + +import com.yskj.acdr.master.ad.entity.Ad; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 推广表 服务类 + *

+ * + * @author 林河 + * @since 2024-09-12 + */ +public interface IAdService extends IService { + +} diff --git a/acdr/src/main/java/com/yskj/acdr/master/ad/service/impl/AdServiceImpl.java b/acdr/src/main/java/com/yskj/acdr/master/ad/service/impl/AdServiceImpl.java new file mode 100644 index 00000000..1178eb30 --- /dev/null +++ b/acdr/src/main/java/com/yskj/acdr/master/ad/service/impl/AdServiceImpl.java @@ -0,0 +1,20 @@ +package com.yskj.acdr.master.ad.service.impl; + +import com.yskj.acdr.master.ad.entity.Ad; +import com.yskj.acdr.master.ad.mapper.AdMapper; +import com.yskj.acdr.master.ad.service.IAdService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 推广表 服务实现类 + *

+ * + * @author 林河 + * @since 2024-09-12 + */ +@Service +public class AdServiceImpl extends ServiceImpl implements IAdService { + +} diff --git a/acdr/src/main/java/com/yskj/acdr/master/common/ExtendEntity.java b/acdr/src/main/java/com/yskj/acdr/master/common/ExtendEntity.java index f9ef0419..8ac39e67 100644 --- a/acdr/src/main/java/com/yskj/acdr/master/common/ExtendEntity.java +++ b/acdr/src/main/java/com/yskj/acdr/master/common/ExtendEntity.java @@ -28,7 +28,8 @@ public class ExtendEntity { // 逻辑删除 @TableLogic - private Boolean deleted; + @TableField(value = "deleted", fill = FieldFill.INSERT) + private Boolean deleted = false; @TableField(value = "create_time", fill = FieldFill.INSERT) private LocalDateTime createTime; diff --git a/acdr/src/main/java/com/yskj/acdr/master/pet/controller/PetController.java b/acdr/src/main/java/com/yskj/acdr/master/pet/controller/PetController.java index 27c69405..08306063 100644 --- a/acdr/src/main/java/com/yskj/acdr/master/pet/controller/PetController.java +++ b/acdr/src/main/java/com/yskj/acdr/master/pet/controller/PetController.java @@ -13,6 +13,7 @@ import com.yskj.acdr.master.pet.entity.PetSpecialistCertificate; import com.yskj.acdr.master.pet.service.PetExpertCertificationService; import com.yskj.acdr.master.pet.service.PetInfoService; import com.yskj.acdr.master.pet.service.PetSpecialistCertificateService; +import com.yskj.acdr.master.pet.status.PetExpertCertificationStatus; import jakarta.annotation.Resource; import jakarta.validation.constraints.NotBlank; import jakarta.validation.groups.Default; @@ -166,5 +167,18 @@ public class PetController { if (one == null || one.isEmpty()) return GlobalResponse.success(); return GlobalResponse.success(one.getFirst()); } + + /** + * 获取当前宠托师的申请进度/状态 + */ + @GetMapping("/getApplyState") + public GlobalResponse getApplyState() { + // 获取当前用户的申请状态 + PetExpertCertification one = pecs.lambdaQuery() + .eq(PetExpertCertification::getUserId, StpUtil.getLoginIdAsLong()) + .one(); + if (one == null) return GlobalResponse.failure("你还没有申请成为宠托师!"); + return GlobalResponse.success(one.getState()); + } } diff --git a/acdr/src/main/java/com/yskj/acdr/master/user/controller/AuthController.java b/acdr/src/main/java/com/yskj/acdr/master/user/controller/AuthController.java index f1fbc7c1..680634de 100644 --- a/acdr/src/main/java/com/yskj/acdr/master/user/controller/AuthController.java +++ b/acdr/src/main/java/com/yskj/acdr/master/user/controller/AuthController.java @@ -51,7 +51,7 @@ public class AuthController { } - @ApiOperation("判断是否对手机进行实名认证") + @ApiOperation("判断是否对手机进行认证") @GetMapping("/isPhoneBind") public GlobalResponse isUsePhone() { Users user = usersService.getById(StpUtil.getLoginIdAsLong()); diff --git a/acdr/src/main/java/com/yskj/acdr/master/user/entity/Users.java b/acdr/src/main/java/com/yskj/acdr/master/user/entity/Users.java index 70ddf156..27783f58 100644 --- a/acdr/src/main/java/com/yskj/acdr/master/user/entity/Users.java +++ b/acdr/src/main/java/com/yskj/acdr/master/user/entity/Users.java @@ -27,8 +27,8 @@ import java.time.LocalDateTime; @ToString @Accessors(chain = true) @TableName("acdr_users") -@ApiModel(value = "UserBase对象", description = "") -public class Users implements Serializable { +@ApiModel(value = "Users对象", description = "") +public class Users extends ExtendEntity implements Serializable { private static final long serialVersionUID = 1L; @@ -81,14 +81,4 @@ public class Users implements Serializable { @ApiModelProperty("是否拥有宠托师证书") @TableField(value = "is_pet_nursery") private Boolean isPetNursery = false; - - // 逻辑删除 - @TableLogic - private Boolean deleted; - - @TableField(value = "create_time", fill = FieldFill.INSERT) - private LocalDateTime createTime; - - @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) - private LocalDateTime updateTime; } diff --git a/acdr/src/main/java/com/yskj/acdr/master/user/service/AuthenticationService.java b/acdr/src/main/java/com/yskj/acdr/master/user/service/AuthenticationService.java index 65191eda..6e1137f1 100644 --- a/acdr/src/main/java/com/yskj/acdr/master/user/service/AuthenticationService.java +++ b/acdr/src/main/java/com/yskj/acdr/master/user/service/AuthenticationService.java @@ -313,8 +313,9 @@ public class AuthenticationService { * 判断该当前用户是否经过实名认证 */ public boolean isRealName() { + long userId = StpUtil.getLoginIdAsLong(); var query = new LambdaQueryWrapper() - .eq(UserIdentityVerification::getUserId, StpUtil.getLoginIdAsLong()); + .eq(UserIdentityVerification::getUserId, userId); var userIdEn = uidmapper.selectOne(query); return userIdEn != null; }