提交 b5db0b85 authored 作者: hzh's avatar hzh

商城模块集成

上级 4dd9e647
package org.dromara.mall.controller.promotion.admin.article;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mall.enums.CommonStatusEnum;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.controller.promotion.admin.article.vo.category.*;
import org.dromara.mall.convert.promotion.article.ArticleCategoryConvert;
import org.dromara.mall.domain.promotion.ArticleCategoryDO;
import org.dromara.mall.service.promotion.ArticleCategoryService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Comparator;
import java.util.List;
@Tag(name = "管理后台 - 文章分类")
@RestController
@RequestMapping("/admin/promotion/article-category")
@Validated
public class ArticleCategoryController {
@Resource
private ArticleCategoryService articleCategoryService;
@PostMapping("/create")
@Operation(summary = "创建文章分类")
@SaCheckPermission("promotion:article-category:create")
public R<Long> createArticleCategory(@Valid @RequestBody ArticleCategoryCreateReqVO createReqVO) {
return R.ok(articleCategoryService.createArticleCategory(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新文章分类")
@SaCheckPermission("promotion:article-category:update")
public R<Boolean> updateArticleCategory(@Valid @RequestBody ArticleCategoryUpdateReqVO updateReqVO) {
articleCategoryService.updateArticleCategory(updateReqVO);
return R.ok(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除文章分类")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:article-category:delete")
public R<Boolean> deleteArticleCategory(@RequestParam("id") Long id) {
articleCategoryService.deleteArticleCategory(id);
return R.ok(true);
}
@GetMapping("/get")
@Operation(summary = "获得文章分类")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:article-category:query")
public R<ArticleCategoryRespVO> getArticleCategory(@RequestParam("id") Long id) {
ArticleCategoryDO category = articleCategoryService.getArticleCategory(id);
return R.ok(ArticleCategoryConvert.INSTANCE.convert(category));
}
@GetMapping("/list-all-simple")
@Operation(summary = "获取文章分类精简信息列表", description = "只包含被开启的文章分类,主要用于前端的下拉选项")
public R<List<ArticleCategorySimpleRespVO>> getSimpleDeptList() {
// 获得分类列表,只要开启状态的
List<ArticleCategoryDO> list = articleCategoryService.getArticleCategoryListByStatus(CommonStatusEnum.ENABLE.getStatus());
// 降序排序后,返回给前端
list.sort(Comparator.comparing(ArticleCategoryDO::getSort).reversed());
return R.ok(ArticleCategoryConvert.INSTANCE.convertList03(list));
}
@GetMapping("/page")
@Operation(summary = "获得文章分类分页")
@SaCheckPermission("promotion:article-category:query")
public R<PageResult<ArticleCategoryRespVO>> getArticleCategoryPage(@Valid ArticleCategoryPageReqVO pageVO) {
PageResult<ArticleCategoryDO> pageResult = articleCategoryService.getArticleCategoryPage(pageVO);
return R.ok(ArticleCategoryConvert.INSTANCE.convertPage(pageResult));
}
}
package org.dromara.mall.controller.promotion.admin.article;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.controller.promotion.admin.article.vo.article.ArticleCreateReqVO;
import org.dromara.mall.controller.promotion.admin.article.vo.article.ArticlePageReqVO;
import org.dromara.mall.controller.promotion.admin.article.vo.article.ArticleRespVO;
import org.dromara.mall.controller.promotion.admin.article.vo.article.ArticleUpdateReqVO;
import org.dromara.mall.convert.promotion.article.ArticleConvert;
import org.dromara.mall.domain.promotion.ArticleDO;
import org.dromara.mall.service.promotion.ArticleService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Tag(name = "管理后台 - 文章管理")
@RestController
@RequestMapping("/admin/promotion/article")
@Validated
public class ArticleController {
@Resource
private ArticleService articleService;
@PostMapping("/create")
@Operation(summary = "创建文章管理")
@SaCheckPermission("promotion:article:create")
public R<Long> createArticle(@Valid @RequestBody ArticleCreateReqVO createReqVO) {
return R.ok(articleService.createArticle(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新文章管理")
@SaCheckPermission("promotion:article:update")
public R<Boolean> updateArticle(@Valid @RequestBody ArticleUpdateReqVO updateReqVO) {
articleService.updateArticle(updateReqVO);
return R.ok(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除文章管理")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:article:delete")
public R<Boolean> deleteArticle(@RequestParam("id") Long id) {
articleService.deleteArticle(id);
return R.ok(true);
}
@GetMapping("/get")
@Operation(summary = "获得文章管理")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:article:query")
public R<ArticleRespVO> getArticle(@RequestParam("id") Long id) {
ArticleDO article = articleService.getArticle(id);
return R.ok(ArticleConvert.INSTANCE.convert(article));
}
@GetMapping("/page")
@Operation(summary = "获得文章管理分页")
@SaCheckPermission("promotion:article:query")
public R<PageResult<ArticleRespVO>> getArticlePage(@Valid ArticlePageReqVO pageVO) {
PageResult<ArticleDO> pageResult = articleService.getArticlePage(pageVO);
return R.ok(ArticleConvert.INSTANCE.convertPage(pageResult));
}
}
package org.dromara.mall.controller.promotion.admin.article.vo.article;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* 文章管理 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class ArticleBaseVO {
@Schema(description = "文章分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15458")
@NotNull(message = "文章分类编号不能为空")
private Long categoryId;
@Schema(description = "关联商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22378")
@NotNull(message = "关联商品不能为空")
private Long spuId;
@Schema(description = "文章标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "这是一个标题")
@NotNull(message = "文章标题不能为空")
private String title;
@Schema(description = "文章作者", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
private String author;
@Schema(description = "文章封面图片地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
@NotNull(message = "文章封面图片地址不能为空")
private String picUrl;
@Schema(description = "文章简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "这是一个简介")
private String introduction;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "排序不能为空")
private Integer sort;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "状态不能为空")
private Integer status;
@Schema(description = "是否热门(小程序)", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
@NotNull(message = "是否热门(小程序)不能为空")
private Boolean recommendHot;
@Schema(description = "是否轮播图(小程序)", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
@NotNull(message = "是否轮播图(小程序)不能为空")
private Boolean recommendBanner;
@Schema(description = "文章内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "这是文章内容")
@NotNull(message = "文章内容不能为空")
private String content;
}
package org.dromara.mall.controller.promotion.admin.article.vo.article;
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 ArticleCreateReqVO extends ArticleBaseVO {
}
package org.dromara.mall.controller.promotion.admin.article.vo.article;
import org.dromara.common.mybatis.core.page.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 org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 文章管理分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ArticlePageReqVO extends PageParam {
@Schema(description = "文章分类编号", example = "15458")
private Long categoryId;
@Schema(description = "关联商品编号", example = "22378")
private Long spuId;
@Schema(description = "文章标题")
private String title;
@Schema(description = "文章作者")
private String author;
@Schema(description = "状态", example = "2")
private Integer status;
@Schema(description = "是否热门(小程序)")
private Boolean recommendHot;
@Schema(description = "是否轮播图(小程序)")
private Boolean recommendBanner;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
package org.dromara.mall.controller.promotion.admin.article.vo.article;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 文章管理 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ArticleRespVO extends ArticleBaseVO {
@Schema(description = "文章编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8606")
private Long id;
@Schema(description = "浏览量", requiredMode = Schema.RequiredMode.REQUIRED, example = "99999")
private Integer browseCount;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}
package org.dromara.mall.controller.promotion.admin.article.vo.article;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 文章管理更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ArticleUpdateReqVO extends ArticleBaseVO {
@Schema(description = "文章编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8606")
@NotNull(message = "文章编号不能为空")
private Long id;
}
package org.dromara.mall.controller.promotion.admin.article.vo.category;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* 文章分类 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class ArticleCategoryBaseVO {
@Schema(description = "文章分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "秒杀")
@NotNull(message = "文章分类名称不能为空")
private String name;
@Schema(description = "图标地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
private String picUrl;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态不能为空")
private Integer status;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "排序不能为空")
private Integer sort;
}
package org.dromara.mall.controller.promotion.admin.article.vo.category;
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 ArticleCategoryCreateReqVO extends ArticleCategoryBaseVO {
}
package org.dromara.mall.controller.promotion.admin.article.vo.category;
import org.dromara.common.mybatis.core.page.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 org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 文章分类分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ArticleCategoryPageReqVO extends PageParam {
@Schema(description = "文章分类名称", example = "秒杀")
private String name;
@Schema(description = "状态", example = "1")
private Integer status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
package org.dromara.mall.controller.promotion.admin.article.vo.category;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 文章分类 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ArticleCategoryRespVO extends ArticleCategoryBaseVO {
@Schema(description = "文章分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "19490")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}
package org.dromara.mall.controller.promotion.admin.article.vo.category;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 文章分类精简信息 Response VO")
@Data
public class ArticleCategorySimpleRespVO {
@Schema(description = "文章分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "19490")
private Long id;
@Schema(description = "文章分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "秒杀")
private String name;
}
package org.dromara.mall.controller.promotion.admin.article.vo.category;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 文章分类更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ArticleCategoryUpdateReqVO extends ArticleCategoryBaseVO {
@Schema(description = "文章分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "19490")
@NotNull(message = "文章分类编号不能为空")
private Long id;
}
package org.dromara.mall.controller.promotion.admin.banner;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.controller.promotion.admin.banner.vo.BannerCreateReqVO;
import org.dromara.mall.controller.promotion.admin.banner.vo.BannerPageReqVO;
import org.dromara.mall.controller.promotion.admin.banner.vo.BannerRespVO;
import org.dromara.mall.controller.promotion.admin.banner.vo.BannerUpdateReqVO;
import org.dromara.mall.convert.promotion.banner.BannerConvert;
import org.dromara.mall.domain.promotion.BannerDO;
import org.dromara.mall.service.promotion.BannerService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Tag(name = "管理后台 - Banner 管理")
@RestController
@RequestMapping("/admin/promotion/banner")
@Validated
public class BannerController {
@Resource
private BannerService bannerService;
@PostMapping("/create")
@Operation(summary = "创建 Banner")
@SaCheckPermission("promotion:banner:create")
public R<Long> createBanner(@Valid @RequestBody BannerCreateReqVO createReqVO) {
return R.ok(bannerService.createBanner(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新 Banner")
@SaCheckPermission("promotion:banner:update")
public R<Boolean> updateBanner(@Valid @RequestBody BannerUpdateReqVO updateReqVO) {
bannerService.updateBanner(updateReqVO);
return R.ok(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除 Banner")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:banner:delete")
public R<Boolean> deleteBanner(@RequestParam("id") Long id) {
bannerService.deleteBanner(id);
return R.ok(true);
}
@GetMapping("/get")
@Operation(summary = "获得 Banner")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:banner:query")
public R<BannerRespVO> getBanner(@RequestParam("id") Long id) {
BannerDO banner = bannerService.getBanner(id);
return R.ok(BannerConvert.INSTANCE.convert(banner));
}
@GetMapping("/page")
@Operation(summary = "获得 Banner 分页")
@SaCheckPermission("promotion:banner:query")
public R<PageResult<BannerRespVO>> getBannerPage(@Valid BannerPageReqVO pageVO) {
PageResult<BannerDO> pageResult = bannerService.getBannerPage(pageVO);
return R.ok(BannerConvert.INSTANCE.convertPage(pageResult));
}
}
package org.dromara.mall.controller.promotion.admin.banner.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.dromara.common.mall.enums.CommonStatusEnum;
import org.dromara.common.mall.validation.InEnum;
import org.dromara.mall.enums.promotion.banner.BannerPositionEnum;
/**
* Banner Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
* @author xia
*/
@Data
public class BannerBaseVO {
@Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "标题不能为空")
private String title;
@Schema(description = "跳转链接", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "跳转链接不能为空")
private String url;
@Schema(description = "图片地址", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "图片地址不能为空")
private String picUrl;
@Schema(description = "position", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "position 不能为空")
@InEnum(BannerPositionEnum.class)
private Integer position;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "排序不能为空")
private Integer sort;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "状态不能为空")
@InEnum(CommonStatusEnum.class)
private Integer status;
@Schema(description = "备注")
private String memo;
}
package org.dromara.mall.controller.promotion.admin.banner.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* @author xia
*/
@Schema(description = "管理后台 - Banner 创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BannerCreateReqVO extends BannerBaseVO {
}
package org.dromara.mall.controller.promotion.admin.banner.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.dromara.common.mall.enums.CommonStatusEnum;
import org.dromara.common.mall.validation.InEnum;
import org.dromara.common.mybatis.core.page.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - Banner 分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BannerPageReqVO extends PageParam {
@Schema(description = "标题", example = "这是一个标题")
private String title;
@Schema(description = "状态", example = "1")
@InEnum(CommonStatusEnum.class)
private Integer status;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@Schema(description = "创建时间")
private LocalDateTime[] createTime;
}
package org.dromara.mall.controller.promotion.admin.banner.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - Banner Response VO")
@Data
@ToString(callSuper = true)
public class BannerRespVO extends BannerBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED)
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-01 23:59:59")
private LocalDateTime createTime;
}
package org.dromara.mall.controller.promotion.admin.banner.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* @author xia
*/
@Schema(description = "管理后台 - Banner更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BannerUpdateReqVO extends BannerBaseVO {
@Schema(description = "banner 编号", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "banner 编号不能为空")
private Long id;
}
package org.dromara.mall.controller.promotion.admin.bargain;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.api.dto.product.ProductSpuRespDTO;
import org.dromara.mall.api.service.product.ProductSpuApi;
import org.dromara.mall.controller.promotion.admin.bargain.vo.activity.*;
import org.dromara.mall.convert.promotion.bargain.BargainActivityConvert;
import org.dromara.mall.domain.promotion.BargainActivityDO;
import org.dromara.mall.enums.promotion.bargain.BargainRecordStatusEnum;
import org.dromara.mall.service.promotion.BargainActivityService;
import org.dromara.mall.service.promotion.BargainHelpService;
import org.dromara.mall.service.promotion.BargainRecordService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import static org.dromara.common.mall.util.collection.CollectionUtils.convertList;
@Tag(name = "管理后台 - 砍价活动")
@RestController
@RequestMapping("/admin/promotion/bargain-activity")
@Validated
public class BargainActivityController {
@Resource
private BargainActivityService bargainActivityService;
@Resource
private BargainRecordService bargainRecordService;
@Resource
private BargainHelpService bargainHelpService;
@Resource
private ProductSpuApi spuApi;
@PostMapping("/create")
@Operation(summary = "创建砍价活动")
@SaCheckPermission("promotion:bargain-activity:create")
public R<Long> createBargainActivity(@Valid @RequestBody BargainActivityCreateReqVO createReqVO) {
return R.ok(bargainActivityService.createBargainActivity(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新砍价活动")
@SaCheckPermission("promotion:bargain-activity:update")
public R<Boolean> updateBargainActivity(@Valid @RequestBody BargainActivityUpdateReqVO updateReqVO) {
bargainActivityService.updateBargainActivity(updateReqVO);
return R.ok(true);
}
@PutMapping("/close")
@Operation(summary = "关闭砍价活动")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:bargain-activity:close")
public R<Boolean> closeSeckillActivity(@RequestParam("id") Long id) {
bargainActivityService.closeBargainActivityById(id);
return R.ok(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除砍价活动")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:bargain-activity:delete")
public R<Boolean> deleteBargainActivity(@RequestParam("id") Long id) {
bargainActivityService.deleteBargainActivity(id);
return R.ok(true);
}
@GetMapping("/get")
@Operation(summary = "获得砍价活动")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:bargain-activity:query")
public R<BargainActivityRespVO> getBargainActivity(@RequestParam("id") Long id) {
return R.ok(BargainActivityConvert.INSTANCE.convert(bargainActivityService.getBargainActivity(id)));
}
@GetMapping("/page")
@Operation(summary = "获得砍价活动分页")
@SaCheckPermission("promotion:bargain-activity:query")
public R<PageResult<BargainActivityPageItemRespVO>> getBargainActivityPage(
@Valid BargainActivityPageReqVO pageVO) {
// 查询砍价活动
PageResult<BargainActivityDO> pageResult = bargainActivityService.getBargainActivityPage(pageVO);
if (CollUtil.isEmpty(pageResult.getList())) {
return R.ok(PageResult.empty(pageResult.getTotal()));
}
// 拼接数据
List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(pageResult.getList(), BargainActivityDO::getSpuId));
// 统计数据
Collection<Long> activityIds = convertList(pageResult.getList(), BargainActivityDO::getId);
Map<Long, Integer> recordUserCountMap = bargainRecordService.getBargainRecordUserCountMap(activityIds, null);
Map<Long, Integer> recordSuccessUserCountMap = bargainRecordService.getBargainRecordUserCountMap(activityIds,
BargainRecordStatusEnum.SUCCESS.getStatus());
Map<Long, Integer> helpUserCountMap = bargainHelpService.getBargainHelpUserCountMapByActivity(activityIds);
return R.ok(BargainActivityConvert.INSTANCE.convertPage(pageResult, spuList,
recordUserCountMap, recordSuccessUserCountMap, helpUserCountMap));
}
}
package org.dromara.mall.controller.promotion.admin.bargain;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.api.dto.member.MemberUserRespDTO;
import org.dromara.mall.api.service.member.MemberUserApi;
import org.dromara.mall.controller.promotion.admin.bargain.vo.help.BargainHelpPageReqVO;
import org.dromara.mall.controller.promotion.admin.bargain.vo.help.BargainHelpRespVO;
import org.dromara.mall.convert.promotion.bargain.BargainHelpConvert;
import org.dromara.mall.domain.promotion.BargainHelpDO;
import org.dromara.mall.service.promotion.BargainHelpService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
import static org.dromara.common.mall.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - 砍价助力")
@RestController
@RequestMapping("/admin/promotion/bargain-help")
@Validated
public class BargainHelpController {
@Resource
private BargainHelpService bargainHelpService;
@Resource
private MemberUserApi memberUserApi;
@GetMapping("/page")
@Operation(summary = "获得砍价助力分页")
@SaCheckPermission("promotion:bargain-help:query")
public R<PageResult<BargainHelpRespVO>> getBargainHelpPage(@Valid BargainHelpPageReqVO pageVO) {
PageResult<BargainHelpDO> pageResult = bargainHelpService.getBargainHelpPage(pageVO);
if (CollUtil.isEmpty(pageResult.getList())) {
return R.ok(PageResult.empty(pageResult.getTotal()));
}
// 拼接数据
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(
convertSet(pageResult.getList(), BargainHelpDO::getUserId));
return R.ok(BargainHelpConvert.INSTANCE.convertPage(pageResult, userMap));
}
}
package org.dromara.mall.controller.promotion.admin.bargain;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.api.dto.member.MemberUserRespDTO;
import org.dromara.mall.api.service.member.MemberUserApi;
import org.dromara.mall.controller.promotion.admin.bargain.vo.recrod.BargainRecordPageItemRespVO;
import org.dromara.mall.controller.promotion.admin.bargain.vo.recrod.BargainRecordPageReqVO;
import org.dromara.mall.convert.promotion.bargain.BargainRecordConvert;
import org.dromara.mall.domain.promotion.BargainActivityDO;
import org.dromara.mall.domain.promotion.BargainRecordDO;
import org.dromara.mall.service.promotion.BargainActivityService;
import org.dromara.mall.service.promotion.BargainHelpService;
import org.dromara.mall.service.promotion.BargainRecordService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import static org.dromara.common.mall.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - 砍价记录")
@RestController
@RequestMapping("/admin/promotion/bargain-record")
@Validated
public class BargainRecordController {
@Resource
private BargainRecordService bargainRecordService;
@Resource
private BargainActivityService bargainActivityService;
@Resource
private BargainHelpService bargainHelpService;
@Resource
private MemberUserApi memberUserApi;
@GetMapping("/page")
@Operation(summary = "获得砍价记录分页")
@SaCheckPermission("promotion:bargain-record:query")
public R<PageResult<BargainRecordPageItemRespVO>> getBargainRecordPage(@Valid BargainRecordPageReqVO pageVO) {
PageResult<BargainRecordDO> pageResult = bargainRecordService.getBargainRecordPage(pageVO);
if (CollUtil.isEmpty(pageResult.getList())) {
return R.ok(PageResult.empty(pageResult.getTotal()));
}
// 拼接数据
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(
convertSet(pageResult.getList(), BargainRecordDO::getUserId));
List<BargainActivityDO> activityList = bargainActivityService.getBargainActivityList(
convertSet(pageResult.getList(), BargainRecordDO::getActivityId));
Map<Long, Integer> helpCountMap = bargainHelpService.getBargainHelpUserCountMapByRecord(
convertSet(pageResult.getList(), BargainRecordDO::getId));
return R.ok(BargainRecordConvert.INSTANCE.convertPage(pageResult, helpCountMap, activityList, userMap));
}
}
package org.dromara.mall.controller.promotion.admin.bargain.vo.activity;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 砍价活动 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*
* @author HUIHUI
*/
@Data
public class BargainActivityBaseVO {
@Schema(description = "砍价活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "砍得越多省得越多,是兄弟就来砍我")
@NotNull(message = "砍价名称不能为空")
private String name;
@Schema(description = "商品 SPU 编号", example = "1")
@NotNull(message = "砍价商品不能为空")
private Long spuId;
@Schema(description = "商品 skuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
@NotNull(message = "商品 skuId 不能为空")
private Long skuId;
@Schema(description = "砍价起始价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
@NotNull(message = "砍价起始价格不能为空")
private Integer bargainFirstPrice;
@Schema(description = "砍价底价", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
@NotNull(message = "砍价底价不能为空")
private Integer bargainMinPrice;
@Schema(description = "活动库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
@NotNull(message = "活动库存不能为空")
private Integer stock;
@Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "16218")
@NotNull(message = "总限购数量不能为空")
private Integer totalLimitCount;
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
@NotNull(message = "活动开始时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime startTime;
@Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
@NotNull(message = "活动结束时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime endTime;
@Schema(description = "最大助力次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
@NotNull(message = "最大助力次数不能为空")
private Integer helpMaxCount;
@Schema(description = "最大帮砍次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
@NotNull(message = "最大帮砍次数不能为空")
private Integer bargainCount;
@Schema(description = "用户每次砍价的最小金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
@NotNull(message = "用户每次砍价的最小金额不能为空")
private Integer randomMinPrice;
@Schema(description = "用户每次砍价的最大金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
@NotNull(message = "用户每次砍价的最大金额不能为空")
private Integer randomMaxPrice;
}
package org.dromara.mall.controller.promotion.admin.bargain.vo.activity;
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 BargainActivityCreateReqVO extends BargainActivityBaseVO {
}
package org.dromara.mall.controller.promotion.admin.bargain.vo.activity;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 砍价活动的分页项 Response VO")
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BargainActivityPageItemRespVO extends BargainActivityBaseVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
private Long id;
@Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618大促")
private String spuName;
@Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png")
private String picUrl;
@Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
@NotNull(message = "活动状态不能为空")
private Integer status;
@Schema(description = "活动总库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
private Integer totalStock;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-01 23:59:59")
private LocalDateTime createTime;
// ========== 统计字段 ==========
@Schema(description = "总砍价的用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "999")
private Integer recordUserCount;
@Schema(description = "成功砍价的用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "500")
private Integer recordSuccessUserCount;
@Schema(description = "帮助砍价的用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
private Integer helpUserCount;
}
package org.dromara.mall.controller.promotion.admin.bargain.vo.activity;
import org.dromara.common.mybatis.core.page.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 BargainActivityPageReqVO extends PageParam {
@Schema(description = "砍价名称", example = "赵六")
private String name;
@Schema(description = "活动状态", example = "0")
private Integer status;
}
package org.dromara.mall.controller.promotion.admin.bargain.vo.activity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 砍价活动 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BargainActivityRespVO extends BargainActivityBaseVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
private Long id;
@Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
private Integer status;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-01 23:59:59")
private LocalDateTime createTime;
}
package org.dromara.mall.controller.promotion.admin.bargain.vo.activity;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 砍价活动更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BargainActivityUpdateReqVO extends BargainActivityBaseVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
@NotNull(message = "活动编号不能为空")
private Long id;
}
package org.dromara.mall.controller.promotion.admin.bargain.vo.help;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 砍价助力 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class BargainHelpBaseVO {
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "5402")
private Long userId;
@Schema(description = "砍价活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "16825")
private Long activityId;
@Schema(description = "砍价记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1800")
private Long recordId;
@Schema(description = "减少砍价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "32300")
private Integer reducePrice;
}
package org.dromara.mall.controller.promotion.admin.bargain.vo.help;
import org.dromara.common.mybatis.core.page.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 BargainHelpPageReqVO extends PageParam {
@Schema(description = "砍价记录编号", example = "1800")
private Long recordId;
}
package org.dromara.mall.controller.promotion.admin.bargain.vo.help;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 砍价助力 Response VO")
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BargainHelpRespVO extends BargainHelpBaseVO {
@Schema(description = "砍价助力编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25860")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
// ========== 用户相关 ==========
@Schema(description = "用户昵称", example = "老芋艿")
private String nickname;
@Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xxx.jpg")
private String avatar;
}
package org.dromara.mall.controller.promotion.admin.bargain.vo.recrod;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 砍价记录 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class BargainRecordBaseVO {
@Schema(description = "砍价活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "22690")
@NotNull(message = "砍价活动名称不能为空")
private Long activityId;
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "9430")
@NotNull(message = "用户编号不能为空")
private Long userId;
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23622")
@NotNull(message = "商品 SPU 编号不能为空")
private Long spuId;
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29950")
@NotNull(message = "商品 SKU 编号不能为空")
private Long skuId;
@Schema(description = "砍价起始价格,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "31160")
@NotNull(message = "砍价起始价格,单位:分不能为空")
private Integer bargainFirstPrice;
@Schema(description = "当前砍价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "22743")
@NotNull(message = "当前砍价,单位:分不能为空")
private Integer bargainPrice;
@Schema(description = "砍价状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "砍价状态不能为空")
private Integer status;
@Schema(description = "订单编号", example = "27845")
private Long orderId;
@Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "结束时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime endTime;
}
package org.dromara.mall.controller.promotion.admin.bargain.vo.recrod;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.dromara.mall.controller.promotion.admin.bargain.vo.activity.BargainActivityRespVO;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 砍价记录的分页项 Response VO")
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BargainRecordPageItemRespVO extends BargainRecordBaseVO {
@Schema(description = "记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-01 23:59:59")
private LocalDateTime createTime;
@Schema(description = "帮砍次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
private Integer helpCount;
// ========== 用户相关 ==========
@Schema(description = "用户昵称", example = "老芋艿")
private String nickname;
@Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xxx.jpg")
private String avatar;
// ========== 活动相关 ==========
private BargainActivityRespVO activity;
}
package org.dromara.mall.controller.promotion.admin.bargain.vo.recrod;
import org.dromara.common.mybatis.core.page.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 org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 砍价记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BargainRecordPageReqVO extends PageParam {
@Schema(description = "砍价状态", example = "1")
private Integer status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
package org.dromara.mall.controller.promotion.admin.combination;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mall.enums.CommonStatusEnum;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.api.dto.product.ProductSpuRespDTO;
import org.dromara.mall.api.service.product.ProductSpuApi;
import org.dromara.mall.controller.promotion.admin.combination.vo.activity.*;
import org.dromara.mall.convert.promotion.combination.CombinationActivityConvert;
import org.dromara.mall.domain.promotion.CombinationActivityDO;
import org.dromara.mall.domain.promotion.CombinationProductDO;
import org.dromara.mall.domain.promotion.CombinationRecordDO;
import org.dromara.mall.enums.promotion.combination.CombinationRecordStatusEnum;
import org.dromara.mall.service.promotion.CombinationActivityService;
import org.dromara.mall.service.promotion.CombinationRecordService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static cn.hutool.core.collection.CollectionUtil.newArrayList;
import static org.dromara.common.mall.util.collection.CollectionUtils.convertList;
import static org.dromara.common.mall.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - 拼团活动")
@RestController
@RequestMapping("/admin/promotion/combination-activity")
@Validated
public class CombinationActivityController {
@Resource
private CombinationActivityService combinationActivityService;
@Resource
private CombinationRecordService combinationRecordService;
@Resource
private ProductSpuApi productSpuApi;
@PostMapping("/create")
@Operation(summary = "创建拼团活动")
@SaCheckPermission("promotion:combination-activity:create")
public R<Long> createCombinationActivity(@Valid @RequestBody CombinationActivityCreateReqVO createReqVO) {
return R.ok(combinationActivityService.createCombinationActivity(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新拼团活动")
@SaCheckPermission("promotion:combination-activity:update")
public R<Boolean> updateCombinationActivity(@Valid @RequestBody CombinationActivityUpdateReqVO updateReqVO) {
combinationActivityService.updateCombinationActivity(updateReqVO);
return R.ok(true);
}
@PutMapping("/close")
@Operation(summary = "关闭拼团活动")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:combination-activity:close")
public R<Boolean> closeCombinationActivity(@RequestParam("id") Long id) {
combinationActivityService.closeCombinationActivityById(id);
return R.ok(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除拼团活动")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:combination-activity:delete")
public R<Boolean> deleteCombinationActivity(@RequestParam("id") Long id) {
combinationActivityService.deleteCombinationActivity(id);
return R.ok(true);
}
@GetMapping("/get")
@Operation(summary = "获得拼团活动")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:combination-activity:query")
public R<CombinationActivityRespVO> getCombinationActivity(@RequestParam("id") Long id) {
CombinationActivityDO activity = combinationActivityService.getCombinationActivity(id);
List<CombinationProductDO> products = combinationActivityService.getCombinationProductListByActivityIds(newArrayList(id));
return R.ok(CombinationActivityConvert.INSTANCE.convert(activity, products));
}
@GetMapping("/list-by-ids")
@Operation(summary = "获得拼团活动列表,基于活动编号数组")
@Parameter(name = "ids", description = "活动编号数组", required = true, example = "[1024, 1025]")
public R<List<CombinationActivityRespVO>> getCombinationActivityListByIds(@RequestParam("ids") List<Long> ids) {
// 1. 获得开启的活动列表
List<CombinationActivityDO> activityList = combinationActivityService.getCombinationActivityListByIds(ids);
activityList.removeIf(activity -> CommonStatusEnum.isDisable(activity.getStatus()));
if (CollUtil.isEmpty(activityList)) {
return R.ok(Collections.emptyList());
}
// 2. 拼接返回
List<CombinationProductDO> productList = combinationActivityService.getCombinationProductListByActivityIds(
convertList(activityList, CombinationActivityDO::getId));
List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(convertList(activityList, CombinationActivityDO::getSpuId));
return R.ok(CombinationActivityConvert.INSTANCE.convertList(activityList, productList, spuList));
}
@GetMapping("/page")
@Operation(summary = "获得拼团活动分页")
@SaCheckPermission("promotion:combination-activity:query")
public R<PageResult<CombinationActivityPageItemRespVO>> getCombinationActivityPage(
@Valid CombinationActivityPageReqVO pageVO) {
// 查询拼团活动
PageResult<CombinationActivityDO> pageResult = combinationActivityService.getCombinationActivityPage(pageVO);
if (CollUtil.isEmpty(pageResult.getList())) {
return R.ok(PageResult.empty(pageResult.getTotal()));
}
// 统计数据
Set<Long> activityIds = convertSet(pageResult.getList(), CombinationActivityDO::getId);
Map<Long, Integer> groupCountMap = combinationRecordService.getCombinationRecordCountMapByActivity(
activityIds, null, CombinationRecordDO.HEAD_ID_GROUP);
Map<Long, Integer> groupSuccessCountMap = combinationRecordService.getCombinationRecordCountMapByActivity(
activityIds, CombinationRecordStatusEnum.SUCCESS.getStatus(), CombinationRecordDO.HEAD_ID_GROUP);
Map<Long, Integer> recordCountMap = combinationRecordService.getCombinationRecordCountMapByActivity(
activityIds, null, null);
// 拼接数据
List<CombinationProductDO> products = combinationActivityService.getCombinationProductListByActivityIds(
convertSet(pageResult.getList(), CombinationActivityDO::getId));
List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(
convertSet(pageResult.getList(), CombinationActivityDO::getSpuId));
return R.ok(CombinationActivityConvert.INSTANCE.convertPage(pageResult, products,
groupCountMap, groupSuccessCountMap, recordCountMap, spus));
}
}
package org.dromara.mall.controller.promotion.admin.combination;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.controller.promotion.admin.combination.vo.recrod.CombinationRecordPageItemRespVO;
import org.dromara.mall.controller.promotion.admin.combination.vo.recrod.CombinationRecordReqPageVO;
import org.dromara.mall.controller.promotion.admin.combination.vo.recrod.CombinationRecordSummaryVO;
import org.dromara.mall.convert.promotion.combination.CombinationActivityConvert;
import org.dromara.mall.domain.promotion.CombinationActivityDO;
import org.dromara.mall.domain.promotion.CombinationProductDO;
import org.dromara.mall.domain.promotion.CombinationRecordDO;
import org.dromara.mall.enums.promotion.combination.CombinationRecordStatusEnum;
import org.dromara.mall.service.promotion.CombinationActivityService;
import org.dromara.mall.service.promotion.CombinationRecordService;
import org.springframework.context.annotation.Lazy;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static org.dromara.common.mall.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - 拼团记录")
@RestController
@RequestMapping("/admin/promotion/combination-record")
@Validated
public class CombinationRecordController {
@Resource
private CombinationActivityService combinationActivityService;
@Resource
@Lazy
private CombinationRecordService combinationRecordService;
@GetMapping("/page")
@Operation(summary = "获得拼团记录分页")
@SaCheckPermission("promotion:combination-record:query")
public R<PageResult<CombinationRecordPageItemRespVO>> getCombinationRecordPage(
@Valid CombinationRecordReqPageVO pageVO) {
PageResult<CombinationRecordDO> recordPage = combinationRecordService.getCombinationRecordPage(pageVO);
// 拼接数据
List<CombinationActivityDO> activities = combinationActivityService.getCombinationActivityListByIds(
convertSet(recordPage.getList(), CombinationRecordDO::getActivityId));
List<CombinationProductDO> products = combinationActivityService.getCombinationProductListByActivityIds(
convertSet(recordPage.getList(), CombinationRecordDO::getActivityId));
return R.ok(CombinationActivityConvert.INSTANCE.convert(recordPage, activities, products));
}
@GetMapping("/get-summary")
@Operation(summary = "获得拼团记录的概要信息", description = "用于拼团记录页面展示")
@SaCheckPermission("promotion:combination-record:query")
public R<CombinationRecordSummaryVO> getCombinationRecordSummary() {
CombinationRecordSummaryVO summaryVO = new CombinationRecordSummaryVO();
summaryVO.setUserCount(combinationRecordService.getCombinationUserCount()); // 获取拼团用户参与数量
summaryVO.setSuccessCount(combinationRecordService.getCombinationRecordCount( // 获取成团记录
CombinationRecordStatusEnum.SUCCESS.getStatus(), null, CombinationRecordDO.HEAD_ID_GROUP));
summaryVO.setVirtualGroupCount(combinationRecordService.getCombinationRecordCount(// 获取虚拟成团记录
null, Boolean.TRUE, CombinationRecordDO.HEAD_ID_GROUP));
return R.ok(summaryVO);
}
}
package org.dromara.mall.controller.promotion.admin.combination.vo.activity;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 拼团活动 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*
* @author HUIHUI
*/
@Data
@Accessors(chain = true)
public class CombinationActivityBaseVO {
@Schema(description = "拼团名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "越拼越省钱")
@NotNull(message = "拼团名称不能为空")
private String name;
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "拼团商品不能为空")
private Long spuId;
@Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "16218")
@NotNull(message = "总限购数量不能为空")
private Integer totalLimitCount;
@Schema(description = "单次限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "28265")
@NotNull(message = "单次限购数量不能为空")
private Integer singleLimitCount;
@Schema(description = "活动时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
@NotNull(message = "活动时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime startTime;
@Schema(description = "活动时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
@NotNull(message = "活动时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime endTime;
@Schema(description = "开团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
@NotNull(message = "开团人数不能为空")
private Integer userSize;
@Schema(description = "虚拟成团", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
@NotNull(message = "虚拟成团不能为空")
private Boolean virtualGroup;
@Schema(description = "限制时长(小时)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "限制时长不能为空")
private Integer limitDuration;
}
package org.dromara.mall.controller.promotion.admin.combination.vo.activity;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.dromara.mall.controller.promotion.admin.combination.vo.product.CombinationProductBaseVO;
import java.util.List;
@Schema(description = "管理后台 - 拼团活动创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CombinationActivityCreateReqVO extends CombinationActivityBaseVO {
@Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
@Valid
private List<CombinationProductBaseVO> products;
}
package org.dromara.mall.controller.promotion.admin.combination.vo.activity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.dromara.mall.controller.promotion.admin.combination.vo.product.CombinationProductRespVO;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 拼团活动的分页项 Response VO")
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CombinationActivityPageItemRespVO extends CombinationActivityBaseVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
private Integer status;
@Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
private List<CombinationProductRespVO> products;
// ========== 商品字段 ==========
@Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 name 读取
example = "618大促")
private String spuName;
@Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 picUrl 读取
example = "https://www.iocoder.cn/xx.png")
private String picUrl;
@Schema(description = "商品市场价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 marketPrice 读取
example = "50")
private Integer marketPrice;
// ========== 统计字段 ==========
@Schema(description = "开团组数", requiredMode = Schema.RequiredMode.REQUIRED, example = "33")
private Integer groupCount;
@Schema(description = "成团组数", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
private Integer groupSuccessCount;
@Schema(description = "购买次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private Integer recordCount;
}
package org.dromara.mall.controller.promotion.admin.combination.vo.activity;
import org.dromara.common.mybatis.core.page.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 CombinationActivityPageReqVO extends PageParam {
@Schema(description = "拼团名称", example = "赵六")
private String name;
@Schema(description = "活动状态", example = "0")
private Integer status;
}
package org.dromara.mall.controller.promotion.admin.combination.vo.activity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.dromara.mall.controller.promotion.admin.combination.vo.product.CombinationProductRespVO;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 拼团活动 Response VO")
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CombinationActivityRespVO extends CombinationActivityBaseVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "开团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "666")
private Integer userSize;
@Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
private List<CombinationProductRespVO> products;
@Schema(description = "商品 SPU 名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "一个白菜")
private String spuName; // 从 SPU 的 name 读取
@Schema(description = "商品图片", requiredMode = Schema.RequiredMode.REQUIRED, example = "4096")
private String picUrl; // 从 SPU 的 picUrl 读取
@Schema(description = "商品市场价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
private Integer marketPrice; // 从 SPU 的 marketPrice 读取
@Schema(description = "拼团金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private Integer combinationPrice; // 从 products 获取最小 price 读取
}
package org.dromara.mall.controller.promotion.admin.combination.vo.activity;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.dromara.mall.controller.promotion.admin.combination.vo.product.CombinationProductBaseVO;
import java.util.List;
@Schema(description = "管理后台 - 拼团活动更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CombinationActivityUpdateReqVO extends CombinationActivityBaseVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
@NotNull(message = "活动编号不能为空")
private Long id;
@Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
@Valid
private List<CombinationProductBaseVO> products;
}
package org.dromara.mall.controller.promotion.admin.combination.vo.product;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* 拼团商品 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class CombinationProductBaseVO {
@Schema(description = "商品 spuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
@NotNull(message = "商品 spuId 不能为空")
private Long spuId;
@Schema(description = "商品 skuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
@NotNull(message = "商品 skuId 不能为空")
private Long skuId;
@Schema(description = "拼团价格,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "27682")
@NotNull(message = "拼团价格不能为空")
private Integer combinationPrice;
}
package org.dromara.mall.controller.promotion.admin.combination.vo.product;
import org.dromara.common.mybatis.core.page.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 org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 拼团商品分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CombinationProductPageReqVO extends PageParam {
@Schema(description = "拼团活动编号", example = "6829")
private Long activityId;
@Schema(description = "商品 SPU 编号", example = "18731")
private Long spuId;
@Schema(description = "商品 SKU 编号", example = "31675")
private Long skuId;
@Schema(description = "拼团商品状态", example = "2")
private Integer activityStatus;
@Schema(description = "活动开始时间点")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] activityStartTime;
@Schema(description = "活动结束时间点")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] activityEndTime;
@Schema(description = "拼团价格,单位分", example = "27682")
private Integer activePrice;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
package org.dromara.mall.controller.promotion.admin.combination.vo.product;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 拼团商品 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CombinationProductRespVO extends CombinationProductBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28322")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}
package org.dromara.mall.controller.promotion.admin.combination.vo.recrod;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 拼团记录 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*
* @author HUIHUI
*/
@Data
public class CombinationRecordBaseVO {
@Schema(description = "拼团记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "拼团活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long activityId;
@Schema(description = "团长编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long headId;
// ========== 用户相关 ==========
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "9430")
@NotNull(message = "用户编号不能为空")
private Long userId;
@Schema(description = "用户昵称", example = "老芋艿")
private String nickname;
@Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xxx.jpg")
private String avatar;
// ========== 商品相关 ==========
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23622")
@NotNull(message = "商品 SPU 编号不能为空")
private Long spuId;
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29950")
@NotNull(message = "商品 SKU 编号不能为空")
private Long skuId;
@Schema(description = "商品名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是大黄豆")
private String spuName;
@Schema(description = "商品图片", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
private String picUrl;
@Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime expireTime;
@Schema(description = "可参团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
private Integer userSize;
@Schema(description = "已参团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
private Integer userCount;
@Schema(description = "拼团状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "是否虚拟成团", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
private Boolean virtualGroup;
@Schema(description = "开始时间 (订单付款后开始的时间)", requiredMode = Schema.RequiredMode.REQUIRED)
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime startTime;
@Schema(description = "结束时间(成团时间/失败时间)", requiredMode = Schema.RequiredMode.REQUIRED)
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime endTime;
}
package org.dromara.mall.controller.promotion.admin.combination.vo.recrod;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.dromara.mall.controller.promotion.admin.combination.vo.activity.CombinationActivityRespVO;
@Schema(description = "管理后台 - 拼团记录的分页项 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CombinationRecordPageItemRespVO extends CombinationRecordBaseVO {
// ========== 活动相关 ==========
private CombinationActivityRespVO activity;
}
package org.dromara.mall.controller.promotion.admin.combination.vo.recrod;
import org.dromara.common.mybatis.core.page.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 拼团记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CombinationRecordReqPage2VO extends PageParam {
@Schema(description = "团长编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "团长编号不能为空")
private Long headId;
}
package org.dromara.mall.controller.promotion.admin.combination.vo.recrod;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.dromara.common.mall.validation.InEnum;
import org.dromara.common.mybatis.core.page.PageParam;
import org.dromara.mall.enums.promotion.combination.CombinationRecordStatusEnum;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 拼团记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CombinationRecordReqPageVO extends PageParam {
@Schema(description = "活动状态", example = "1")
@InEnum(CombinationRecordStatusEnum.class)
private Integer status;
@Schema(description = "团长编号", example = "1024")
private Long headId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
package org.dromara.mall.controller.promotion.admin.combination.vo.recrod;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 拼团记录信息统计 Response VO")
@Data
public class CombinationRecordSummaryVO {
@Schema(description = "所有拼团记录", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long userCount;
@Schema(description = "成团记录", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long successCount;
@Schema(description = "虚拟成团记录", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long virtualGroupCount;
}
package org.dromara.mall.controller.promotion.admin.coupon;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mall.util.collection.MapUtils;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.api.dto.member.MemberUserRespDTO;
import org.dromara.mall.api.service.member.MemberUserApi;
import org.dromara.mall.controller.promotion.admin.coupon.vo.coupon.CouponPageItemRespVO;
import org.dromara.mall.controller.promotion.admin.coupon.vo.coupon.CouponPageReqVO;
import org.dromara.mall.controller.promotion.admin.coupon.vo.coupon.CouponSendReqVO;
import org.dromara.mall.convert.promotion.coupon.CouponConvert;
import org.dromara.mall.domain.promotion.CouponDO;
import org.dromara.mall.service.promotion.CouponService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import static org.dromara.common.mall.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - 优惠劵")
@RestController
@RequestMapping("/admin/promotion/coupon")
@Validated
public class CouponController {
@Resource
private CouponService couponService;
@Resource
private MemberUserApi memberUserApi;
@DeleteMapping("/delete")
@Operation(summary = "回收优惠劵")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:coupon:delete")
public R<Boolean> deleteCoupon(@RequestParam("id") Long id) {
couponService.deleteCoupon(id);
return R.ok(true);
}
@GetMapping("/page")
@Operation(summary = "获得优惠劵分页")
@SaCheckPermission("promotion:coupon:query")
public R<PageResult<CouponPageItemRespVO>> getCouponPage(@Valid CouponPageReqVO pageVO) {
PageResult<CouponDO> pageResult = couponService.getCouponPage(pageVO);
PageResult<CouponPageItemRespVO> pageResulVO = CouponConvert.INSTANCE.convertPage(pageResult);
if (CollUtil.isEmpty(pageResulVO.getList())) {
return R.ok(pageResulVO);
}
// 读取用户信息,进行拼接
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(convertSet(pageResult.getList(), CouponDO::getUserId));
pageResulVO.getList().forEach(itemRespVO -> MapUtils.findAndThen(userMap, itemRespVO.getUserId(),
userRespDTO -> itemRespVO.setNickname(userRespDTO.getNickname())));
return R.ok(pageResulVO);
}
@PostMapping("/send")
@Operation(summary = "发送优惠劵")
@SaCheckPermission("promotion:coupon:send")
public R<Boolean> sendCoupon(@Valid @RequestBody CouponSendReqVO reqVO) {
couponService.takeCouponByAdmin(reqVO.getTemplateId(), reqVO.getUserIds());
return R.ok(true);
}
}
package org.dromara.mall.controller.promotion.admin.coupon;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.controller.promotion.admin.coupon.vo.template.*;
import org.dromara.mall.convert.promotion.coupon.CouponTemplateConvert;
import org.dromara.mall.domain.promotion.CouponTemplateDO;
import org.dromara.mall.service.promotion.CouponTemplateService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.List;
@Tag(name = "管理后台 - 优惠劵模板")
@RestController
@RequestMapping("/admin/promotion/coupon-template")
@Validated
public class CouponTemplateController {
@Resource
private CouponTemplateService couponTemplateService;
@PostMapping("/create")
@Operation(summary = "创建优惠劵模板")
@SaCheckPermission("promotion:coupon-template:create")
public R<Long> createCouponTemplate(@Valid @RequestBody CouponTemplateCreateReqVO createReqVO) {
return R.ok(couponTemplateService.createCouponTemplate(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新优惠劵模板")
@SaCheckPermission("promotion:coupon-template:update")
public R<Boolean> updateCouponTemplate(@Valid @RequestBody CouponTemplateUpdateReqVO updateReqVO) {
couponTemplateService.updateCouponTemplate(updateReqVO);
return R.ok(true);
}
@PutMapping("/update-status")
@Operation(summary = "更新优惠劵模板状态")
@SaCheckPermission("promotion:coupon-template:update")
public R<Boolean> updateCouponTemplateStatus(@Valid @RequestBody CouponTemplateUpdateStatusReqVO reqVO) {
couponTemplateService.updateCouponTemplateStatus(reqVO.getId(), reqVO.getStatus());
return R.ok(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除优惠劵模板")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:coupon-template:delete")
public R<Boolean> deleteCouponTemplate(@RequestParam("id") Long id) {
couponTemplateService.deleteCouponTemplate(id);
return R.ok(true);
}
@GetMapping("/get")
@Operation(summary = "获得优惠劵模板")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:coupon-template:query")
public R<CouponTemplateRespVO> getCouponTemplate(@RequestParam("id") Long id) {
CouponTemplateDO couponTemplate = couponTemplateService.getCouponTemplate(id);
return R.ok(CouponTemplateConvert.INSTANCE.convert(couponTemplate));
}
@GetMapping("/page")
@Operation(summary = "获得优惠劵模板分页")
@SaCheckPermission("promotion:coupon-template:query")
public R<PageResult<CouponTemplateRespVO>> getCouponTemplatePage(@Valid CouponTemplatePageReqVO pageVO) {
PageResult<CouponTemplateDO> pageResult = couponTemplateService.getCouponTemplatePage(pageVO);
return R.ok(CouponTemplateConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/list")
@Operation(summary = "获得优惠劵模板列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@SaCheckPermission("promotion:coupon-template:query")
public R<List<CouponTemplateRespVO>> getCouponTemplateList(@RequestParam("ids") Collection<Long> ids) {
List<CouponTemplateDO> list = couponTemplateService.getCouponTemplateList(ids);
return R.ok(CouponTemplateConvert.INSTANCE.convertList(list));
}
}
package org.dromara.mall.controller.promotion.admin.coupon.vo.coupon;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.dromara.common.mall.validation.InEnum;
import org.dromara.mall.enums.promotion.common.PromotionDiscountTypeEnum;
import org.dromara.mall.enums.promotion.common.PromotionProductScopeEnum;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.List;
import static org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
import static org.dromara.common.mall.util.date.DateUtils.TIME_ZONE_DEFAULT;
/**
* 优惠劵 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class CouponBaseVO {
// ========== 基本信息 BEGIN ==========
@Schema(description = "优惠劵模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "优惠劵模板编号不能为空")
private Long templateId;
@Schema(description = "优惠劵名", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节送送送")
@NotNull(message = "优惠劵名不能为空")
private String name;
@Schema(description = "优惠码状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
// ========== 基本信息 END ==========
// ========== 领取情况 BEGIN ==========
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "用户编号不能为空")
private Long userId;
@Schema(description = "领取方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "领取方式不能为空")
private Integer takeType;
// ========== 领取情况 END ==========
// ========== 使用规则 BEGIN ==========
@Schema(description = "是否设置满多少金额可用", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") // 单位:分;0 - 不限制
@NotNull(message = "是否设置满多少金额可用不能为空")
private Integer usePrice;
@Schema(description = "固定日期 - 生效开始时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
private LocalDateTime validStartTime;
@Schema(description = "固定日期 - 生效结束时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
private LocalDateTime validEndTime;
@Schema(description = "商品范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "商品范围不能为空")
@InEnum(PromotionProductScopeEnum.class)
private Integer productScope;
@Schema(description = "商品范围编号的数组", example = "1,3")
private List<Long> productScopeValues;
// ========== 使用规则 END ==========
// ========== 使用效果 BEGIN ==========
@Schema(description = "优惠类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "优惠类型不能为空")
@InEnum(PromotionDiscountTypeEnum.class)
private Integer discountType;
@Schema(description = "折扣百分比", example = "80") // 例如说,80% 为 80
private Integer discountPercent;
@Schema(description = "优惠金额", example = "10")
@Min(value = 0, message = "优惠金额需要大于等于 0")
private Integer discountPrice;
@Schema(description = "折扣上限", example = "100") // 单位:分,仅在 discountType 为 PERCENT 使用
private Integer discountLimitPrice;
// ========== 使用效果 END ==========
// ========== 使用情况 BEGIN ==========
@Schema(description = "使用订单号", example = "4096")
private Long useOrderId;
@Schema(description = "使用时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
private LocalDateTime useTime;
// ========== 使用情况 END ==========
}
package org.dromara.mall.controller.promotion.admin.coupon.vo.coupon;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 优惠劵分页的每一项 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CouponPageItemRespVO extends CouponRespVO {
@Schema(description = "用户昵称", example = "老芋艿")
private String nickname;
}
package org.dromara.mall.controller.promotion.admin.coupon.vo.coupon;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.dromara.common.mall.validation.InEnum;
import org.dromara.common.mybatis.core.page.PageParam;
import org.dromara.mall.enums.promotion.coupon.CouponStatusEnum;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.Collection;
import static org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 优惠劵分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CouponPageReqVO extends PageParam {
@Schema(description = "优惠劵模板编号", example = "2048")
private Long templateId;
@Schema(description = "优惠码状态", example = "1")
@InEnum(value = CouponStatusEnum.class, message = "优惠劵状态,必须是 {value}")
private Integer status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "用户昵称", example = "芋艿")
private String nickname;
@Schema(description = "用户编号", example = "1")
private Collection<Long> userIds;
}
package org.dromara.mall.controller.promotion.admin.coupon.vo.coupon;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 优惠劵 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CouponRespVO extends CouponBaseVO {
@Schema(description = "优惠劵编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}
package org.dromara.mall.controller.promotion.admin.coupon.vo.coupon;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.ToString;
import java.util.Set;
@Schema(description = "管理后台 - 优惠劵发放 Request VO")
@Data
@ToString(callSuper = true)
public class CouponSendReqVO {
@Schema(description = "优惠劵模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "优惠劵模板编号不能为空")
private Long templateId;
@Schema(description = "用户编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2]")
@NotEmpty(message = "用户编号列表不能为空")
private Set<Long> userIds;
}
package org.dromara.mall.controller.promotion.admin.coupon.vo.template;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.dromara.common.mall.validation.InEnum;
import org.dromara.mall.enums.promotion.common.PromotionDiscountTypeEnum;
import org.dromara.mall.enums.promotion.common.PromotionProductScopeEnum;
import org.dromara.mall.enums.promotion.coupon.CouponTemplateValidityTypeEnum;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import static org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
import static org.dromara.common.mall.util.date.DateUtils.TIME_ZONE_DEFAULT;
/**
* 优惠劵模板 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class CouponTemplateBaseVO {
@Schema(description = "优惠劵名", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节送送送")
@NotNull(message = "优惠劵名不能为空")
private String name;
@Schema(description = "优惠券说明", example = "优惠券使用说明")
private String description;
@Schema(description = "发行总量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") // -1 - 则表示不限制发放数量
@NotNull(message = "发行总量不能为空")
private Integer totalCount;
@Schema(description = "每人限领个数", requiredMode = Schema.RequiredMode.REQUIRED, example = "66") // -1 - 则表示不限制
@NotNull(message = "每人限领个数不能为空")
private Integer takeLimitCount;
@Schema(description = "领取方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "领取方式不能为空")
private Integer takeType;
@Schema(description = "是否设置满多少金额可用", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") // 单位:分;0 - 不限制
@NotNull(message = "是否设置满多少金额可用不能为空")
private Integer usePrice;
@Schema(description = "商品范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "商品范围不能为空")
@InEnum(PromotionProductScopeEnum.class)
private Integer productScope;
@Schema(description = "商品范围编号的数组", example = "[1, 3]")
private List<Long> productScopeValues;
@Schema(description = "生效日期类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "生效日期类型不能为空")
@InEnum(CouponTemplateValidityTypeEnum.class)
private Integer validityType;
@Schema(description = "固定日期 - 生效开始时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
private LocalDateTime validStartTime;
@Schema(description = "固定日期 - 生效结束时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
private LocalDateTime validEndTime;
@Schema(description = "领取日期 - 开始天数")
@Min(value = 0L, message = "开始天数必须大于 0")
private Integer fixedStartTerm;
@Schema(description = "领取日期 - 结束天数")
@Min(value = 1L, message = "开始天数必须大于 1")
private Integer fixedEndTerm;
@Schema(description = "优惠类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "优惠类型不能为空")
@InEnum(PromotionDiscountTypeEnum.class)
private Integer discountType;
@Schema(description = "折扣百分比", example = "80") // 例如说,80% 为 80
private Integer discountPercent;
@Schema(description = "优惠金额", example = "10")
@Min(value = 0, message = "优惠金额需要大于等于 0")
private Integer discountPrice;
@Schema(description = "折扣上限", example = "100") // 单位:分,仅在 discountType 为 PERCENT 使用
private Integer discountLimitPrice;
@AssertTrue(message = "商品范围编号的数组不能为空")
@JsonIgnore
public boolean isProductScopeValuesValid() {
return Objects.equals(productScope, PromotionProductScopeEnum.ALL.getScope()) // 全部范围时,可以为空
|| CollUtil.isNotEmpty(productScopeValues);
}
@AssertTrue(message = "生效开始时间不能为空")
@JsonIgnore
public boolean isValidStartTimeValid() {
return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.DATE.getType())
|| validStartTime != null;
}
@AssertTrue(message = "生效结束时间不能为空")
@JsonIgnore
public boolean isValidEndTimeValid() {
return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.DATE.getType())
|| validEndTime != null;
}
@AssertTrue(message = "开始天数不能为空")
@JsonIgnore
public boolean isFixedStartTermValid() {
return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.TERM.getType())
|| fixedStartTerm != null;
}
@AssertTrue(message = "结束天数不能为空")
@JsonIgnore
public boolean isFixedEndTermValid() {
return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.TERM.getType())
|| fixedEndTerm != null;
}
@AssertTrue(message = "折扣百分比需要大于等于 1,小于等于 99")
@JsonIgnore
public boolean isDiscountPercentValid() {
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType())
|| (discountPercent != null && discountPercent >= 1 && discountPercent<= 99);
}
@AssertTrue(message = "优惠金额不能为空")
@JsonIgnore
public boolean isDiscountPriceValid() {
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PRICE.getType())
|| discountPrice != null;
}
@AssertTrue(message = "折扣上限不能为空")
@JsonIgnore
public boolean isDiscountLimitPriceValid() {
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType())
|| discountLimitPrice != null;
}
}
package org.dromara.mall.controller.promotion.admin.coupon.vo.template;
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 CouponTemplateCreateReqVO extends CouponTemplateBaseVO {
}
package org.dromara.mall.controller.promotion.admin.coupon.vo.template;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.dromara.common.mall.validation.InEnum;
import org.dromara.common.mybatis.core.page.PageParam;
import org.dromara.mall.enums.promotion.common.PromotionProductScopeEnum;
import org.dromara.mall.enums.promotion.coupon.CouponTakeTypeEnum;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.List;
import static org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 优惠劵模板分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CouponTemplatePageReqVO extends PageParam {
@Schema(description = "优惠劵名", example = "你好")
private String name;
@Schema(description = "状态", example = "1")
private Integer status;
@Schema(description = "优惠类型", example = "1")
private Integer discountType;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "可以领取的类型", example = "[1, 2, 3]")
@InEnum(value = CouponTakeTypeEnum.class, message = "可以领取的类型,必须是 {value}")
private List<Integer> canTakeTypes;
@Schema(description = "商品范围", example = "1")
@InEnum(value = PromotionProductScopeEnum.class, message = "商品范围,必须是 {value}")
private Integer productScope;
@Schema(description = "商品范围编号", example = "1")
private Long productScopeValue;
}
package org.dromara.mall.controller.promotion.admin.coupon.vo.template;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.dromara.common.mall.enums.CommonStatusEnum;
import org.dromara.common.mall.validation.InEnum;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 优惠劵模板 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CouponTemplateRespVO extends CouponTemplateBaseVO {
@Schema(description = "模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@InEnum(CommonStatusEnum.class)
private Integer status;
@Schema(description = "领取优惠券的数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer takeCount;
@Schema(description = "使用优惠券的次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
private Integer useCount;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}
package org.dromara.mall.controller.promotion.admin.coupon.vo.template;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 优惠劵模板更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CouponTemplateUpdateReqVO extends CouponTemplateBaseVO {
@Schema(description = "模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "模板编号不能为空")
private Long id;
}
package org.dromara.mall.controller.promotion.admin.coupon.vo.template;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.dromara.common.mall.enums.CommonStatusEnum;
import org.dromara.common.mall.validation.InEnum;
@Schema(description = "管理后台 - 优惠劵模板更新状态 Request VO")
@Data
public class CouponTemplateUpdateStatusReqVO {
@Schema(description = "优惠劵模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "优惠劵模板编号不能为空")
private Long id;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}
package org.dromara.mall.controller.promotion.admin.discount;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.controller.promotion.admin.discount.vo.DiscountActivityCreateReqVO;
import org.dromara.mall.controller.promotion.admin.discount.vo.DiscountActivityPageReqVO;
import org.dromara.mall.controller.promotion.admin.discount.vo.DiscountActivityRespVO;
import org.dromara.mall.controller.promotion.admin.discount.vo.DiscountActivityUpdateReqVO;
import org.dromara.mall.convert.promotion.discount.DiscountActivityConvert;
import org.dromara.mall.domain.promotion.DiscountActivityDO;
import org.dromara.mall.domain.promotion.DiscountProductDO;
import org.dromara.mall.service.promotion.DiscountActivityService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import static org.dromara.common.mall.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - 限时折扣活动")
@RestController
@RequestMapping("/admin/promotion/discount-activity")
@Validated
public class DiscountActivityController {
@Resource
private DiscountActivityService discountActivityService;
@PostMapping("/create")
@Operation(summary = "创建限时折扣活动")
@SaCheckPermission("promotion:discount-activity:create")
public R<Long> createDiscountActivity(@Valid @RequestBody DiscountActivityCreateReqVO createReqVO) {
return R.ok(discountActivityService.createDiscountActivity(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新限时折扣活动")
@SaCheckPermission("promotion:discount-activity:update")
public R<Boolean> updateDiscountActivity(@Valid @RequestBody DiscountActivityUpdateReqVO updateReqVO) {
discountActivityService.updateDiscountActivity(updateReqVO);
return R.ok(true);
}
@PutMapping("/close")
@Operation(summary = "关闭限时折扣活动")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:discount-activity:close")
public R<Boolean> closeRewardActivity(@RequestParam("id") Long id) {
discountActivityService.closeDiscountActivity(id);
return R.ok(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除限时折扣活动")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:discount-activity:delete")
public R<Boolean> deleteDiscountActivity(@RequestParam("id") Long id) {
discountActivityService.deleteDiscountActivity(id);
return R.ok(true);
}
@GetMapping("/get")
@Operation(summary = "获得限时折扣活动")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:discount-activity:query")
public R<DiscountActivityRespVO> getDiscountActivity(@RequestParam("id") Long id) {
DiscountActivityDO discountActivity = discountActivityService.getDiscountActivity(id);
if (discountActivity == null) {
return R.ok(null);
}
// 拼接结果
List<DiscountProductDO> discountProducts = discountActivityService.getDiscountProductsByActivityId(id);
return R.ok(DiscountActivityConvert.INSTANCE.convert(discountActivity, discountProducts));
}
@GetMapping("/page")
@Operation(summary = "获得限时折扣活动分页")
@SaCheckPermission("promotion:discount-activity:query")
public R<PageResult<DiscountActivityRespVO>> getDiscountActivityPage(@Valid DiscountActivityPageReqVO pageVO) {
PageResult<DiscountActivityDO> pageResult = discountActivityService.getDiscountActivityPage(pageVO);
if (CollUtil.isEmpty(pageResult.getList())) {
return R.ok(PageResult.empty(pageResult.getTotal()));
}
// 拼接数据
List<DiscountProductDO> products = discountActivityService.getDiscountProductsByActivityId(
convertSet(pageResult.getList(), DiscountActivityDO::getId));
return R.ok(DiscountActivityConvert.INSTANCE.convertPage(pageResult, products));
}
}
package org.dromara.mall.controller.promotion.admin.discount.vo;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.dromara.common.mall.validation.InEnum;
import org.dromara.mall.enums.promotion.common.PromotionDiscountTypeEnum;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 限时折扣活动 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class DiscountActivityBaseVO {
@Schema(description = "活动标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "一个标题")
@NotNull(message = "活动标题不能为空")
private String name;
@Schema(description = "开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "开始时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime startTime;
@Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "结束时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime endTime;
@Schema(description = "备注", example = "我是备注")
private String remark;
@Schema(description = "商品")
@Data
public static class Product {
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "商品 SPU 编号不能为空")
private Long spuId;
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "商品 SKU 编号不能为空")
private Long skuId;
@Schema(description = "优惠类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "优惠类型不能为空")
@InEnum(PromotionDiscountTypeEnum.class)
private Integer discountType;
@Schema(description = "折扣百分比", example = "80") // 例如说,80% 为 80
private Integer discountPercent;
@Schema(description = "优惠金额", example = "10")
@Min(value = 0, message = "优惠金额需要大于等于 0")
private Integer discountPrice;
@AssertTrue(message = "折扣百分比需要大于等于 0.01%,小于等于 99.99%")
@JsonIgnore
public boolean isDiscountPercentValid() {
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType())
|| (discountPercent != null && discountPercent >= 1 && discountPercent <= 9999);
}
@AssertTrue(message = "优惠金额不能为空")
@JsonIgnore
public boolean isDiscountPriceValid() {
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PRICE.getType())
|| discountPrice != null;
}
}
}
package org.dromara.mall.controller.promotion.admin.discount.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.List;
@Schema(description = "管理后台 - 限时折扣活动创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DiscountActivityCreateReqVO extends DiscountActivityBaseVO {
/**
* 商品列表
*/
@NotEmpty(message = "商品列表不能为空")
@Valid
private List<Product> products;
}
package org.dromara.mall.controller.promotion.admin.discount.vo;
import org.dromara.common.mybatis.core.page.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 org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 限时折扣活动分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DiscountActivityPageReqVO extends PageParam {
@Schema(description = "活动标题", example = "一个标题")
private String name;
@Schema(description = "活动状态", example = "1")
private Integer status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
package org.dromara.mall.controller.promotion.admin.discount.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 限时折扣活动 Response VO")
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DiscountActivityRespVO extends DiscountActivityBaseVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "活动状态不能为空")
private Integer status;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "限时折扣商品", requiredMode = Schema.RequiredMode.REQUIRED)
private List<Product> products;
}
package org.dromara.mall.controller.promotion.admin.discount.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.List;
@Schema(description = "管理后台 - 限时折扣活动更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DiscountActivityUpdateReqVO extends DiscountActivityBaseVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "活动编号不能为空")
private Long id;
/**
* 商品列表
*/
@NotEmpty(message = "商品列表不能为空")
@Valid
private List<Product> products;
}
package org.dromara.mall.controller.promotion.admin.diy;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.controller.promotion.admin.diy.vo.page.*;
import org.dromara.mall.convert.promotion.diy.DiyPageConvert;
import org.dromara.mall.domain.promotion.DiyPageDO;
import org.dromara.mall.service.promotion.DiyPageService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.List;
@Tag(name = "管理后台 - 装修页面")
@RestController
@RequestMapping("/admin/promotion/diy-page")
@Validated
public class DiyPageController {
@Resource
private DiyPageService diyPageService;
@PostMapping("/create")
@Operation(summary = "创建装修页面")
@SaCheckPermission("promotion:diy-page:create")
public R<Long> createDiyPage(@Valid @RequestBody DiyPageCreateReqVO createReqVO) {
return R.ok(diyPageService.createDiyPage(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新装修页面")
@SaCheckPermission("promotion:diy-page:update")
public R<Boolean> updateDiyPage(@Valid @RequestBody DiyPageUpdateReqVO updateReqVO) {
diyPageService.updateDiyPage(updateReqVO);
return R.ok(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除装修页面")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:diy-page:delete")
public R<Boolean> deleteDiyPage(@RequestParam("id") Long id) {
diyPageService.deleteDiyPage(id);
return R.ok(true);
}
@GetMapping("/get")
@Operation(summary = "获得装修页面")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:diy-page:query")
public R<DiyPageRespVO> getDiyPage(@RequestParam("id") Long id) {
DiyPageDO diyPage = diyPageService.getDiyPage(id);
return R.ok(DiyPageConvert.INSTANCE.convert(diyPage));
}
@GetMapping("/list")
@Operation(summary = "获得装修页面列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@SaCheckPermission("promotion:diy-page:query")
public R<List<DiyPageRespVO>> getDiyPageList(@RequestParam("ids") Collection<Long> ids) {
List<DiyPageDO> list = diyPageService.getDiyPageList(ids);
return R.ok(DiyPageConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@Operation(summary = "获得装修页面分页")
@SaCheckPermission("promotion:diy-page:query")
public R<PageResult<DiyPageRespVO>> getDiyPagePage(@Valid DiyPagePageReqVO pageVO) {
PageResult<DiyPageDO> pageResult = diyPageService.getDiyPagePage(pageVO);
return R.ok(DiyPageConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/get-property")
@Operation(summary = "获得装修页面属性")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:diy-page:query")
public R<DiyPagePropertyRespVO> getDiyPageProperty(@RequestParam("id") Long id) {
DiyPageDO diyPage = diyPageService.getDiyPage(id);
return R.ok(DiyPageConvert.INSTANCE.convertPropertyVo(diyPage));
}
@PutMapping("/update-property")
@Operation(summary = "更新装修页面属性")
@SaCheckPermission("promotion:diy-page:update")
public R<Boolean> updateDiyPageProperty(@Valid @RequestBody DiyPagePropertyUpdateRequestVO updateReqVO) {
diyPageService.updateDiyPageProperty(updateReqVO);
return R.ok(true);
}
}
package org.dromara.mall.controller.promotion.admin.diy;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.controller.promotion.admin.diy.vo.template.*;
import org.dromara.mall.convert.promotion.diy.DiyTemplateConvert;
import org.dromara.mall.domain.promotion.DiyPageDO;
import org.dromara.mall.domain.promotion.DiyTemplateDO;
import org.dromara.mall.service.promotion.DiyPageService;
import org.dromara.mall.service.promotion.DiyTemplateService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Tag(name = "管理后台 - 装修模板")
@RestController
@RequestMapping("/admin/promotion/diy-template")
@Validated
public class DiyTemplateController {
@Resource
private DiyTemplateService diyTemplateService;
@Resource
private DiyPageService diyPageService;
@PostMapping("/create")
@Operation(summary = "创建装修模板")
@SaCheckPermission("promotion:diy-template:create")
public R<Long> createDiyTemplate(@Valid @RequestBody DiyTemplateCreateReqVO createReqVO) {
return R.ok(diyTemplateService.createDiyTemplate(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新装修模板")
@SaCheckPermission("promotion:diy-template:update")
public R<Boolean> updateDiyTemplate(@Valid @RequestBody DiyTemplateUpdateReqVO updateReqVO) {
diyTemplateService.updateDiyTemplate(updateReqVO);
return R.ok(true);
}
@PutMapping("/use")
@Operation(summary = "使用装修模板")
@SaCheckPermission("promotion:diy-template:use")
public R<Boolean> useDiyTemplate(@RequestParam("id") Long id) {
diyTemplateService.useDiyTemplate(id);
return R.ok(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除装修模板")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:diy-template:delete")
public R<Boolean> deleteDiyTemplate(@RequestParam("id") Long id) {
diyTemplateService.deleteDiyTemplate(id);
return R.ok(true);
}
@GetMapping("/get")
@Operation(summary = "获得装修模板")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:diy-template:query")
public R<DiyTemplateRespVO> getDiyTemplate(@RequestParam("id") Long id) {
DiyTemplateDO diyTemplate = diyTemplateService.getDiyTemplate(id);
return R.ok(DiyTemplateConvert.INSTANCE.convert(diyTemplate));
}
@GetMapping("/page")
@Operation(summary = "获得装修模板分页")
@SaCheckPermission("promotion:diy-template:query")
public R<PageResult<DiyTemplateRespVO>> getDiyTemplatePage(@Valid DiyTemplatePageReqVO pageVO) {
PageResult<DiyTemplateDO> pageResult = diyTemplateService.getDiyTemplatePage(pageVO);
return R.ok(DiyTemplateConvert.INSTANCE.convertPage(pageResult));
}
// TODO @疯狂:这个要不和 getDiyTemplate 合并,然后 DiyTemplateRespVO 里面直接把 DiyPagePropertyRespVO 也加上。减少 VO 好了,管理后台 get 多返回点数据,也问题不大的。目的,还是想尽可能降低大家的理解成本哈;
@GetMapping("/get-property")
@Operation(summary = "获得装修模板属性")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:diy-template:query")
public R<DiyTemplatePropertyRespVO> getDiyTemplateProperty(@RequestParam("id") Long id) {
DiyTemplateDO diyTemplate = diyTemplateService.getDiyTemplate(id);
List<DiyPageDO> pages = diyPageService.getDiyPageByTemplateId(id);
return R.ok(DiyTemplateConvert.INSTANCE.convertPropertyVo(diyTemplate, pages));
}
// TODO @疯狂:这个接口,要不和 useDiyTemplate 合并成一个,然后 VO 改成我们新的 VO 规范。不改的字段,就不传递。
@PutMapping("/update-property")
@Operation(summary = "更新装修模板属性")
@SaCheckPermission("promotion:diy-template:update")
public R<Boolean> updateDiyTemplateProperty(@Valid @RequestBody DiyTemplatePropertyUpdateRequestVO updateReqVO) {
diyTemplateService.updateDiyTemplateProperty(updateReqVO);
return R.ok(true);
}
}
package org.dromara.mall.controller.promotion.admin.diy.vo.page;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
/**
* 装修页面 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class DiyPageBaseVO {
@Schema(description = "装修模板编号", example = "26179")
private Long templateId;
@Schema(description = "页面名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
@NotNull(message = "页面名称不能为空")
private String name;
@Schema(description = "备注", example = "随便")
private String remark;
@Schema(description = "预览图")
private List<String> previewPicUrls;
}
package org.dromara.mall.controller.promotion.admin.diy.vo.page;
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 DiyPageCreateReqVO extends DiyPageBaseVO {
}
package org.dromara.mall.controller.promotion.admin.diy.vo.page;
import org.dromara.common.mybatis.core.page.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 org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 装修页面分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DiyPagePageReqVO extends PageParam {
@Schema(description = "页面名称", example = "王五")
private String name;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
package org.dromara.mall.controller.promotion.admin.diy.vo.page;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 装修页面属性 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DiyPagePropertyRespVO extends DiyPageBaseVO {
@Schema(description = "装修页面编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31209")
private Long id;
@Schema(description = "页面属性", example = "[]")
private String property;
}
package org.dromara.mall.controller.promotion.admin.diy.vo.page;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.ToString;
@Schema(description = "管理后台 - 装修页面属性更新 Request VO")
@Data
@ToString(callSuper = true)
public class DiyPagePropertyUpdateRequestVO {
@Schema(description = "装修页面编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31209")
@NotNull(message = "装修页面编号不能为空")
private Long id;
@Schema(description = "页面属性,JSON 格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}")
@NotBlank(message = "页面属性不能为空")
private String property;
}
package org.dromara.mall.controller.promotion.admin.diy.vo.page;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 装修页面 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DiyPageRespVO extends DiyPageBaseVO {
@Schema(description = "装修页面编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12082")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}
package org.dromara.mall.controller.promotion.admin.diy.vo.page;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 装修页面更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DiyPageUpdateReqVO extends DiyPageBaseVO {
@Schema(description = "装修页面编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12082")
@NotNull(message = "装修页面编号不能为空")
private Long id;
}
package org.dromara.mall.controller.promotion.admin.diy.vo.template;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
/**
* 装修模板 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class DiyTemplateBaseVO {
@Schema(description = "模板名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "默认主题")
@NotEmpty(message = "模板名称不能为空")
private String name;
@Schema(description = "备注", example = "默认主题")
private String remark;
@Schema(description = "预览图", example = "[https://www.iocoder.cn/1.jpg]")
private List<String> previewPicUrls;
}
package org.dromara.mall.controller.promotion.admin.diy.vo.template;
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 DiyTemplateCreateReqVO extends DiyTemplateBaseVO {
}
package org.dromara.mall.controller.promotion.admin.diy.vo.template;
import org.dromara.common.mybatis.core.page.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 org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 装修模板分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DiyTemplatePageReqVO extends PageParam {
@Schema(description = "模板名称", example = "默认主题")
private String name;
@Schema(description = "是否使用", example = "true")
private Boolean used;
@Schema(description = "使用时间", example = "使用时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] usedTime;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
package org.dromara.mall.controller.promotion.admin.diy.vo.template;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.dromara.mall.controller.promotion.admin.diy.vo.page.DiyPagePropertyRespVO;
import java.util.List;
@Schema(description = "管理后台 - 装修模板属性 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DiyTemplatePropertyRespVO extends DiyTemplateBaseVO {
@Schema(description = "装修模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31209")
private Long id;
@Schema(description = "模板属性,JSON 格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}")
private String property;
@Schema(description = "模板页面", requiredMode = Schema.RequiredMode.REQUIRED, example = "[]")
private List<DiyPagePropertyRespVO> pages;
}
package org.dromara.mall.controller.promotion.admin.diy.vo.template;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.ToString;
@Schema(description = "管理后台 - 装修模板属性更新 Request VO")
@Data
@ToString(callSuper = true)
public class DiyTemplatePropertyUpdateRequestVO {
@Schema(description = "装修模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31209")
@NotNull(message = "装修模板编号不能为空")
private Long id;
@Schema(description = "模板属性,JSON 格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}")
@NotBlank(message = "模板属性不能为空")
private String property;
}
package org.dromara.mall.controller.promotion.admin.diy.vo.template;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 装修模板 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DiyTemplateRespVO extends DiyTemplateBaseVO {
@Schema(description = "装修模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31209")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "是否使用", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
private Boolean used;
@Schema(description = "使用时间", example = "使用时间")
private LocalDateTime usedTime;
}
package org.dromara.mall.controller.promotion.admin.diy.vo.template;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 装修模板更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DiyTemplateUpdateReqVO extends DiyTemplateBaseVO {
@Schema(description = "装修模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31209")
@NotNull(message = "装修模板编号不能为空")
private Long id;
}
package org.dromara.mall.controller.promotion.admin.kefu;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mall.util.object.BeanUtils;
import org.dromara.mall.api.dto.member.MemberUserRespDTO;
import org.dromara.mall.api.service.member.MemberUserApi;
import org.dromara.mall.controller.promotion.admin.kefu.vo.conversation.KeFuConversationRespVO;
import org.dromara.mall.controller.promotion.admin.kefu.vo.conversation.KeFuConversationUpdatePinnedReqVO;
import org.dromara.mall.domain.promotion.KefuConversationDO;
import org.dromara.mall.service.promotion.KeFuConversationService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import static org.dromara.common.mall.util.collection.CollectionUtils.convertSet;
import static org.dromara.common.mall.util.collection.MapUtils.findAndThen;
@Tag(name = "管理后台 - 客服会话")
@RestController
@RequestMapping("/admin/promotion/kefu-conversation")
@Validated
public class KeFuConversationController {
@Resource
private KeFuConversationService conversationService;
@Resource
private MemberUserApi memberUserApi;
@GetMapping("/get")
@Operation(summary = "获得客服会话")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:kefu-conversation:query")
public R<KeFuConversationRespVO> getConversation(@RequestParam("id") Long id) {
KefuConversationDO conversation = conversationService.getConversation(id);
if (conversation == null) {
return R.ok(null);
}
// 拼接数据
KeFuConversationRespVO result = BeanUtils.toBean(conversation, KeFuConversationRespVO.class);
MemberUserRespDTO memberUser = memberUserApi.getUser(conversation.getUserId());
if (memberUser != null) {
result.setUserAvatar(memberUser.getAvatar()).setUserNickname(memberUser.getNickname());
}
return R.ok(result);
}
@PutMapping("/update-conversation-pinned")
@Operation(summary = "置顶/取消置顶客服会话")
@SaCheckPermission("promotion:kefu-conversation:update")
public R<Boolean> updateConversationPinned(@Valid @RequestBody KeFuConversationUpdatePinnedReqVO updateReqVO) {
conversationService.updateConversationPinnedByAdmin(updateReqVO);
return R.ok(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除客服会话")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:kefu-conversation:delete")
public R<Boolean> deleteConversation(@RequestParam("id") Long id) {
conversationService.deleteKefuConversation(id);
return R.ok(true);
}
@GetMapping("/list")
@Operation(summary = "获得客服会话列表")
@SaCheckPermission("promotion:kefu-conversation:query")
public R<List<KeFuConversationRespVO>> getConversationList() {
// 查询会话列表
List<KeFuConversationRespVO> respList = BeanUtils.toBean(conversationService.getKefuConversationList(),
KeFuConversationRespVO.class);
// 拼接数据
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(convertSet(respList, KeFuConversationRespVO::getUserId));
respList.forEach(item-> findAndThen(userMap, item.getUserId(),
memberUser-> item.setUserAvatar(memberUser.getAvatar()).setUserNickname(memberUser.getNickname())));
return R.ok(respList);
}
}
package org.dromara.mall.controller.promotion.admin.kefu;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mall.enums.UserTypeEnum;
import org.dromara.common.mall.util.object.BeanUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.mall.api.dto.system.AdminUserRespDTO;
import org.dromara.mall.api.service.system.AdminUserApi;
import org.dromara.mall.controller.promotion.admin.kefu.vo.message.KeFuMessageListReqVO;
import org.dromara.mall.controller.promotion.admin.kefu.vo.message.KeFuMessageRespVO;
import org.dromara.mall.controller.promotion.admin.kefu.vo.message.KeFuMessageSendReqVO;
import org.dromara.mall.domain.promotion.KefuMessageDO;
import org.dromara.mall.service.promotion.KeFuMessageService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import static org.dromara.common.mall.util.collection.CollectionUtils.convertSet;
import static org.dromara.common.mall.util.collection.CollectionUtils.filterList;
import static org.dromara.common.mall.util.collection.MapUtils.findAndThen;
@Tag(name = "管理后台 - 客服消息")
@RestController
@RequestMapping("/admin/promotion/kefu-message")
@Validated
public class KeFuMessageController {
@Resource
private KeFuMessageService messageService;
@Resource
private AdminUserApi adminUserApi;
@PostMapping("/send")
@Operation(summary = "发送客服消息")
@SaCheckPermission("promotion:kefu-message:send")
public R<Long> sendKeFuMessage(@Valid @RequestBody KeFuMessageSendReqVO sendReqVO) {
sendReqVO.setSenderId(LoginHelper.getUserId()).setSenderType(UserTypeEnum.ADMIN.getValue()); // 设置用户编号和类型
return R.ok(messageService.sendKefuMessage(sendReqVO));
}
@PutMapping("/update-read-status")
@Operation(summary = "更新客服消息已读状态")
@Parameter(name = "conversationId", description = "会话编号", required = true)
@SaCheckPermission("promotion:kefu-message:update")
public org.dromara.common.core.domain.R<Boolean> updateKeFuMessageReadStatus(@RequestParam("conversationId") Long conversationId) {
messageService.updateKeFuMessageReadStatus(conversationId, LoginHelper.getMemberId(), UserTypeEnum.ADMIN.getValue());
return R.ok(true);
}
@GetMapping("/list")
@Operation(summary = "获得客服消息列表")
@SaCheckPermission("promotion:kefu-message:query")
public R<List<KeFuMessageRespVO>> getKeFuMessageList(@Valid KeFuMessageListReqVO pageReqVO) {
// 获得数据
List<KefuMessageDO> list = messageService.getKeFuMessageList(pageReqVO);
// 拼接数据
List<KeFuMessageRespVO> result = BeanUtils.toBean(list, KeFuMessageRespVO.class);
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSet(filterList(result,
item -> UserTypeEnum.ADMIN.getValue().equals(item.getSenderType())), KeFuMessageRespVO::getSenderId));
result.forEach(item -> findAndThen(userMap, item.getSenderId(), user -> item.setSenderAvatar(user.getAvatar())));
return R.ok(result);
}
}
package org.dromara.mall.controller.promotion.admin.kefu.vo.conversation;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 客服会话 Response VO")
@Data
@Accessors(chain = true)
public class KeFuConversationRespVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24988")
private Long id;
@Schema(description = "会话所属用户", requiredMode = Schema.RequiredMode.REQUIRED, example = "8300")
private Long userId;
@Schema(description = "会话所属用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://yudao.com/images/avatar.jpg")
private String userAvatar;
@Schema(description = "会话所属用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
private String userNickname;
@Schema(description = "最后聊天时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime lastMessageTime;
@Schema(description = "最后聊天内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "嗨,您好啊")
private String lastMessageContent;
@Schema(description = "最后发送的消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer lastMessageContentType;
@Schema(description = "管理端置顶", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
private Boolean adminPinned;
@Schema(description = "用户是否可见", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
private Boolean userDeleted;
@Schema(description = "管理员是否可见", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
private Boolean adminDeleted;
@Schema(description = "管理员未读消息数", requiredMode = Schema.RequiredMode.REQUIRED, example = "6")
private Integer adminUnreadMessageCount;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}
package org.dromara.mall.controller.promotion.admin.kefu.vo.conversation;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - 客服会话置顶 Request VO")
@Data
public class KeFuConversationUpdatePinnedReqVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23202")
@NotNull(message = "会话编号不能为空")
private Long id;
@Schema(description = "管理端置顶", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
@NotNull(message = "管理端置顶不能为空")
private Boolean adminPinned;
}
package org.dromara.mall.controller.promotion.admin.kefu.vo.message;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static org.dromara.common.mall.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 客服消息列表 Request VO")
@Data
public class KeFuMessageListReqVO {
private static final Integer LIMIT = 10;
@Schema(description = "会话编号", example = "12580")
@NotNull(message = "会话编号不能为空")
private Long conversationId;
@Schema(description = "发送时间", example = "2024-03-27 12:00:00")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime createTime;
@Schema(description = "每次查询条数,最大值为 100", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
@NotNull(message = "每次查询条数不能为空")
@Min(value = 1, message = "每次查询条数最小值为 1")
@Max(value = 100, message = "每次查询最大值为 100")
private Integer limit = LIMIT;
}
package org.dromara.mall.controller.promotion.admin.kefu.vo.message;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 客服消息 Response VO")
@Data
public class KeFuMessageRespVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23202")
private Long id;
@Schema(description = "会话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12580")
private Long conversationId;
@Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24571")
private Long senderId;
@Schema(description = "发送人头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://yudao.com/images/avatar.jpg")
private String senderAvatar;
@Schema(description = "发送人类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer senderType;
@Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29124")
private Long receiverId;
@Schema(description = "接收人类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
private Integer receiverType;
@Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer contentType;
@Schema(description = "消息", requiredMode = Schema.RequiredMode.REQUIRED)
private String content;
@Schema(description = "是否已读", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Boolean readStatus;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}
package org.dromara.mall.controller.promotion.admin.kefu.vo.message;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.experimental.Accessors;
@Schema(description = "管理后台 - 发送客服消息 Request VO")
@Data
@Accessors(chain = true)
public class KeFuMessageSendReqVO {
@Schema(description = "会话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12580")
@NotNull(message = "会话编号不能为空")
private Long conversationId;
@Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "消息类型不能为空")
private Integer contentType;
@Schema(description = "消息", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "消息不能为空")
private String content;
// ========== 后端设置的参数,前端无需传递 ==========
@Schema(description = "发送人编号", example = "24571", hidden = true)
private Long senderId;
@Schema(description = "发送人类型", example = "1", hidden = true)
private Integer senderType;
}
package org.dromara.mall.controller.promotion.admin.point;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mall.enums.CommonStatusEnum;
import org.dromara.common.mall.util.object.BeanUtils;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.api.dto.product.ProductSpuRespDTO;
import org.dromara.mall.api.service.product.ProductSpuApi;
import org.dromara.mall.controller.promotion.admin.point.vo.activity.PointActivityPageReqVO;
import org.dromara.mall.controller.promotion.admin.point.vo.activity.PointActivityRespVO;
import org.dromara.mall.controller.promotion.admin.point.vo.activity.PointActivitySaveReqVO;
import org.dromara.mall.controller.promotion.admin.point.vo.product.PointProductRespVO;
import org.dromara.mall.domain.promotion.PointActivityDO;
import org.dromara.mall.domain.promotion.PointProductDO;
import org.dromara.mall.service.promotion.PointActivityService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.dromara.common.mall.util.collection.CollectionUtils.*;
import static org.dromara.common.mall.util.collection.MapUtils.findAndThen;
@Tag(name = "管理后台 - 积分商城活动")
@RestController
@RequestMapping("/admin/promotion/point-activity")
@Validated
public class PointActivityController {
@Resource
private PointActivityService pointActivityService;
@Resource
private ProductSpuApi productSpuApi;
@PostMapping("/create")
@Operation(summary = "创建积分商城活动")
@SaCheckPermission("promotion:point-activity:create")
public R<Long> createPointActivity(@Valid @RequestBody PointActivitySaveReqVO createReqVO) {
return R.ok(pointActivityService.createPointActivity(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新积分商城活动")
@SaCheckPermission("promotion:point-activity:update")
public R<Boolean> updatePointActivity(@Valid @RequestBody PointActivitySaveReqVO updateReqVO) {
pointActivityService.updatePointActivity(updateReqVO);
return R.ok(true);
}
@PutMapping("/close")
@Operation(summary = "关闭积分商城活动")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:point-activity:close")
public R<Boolean> closeSeckillActivity(@RequestParam("id") Long id) {
pointActivityService.closePointActivity(id);
return R.ok(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除积分商城活动")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:point-activity:delete")
public R<Boolean> deletePointActivity(@RequestParam("id") Long id) {
pointActivityService.deletePointActivity(id);
return R.ok(true);
}
@GetMapping("/get")
@Operation(summary = "获得积分商城活动")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:point-activity:query")
public R<PointActivityRespVO> getPointActivity(@RequestParam("id") Long id) {
PointActivityDO pointActivity = pointActivityService.getPointActivity(id);
if (pointActivity == null) {
return R.ok(null);
}
List<PointProductDO> products = pointActivityService.getPointProductListByActivityIds(Collections.singletonList(id));
PointActivityRespVO respVO = BeanUtils.toBean(pointActivity, PointActivityRespVO.class);
respVO.setProducts(BeanUtils.toBean(products, PointProductRespVO.class));
return R.ok(respVO);
}
@GetMapping("/page")
@Operation(summary = "获得积分商城活动分页")
@SaCheckPermission("promotion:point-activity:query")
public R<PageResult<PointActivityRespVO>> getPointActivityPage(@Valid PointActivityPageReqVO pageReqVO) {
PageResult<PointActivityDO> pageResult = pointActivityService.getPointActivityPage(pageReqVO);
if (CollUtil.isEmpty(pageResult.getList())) {
return R.ok(PageResult.empty(pageResult.getTotal()));
}
// 拼接数据
List<PointActivityRespVO> resultList = buildPointActivityRespVOList(pageResult.getList());
return R.ok(new PageResult<>(resultList, pageResult.getTotal()));
}
@GetMapping("/list-by-ids")
@Operation(summary = "获得积分商城活动列表,基于活动编号数组")
@Parameter(name = "ids", description = "活动编号数组", required = true, example = "[1024, 1025]")
public R<List<PointActivityRespVO>> getPointActivityListByIds(@RequestParam("ids") List<Long> ids) {
// 1. 获得开启的活动列表
List<PointActivityDO> activityList = pointActivityService.getPointActivityListByIds(ids);
activityList.removeIf(activity -> CommonStatusEnum.isDisable(activity.getStatus()));
if (CollUtil.isEmpty(activityList)) {
return R.ok(Collections.emptyList());
}
// 2. 拼接返回
List<PointActivityRespVO> result = buildPointActivityRespVOList(activityList);
return R.ok(result);
}
private List<PointActivityRespVO> buildPointActivityRespVOList(List<PointActivityDO> activityList) {
List<PointProductDO> products = pointActivityService.getPointProductListByActivityIds(
convertSet(activityList, PointActivityDO::getId));
Map<Long, List<PointProductDO>> productsMap = convertMultiMap(products, PointProductDO::getActivityId);
Map<Long, ProductSpuRespDTO> spuMap = productSpuApi.getSpusMap(
convertSet(activityList, PointActivityDO::getSpuId));
List<PointActivityRespVO> result = BeanUtils.toBean(activityList, PointActivityRespVO.class);
result.forEach(activity -> {
// 设置 product 信息
PointProductDO minProduct = getMinObject(productsMap.get(activity.getId()), PointProductDO::getPoint);
assert minProduct != null;
activity.setPoint(minProduct.getPoint()).setPrice(minProduct.getPrice());
findAndThen(spuMap, activity.getSpuId(),
spu -> activity.setSpuName(spu.getName()).setPicUrl(spu.getPicUrl()).setMarketPrice(spu.getMarketPrice()));
});
return result;
}
}
package org.dromara.mall.controller.promotion.admin.point.vo.activity;
import org.dromara.common.mybatis.core.page.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 PointActivityPageReqVO extends PageParam {
@Schema(description = "活动状态", example = "2")
private Integer status;
}
package org.dromara.mall.controller.promotion.admin.point.vo.activity;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
import org.dromara.mall.controller.promotion.admin.point.vo.product.PointProductRespVO;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 积分商城活动 Response VO")
@Data
@Accessors(chain = true)
@ExcelIgnoreUnannotated
public class PointActivityRespVO {
@Schema(description = "积分商城活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11373")
@ExcelProperty("积分商城活动编号")
private Long id;
@Schema(description = "积分商城活动商品", requiredMode = Schema.RequiredMode.REQUIRED, example = "19509")
@ExcelProperty("积分商城活动商品")
private Long spuId;
@Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("活动状态")
private Integer status;
@Schema(description = "积分商城活动库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("积分商城活动库存")
private Integer stock; // 剩余库存积分兑换时扣减
@Schema(description = "积分商城活动总库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("积分商城活动总库存")
private Integer totalStock;
@Schema(description = "备注", example = "你说的对")
@ExcelProperty("备注")
private String remark;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("排序")
private Integer sort;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "积分商城商品", requiredMode = Schema.RequiredMode.REQUIRED)
private List<PointProductRespVO> products;
// ========== 商品字段 ==========
@Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 name 读取
example = "618大促")
private String spuName;
@Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 picUrl 读取
example = "https://www.iocoder.cn/xx.png")
private String picUrl;
@Schema(description = "商品市场价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 marketPrice 读取
example = "50")
private Integer marketPrice;
//======================= 显示所需兑换积分最少的 sku 信息 =======================
@Schema(description = "兑换积分", requiredMode = Schema.RequiredMode.REQUIRED)
private Integer point;
@Schema(description = "兑换金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "15860")
private Integer price;
}
package org.dromara.mall.controller.promotion.admin.point.vo.activity;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.dromara.mall.controller.promotion.admin.point.vo.product.PointProductSaveReqVO;
import java.util.List;
@Schema(description = "管理后台 - 积分商城活动新增/修改 Request VO")
@Data
public class PointActivitySaveReqVO {
@Schema(description = "积分商城活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11373")
private Long id;
@Schema(description = "积分商城活动商品", requiredMode = Schema.RequiredMode.REQUIRED, example = "19509")
@NotNull(message = "积分商城活动商品不能为空")
private Long spuId;
@Schema(description = "备注", example = "你说的对")
private String remark;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "排序不能为空")
private Integer sort;
@Schema(description = "积分商城商品", requiredMode = Schema.RequiredMode.REQUIRED)
private List<PointProductSaveReqVO> products;
}
package org.dromara.mall.controller.promotion.admin.point.vo.product;
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 PointProductRespVO {
@Schema(description = "积分商城商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31718")
private Long id;
@Schema(description = "积分商城活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29388")
private Long activityId;
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8112")
private Long spuId;
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2736")
private Long skuId;
@Schema(description = "可兑换数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "3926")
private Integer count;
@Schema(description = "兑换积分", requiredMode = Schema.RequiredMode.REQUIRED)
private Integer point;
@Schema(description = "兑换金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "15860")
private Integer price;
@Schema(description = "积分商城商品库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private Integer stock;
@Schema(description = "积分商城商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
private Integer activityStatus;
}
package org.dromara.mall.controller.promotion.admin.point.vo.product;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - 积分商城商品新增/修改 Request VO")
@Data
public class PointProductSaveReqVO {
@Schema(description = "积分商城商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31718")
private Long id;
@Schema(description = "积分商城活动 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "29388")
@NotNull(message = "积分商城活动 id不能为空")
private Long activityId;
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8112")
@NotNull(message = "商品 SPU 编号不能为空")
private Long spuId;
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2736")
@NotNull(message = "商品 SKU 编号不能为空")
private Long skuId;
@Schema(description = "可兑换数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "3926")
@NotNull(message = "可兑换数量不能为空")
private Integer count;
@Schema(description = "兑换积分", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "兑换积分不能为空")
private Integer point;
@Schema(description = "兑换金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "15860")
@NotNull(message = "兑换金额,单位:分不能为空")
private Integer price;
@Schema(description = "积分商城商品库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
@NotNull(message = "积分商城商品不能为空")
private Integer stock;
@Schema(description = "积分商城商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "积分商城商品状态不能为空")
private Integer activityStatus;
}
package org.dromara.mall.controller.promotion.admin.reward;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.mall.util.object.BeanUtils;
import org.dromara.common.mybatis.core.page.PageResult;
import org.dromara.mall.controller.promotion.admin.reward.vo.RewardActivityCreateReqVO;
import org.dromara.mall.controller.promotion.admin.reward.vo.RewardActivityPageReqVO;
import org.dromara.mall.controller.promotion.admin.reward.vo.RewardActivityRespVO;
import org.dromara.mall.controller.promotion.admin.reward.vo.RewardActivityUpdateReqVO;
import org.dromara.mall.domain.promotion.RewardActivityDO;
import org.dromara.mall.service.promotion.RewardActivityService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Tag(name = "管理后台 - 满减送活动")
@RestController
@RequestMapping("/admin/promotion/reward-activity")
@Validated
public class RewardActivityController {
@Resource
private RewardActivityService rewardActivityService;
@PostMapping("/create")
@Operation(summary = "创建满减送活动")
@SaCheckPermission("promotion:reward-activity:create")
public R<Long> createRewardActivity(@Valid @RequestBody RewardActivityCreateReqVO createReqVO) {
return R.ok(rewardActivityService.createRewardActivity(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新满减送活动")
@SaCheckPermission("promotion:reward-activity:update")
public R<Boolean> updateRewardActivity(@Valid @RequestBody RewardActivityUpdateReqVO updateReqVO) {
rewardActivityService.updateRewardActivity(updateReqVO);
return R.ok(true);
}
@PutMapping("/close")
@Operation(summary = "关闭满减送活动")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:reward-activity:close")
public R<Boolean> closeRewardActivity(@RequestParam("id") Long id) {
rewardActivityService.closeRewardActivity(id);
return R.ok(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除满减送活动")
@Parameter(name = "id", description = "编号", required = true)
@SaCheckPermission("promotion:reward-activity:delete")
public R<Boolean> deleteRewardActivity(@RequestParam("id") Long id) {
rewardActivityService.deleteRewardActivity(id);
return R.ok(true);
}
@GetMapping("/get")
@Operation(summary = "获得满减送活动")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@SaCheckPermission("promotion:reward-activity:query")
public R<RewardActivityRespVO> getRewardActivity(@RequestParam("id") Long id) {
RewardActivityDO rewardActivity = rewardActivityService.getRewardActivity(id);
return R.ok(BeanUtils.toBean(rewardActivity, RewardActivityRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得满减送活动分页")
@SaCheckPermission("promotion:reward-activity:query")
public R<PageResult<RewardActivityRespVO>> getRewardActivityPage(@Valid RewardActivityPageReqVO pageVO) {
PageResult<RewardActivityDO> pageResult = rewardActivityService.getRewardActivityPage(pageVO);
return R.ok(org.dromara.common.mybatis.util.BeanUtils.toBean(pageResult, RewardActivityRespVO.class));
}
}
package org.dromara.mall.controller.promotion.admin.reward.vo;
import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.Future;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.dromara.common.mall.validation.InEnum;
import org.dromara.mall.enums.promotion.common.PromotionConditionTypeEnum;
import org.dromara.mall.enums.promotion.common.PromotionProductScopeEnum;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* 满减送活动 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class RewardActivityBaseVO {
@Schema(description = "活动标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "满啦满啦")
@NotNull(message = "活动标题不能为空")
private String name;
@Schema(description = "开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "开始时间不能为空")
private LocalDateTime startTime;
@Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "结束时间不能为空")
@Future(message = "结束时间必须大于当前时间")
private LocalDateTime endTime;
@Schema(description = "备注", example = "biubiubiu")
private String remark;
@Schema(description = "条件类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "条件类型不能为空")
@InEnum(value = PromotionConditionTypeEnum.class, message = "条件类型必须是 {value}")
private Integer conditionType;
@Schema(description = "商品范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "商品范围不能为空")
@InEnum(value = PromotionProductScopeEnum.class, message = "商品范围必须是 {value}")
private Integer productScope;
@Schema(description = "商品范围编号的数组", example = "[1, 3]")
private List<Long> productScopeValues;
/**
* 优惠规则的数组
*/
@Valid // 校验下子对象
private List<Rule> rules;
@Schema(description = "优惠规则")
@Data
public static class Rule {
@Schema(description = "优惠门槛", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") // 1. 满 N 元,单位:分; 2. 满 N 件
@Min(value = 1L, message = "优惠门槛必须大于等于 1")
private Integer limit;
@Schema(description = "优惠价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
@Min(value = 1L, message = "优惠价格必须大于等于 1")
private Integer discountPrice;
@Schema(description = "是否包邮", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
@NotNull(message = "规则是否包邮不能为空")
private Boolean freeDelivery;
@Schema(description = "赠送的积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private Integer point;
@Schema(description = "赠送的优惠劵编号的数组")
private Map<Long, Integer> giveCouponTemplateCounts;
@AssertTrue(message = "赠送的积分不能小于 0")
@JsonIgnore
public boolean isPointValid() {
return point == null || point >= 0;
}
}
@AssertTrue(message = "商品范围编号的数组不能为空")
@JsonIgnore
public boolean isProductScopeValuesValid() {
return Objects.equals(productScope, PromotionProductScopeEnum.ALL.getScope()) // 全部范围时,可以为空
|| CollUtil.isNotEmpty(productScopeValues);
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论