Переглянути джерело

feat(store): 新增Banner管理功能

- 新增Banner实体类StoreBanner,包含模块编码、名称、状态等字段
- 创建Banner控制器StoreBannerController,提供增删改查接口
- 实现Banner服务层StoreBannerService及其实现类
- 添加Banner数据传输对象StoreBannerDto和展示对象StoreBannerVo
- 集成MyBatis Plus实现Banner数据访问层Mapper
- 支持Banner分页查询、状态筛选及排序功能
- 提供Banner新增、修改、删除操作的完整业务逻辑
Lhaibo 13 годин тому
батько
коміт
21ab950d66

+ 72 - 0
alien-entity/src/main/java/shop/alien/entity/store/StoreBanner.java

@@ -0,0 +1,72 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Banner表
+ *
+ * @author gpt
+ * @since 2025-12-16
+ */
+@Data
+@JsonInclude
+@TableName("store_banner")
+@ApiModel(value = "StoreBanner对象", description = "Banner表")
+public class StoreBanner extends Model<StoreBanner> {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "模块编码")
+    @TableField("module_code")
+    private String moduleCode;
+
+    @ApiModelProperty(value = "模块名称")
+    @TableField("module_name")
+    private String moduleName;
+
+    @ApiModelProperty(value = "状态:1 启用,0 禁用")
+    @TableField("status")
+    private String status;
+
+    @ApiModelProperty(value = "排序")
+    @TableField("sort")
+    private Integer sort;
+
+    @ApiModelProperty(value = "图片")
+    @TableField("img_urls")
+    private String imgUrls;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}
+

+ 37 - 0
alien-entity/src/main/java/shop/alien/entity/store/dto/StoreBannerDto.java

@@ -0,0 +1,37 @@
+package shop.alien.entity.store.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Banner提交DTO
+ *
+ * 用于新增/修改 Banner 的请求载体。
+ */
+@Data
+@ApiModel(value = "StoreBannerDto对象", description = "Banner提交DTO")
+public class StoreBannerDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键,修改时传递")
+    private Integer id;
+
+    @ApiModelProperty(value = "模块编码")
+    private String moduleCode;
+
+    @ApiModelProperty(value = "模块名称")
+    private String moduleName;
+
+    @ApiModelProperty(value = "状态:1 启用,0 禁用")
+    private String status;
+
+    @ApiModelProperty(value = "排序")
+    private Integer sort;
+
+    @ApiModelProperty(value = "图片URL,多个可用逗号分隔或前端自定义格式")
+    private String imgUrls;
+}
+

+ 24 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/StoreBannerVo.java

@@ -0,0 +1,24 @@
+package shop.alien.entity.store.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import shop.alien.entity.store.StoreBanner;
+
+/**
+ * Banner展示VO
+ *
+ * 面向前端展示的 Banner 数据对象。
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@JsonInclude
+@ApiModel(value = "StoreBannerVo对象", description = "Banner展示VO")
+public class StoreBannerVo extends StoreBanner {
+
+    @ApiModelProperty(value = "状态描述")
+    private String statusText;
+}
+

+ 14 - 0
alien-entity/src/main/java/shop/alien/mapper/StoreBannerMapper.java

@@ -0,0 +1,14 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import shop.alien.entity.store.StoreBanner;
+
+/**
+ * Banner表 Mapper 接口
+ *
+ * @author gpt
+ * @since 2025-12-16
+ */
+public interface StoreBannerMapper extends BaseMapper<StoreBanner> {
+}
+

+ 67 - 0
alien-store/src/main/java/shop/alien/store/controller/StoreBannerController.java

@@ -0,0 +1,67 @@
+package shop.alien.store.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.dto.StoreBannerDto;
+import shop.alien.entity.store.vo.StoreBannerVo;
+import shop.alien.store.service.StoreBannerService;
+
+import java.util.List;
+
+/**
+ * Banner表 前端控制器
+ *
+ * @author gpt
+ * @since 2025-12-16
+ */
+@Slf4j
+@Api(tags = {"二期-Banner管理"})
+@ApiSort(20)
+@CrossOrigin
+@RestController
+@RequestMapping("/banner")
+@RequiredArgsConstructor
+public class StoreBannerController {
+
+    private final StoreBannerService storeBannerService;
+
+    @ApiOperation("新增或修改Banner")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("/saveOrUpdate")
+    public R<String> saveOrUpdate(@RequestBody StoreBannerDto storeBannerDto) {
+        log.info("StoreBannerController.saveOrUpdate?storeBannerDto={}", storeBannerDto);
+        return storeBannerService.saveBanner(storeBannerDto);
+    }
+
+    @ApiOperation("删除Banner")
+    @ApiOperationSupport(order = 2)
+    @PostMapping("/delete")
+    public R<String> delete(@RequestBody List<Integer> ids) {
+        log.info("StoreBannerController.delete?ids={}", ids);
+        return storeBannerService.removeByIds(ids) ? R.success("删除成功") : R.fail("删除失败");
+    }
+
+    @ApiOperation("分页查询Banner列表")
+    @ApiOperationSupport(order = 3)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "moduleCode", value = "模块编码", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "moduleName", value = "模块名称", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "status", value = "状态:1 启用,0 禁用", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "pageNum", value = "页码", dataType = "Integer", paramType = "query", defaultValue = "1"),
+            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "Integer", paramType = "query", defaultValue = "10")
+    })
+    @GetMapping("/page")
+    public R<IPage<StoreBannerVo>> page(String moduleCode,
+                                        String moduleName,
+                                        String status,
+                                        @RequestParam(defaultValue = "1") Integer pageNum,
+                                        @RequestParam(defaultValue = "10") Integer pageSize) {
+        log.info("StoreBannerController.page?moduleCode={}&moduleName={}&status={}&pageNum={}&pageSize={}", moduleCode, moduleName, status, pageNum, pageSize);
+        return R.data(storeBannerService.pageList(moduleCode, moduleName, status, pageNum, pageSize));
+    }
+}
+

+ 38 - 0
alien-store/src/main/java/shop/alien/store/service/StoreBannerService.java

@@ -0,0 +1,38 @@
+package shop.alien.store.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.StoreBanner;
+import shop.alien.entity.store.dto.StoreBannerDto;
+import shop.alien.entity.store.vo.StoreBannerVo;
+
+/**
+ * Banner表 服务类
+ *
+ * @author gpt
+ * @since 2025-12-16
+ */
+public interface StoreBannerService extends IService<StoreBanner> {
+
+    /**
+     * 新增或修改 Banner
+     *
+     * @param storeBannerDto Banner请求DTO
+     * @return 操作结果
+     */
+    R<String> saveBanner(StoreBannerDto storeBannerDto);
+
+    /**
+     * 分页查询 Banner 列表
+     *
+     * @param moduleCode 模块编码
+     * @param moduleName 模块名称
+     * @param status     状态:1 启用,0 禁用
+     * @param pageNum    页码
+     * @param pageSize   每页条数
+     * @return 分页数据
+     */
+    IPage<StoreBannerVo> pageList(String moduleCode, String moduleName, String status, Integer pageNum, Integer pageSize);
+}
+

+ 62 - 0
alien-store/src/main/java/shop/alien/store/service/impl/StoreBannerServiceImpl.java

@@ -0,0 +1,62 @@
+package shop.alien.store.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.StoreBanner;
+import shop.alien.entity.store.dto.StoreBannerDto;
+import shop.alien.entity.store.vo.StoreBannerVo;
+import shop.alien.mapper.StoreBannerMapper;
+import shop.alien.store.service.StoreBannerService;
+
+/**
+ * Banner表 服务实现类
+ *
+ * @author gpt
+ * @since 2025-12-16
+ */
+@Service
+public class StoreBannerServiceImpl extends ServiceImpl<StoreBannerMapper, StoreBanner> implements StoreBannerService {
+
+    @Transactional
+    @Override
+    public R<String> saveBanner(StoreBannerDto storeBannerDto) {
+        StoreBanner storeBanner = new StoreBanner();
+        BeanUtils.copyProperties(storeBannerDto, storeBanner);
+        boolean update = storeBanner.getId() != null;
+        boolean result = this.saveOrUpdate(storeBanner);
+        if (result) {
+            return R.success(update ? "修改成功" : "新增成功");
+        }
+        return R.fail(update ? "修改失败" : "新增失败");
+    }
+
+    @Override
+    public IPage<StoreBannerVo> pageList(String moduleCode, String moduleName, String status, Integer pageNum, Integer pageSize) {
+        int current = pageNum == null || pageNum <= 0 ? 1 : pageNum;
+        int size = pageSize == null || pageSize <= 0 ? 10 : pageSize;
+        Page<StoreBanner> page = new Page<>(current, size);
+        LambdaQueryWrapper<StoreBanner> wrapper = new LambdaQueryWrapper<>();
+        wrapper.like(StringUtils.isNotBlank(moduleCode), StoreBanner::getModuleCode, moduleCode);
+        wrapper.like(StringUtils.isNotBlank(moduleName), StoreBanner::getModuleName, moduleName);
+        wrapper.eq(StringUtils.isNotBlank(status), StoreBanner::getStatus, status);
+        wrapper.orderByAsc(StoreBanner::getSort).orderByDesc(StoreBanner::getCreatedTime);
+        return this.page(page, wrapper).convert(this::toVo);
+    }
+
+    private StoreBannerVo toVo(StoreBanner banner) {
+        StoreBannerVo vo = new StoreBannerVo();
+        BeanUtils.copyProperties(banner, vo);
+        if (StringUtils.isNotBlank(banner.getStatus())) {
+            vo.setStatusText("1".equals(banner.getStatus()) ? "启用" : "禁用");
+        }
+        return vo;
+    }
+}
+