src/main/java/com/mzl/flower/dto/request/flower/FlowerBatchDTO.java
对比新文件 @@ -0,0 +1,14 @@ package com.mzl.flower.dto.request.flower; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.List; @Data public class FlowerBatchDTO { @ApiModelProperty(value = "ids") @NotNull(message = "传入的IDS不能为空") private List<Long> ids; } src/main/java/com/mzl/flower/dto/response/flower/FlowerSupplierListDTO.java
@@ -47,4 +47,7 @@ private String statusStr; private Integer realSales;//真实销量 @ApiModelProperty(value = "价格排序") private Integer typeRank; } src/main/java/com/mzl/flower/entity/FlowerDeleteDO.java
对比新文件 @@ -0,0 +1,152 @@ package com.mzl.flower.entity; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.experimental.Accessors; import java.math.BigDecimal; import java.time.LocalDateTime; /** * @author @TaoJie * @since 2024-09-09 */ @Data @Accessors(chain = true) @TableName("t_flower_delete") public class FlowerDeleteDO{ @TableId(value = "id") private Long id; @TableField("create_by") private String createBy; @TableField("create_time") private LocalDateTime createTime; @TableField("update_by") private String updateBy; @TableField("update_time") private LocalDateTime updateTime; @TableField("deleted") @TableLogic private Boolean deleted; /** * 分类id */ private Long category; /** * 单位 */ private String unit; /** * 颜色 */ private String color; /** * 名称 */ private String name; /** * 封面 */ private String cover; /** * 轮播图 */ private String banners; /** * 视频 */ private String video; /** * 级别; FLOWER_LEVEL */ private String level; /** * 所属供应商 */ private Long supplierId; /** * 供应商价格 */ private BigDecimal price; /** * 库存 */ private Integer stock; /** * 状态 */ private String status; /** * 标签 */ private String tags; /** * 审核意见 */ private String auditRemarks; /** * 审核时间 */ private LocalDateTime auditTime; /** * 是否显示 */ private Boolean shown; /** * 销量 */ private Integer sales; /** * 描述 */ private String description; /** * 是否推荐 */ private Boolean recommend; /** * 真实销量 */ private Integer realSales; /** * 推荐排序 */ private Integer recommendRank; /** * 同类排名 */ private Integer typeRank; } src/main/java/com/mzl/flower/entity/flower/Flower.java
@@ -3,7 +3,6 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.mzl.flower.base.BaseAutoEntity; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; @@ -76,4 +75,7 @@ @TableField("recommend_rank") private Integer recommendRank;//推荐排序 @TableField("type_rank") private Integer typeRank;//同类排序 } src/main/java/com/mzl/flower/mapper/FlowerDeleteMapper.java
对比新文件 @@ -0,0 +1,16 @@ package com.mzl.flower.mapper; import com.mzl.flower.entity.FlowerDeleteDO; import com.baomidou.mybatisplus.core.mapper.BaseMapper; /** * <p> * Mapper 接口 * </p> * * @author @TaoJie * @since 2024-09-09 */ public interface FlowerDeleteMapper extends BaseMapper<FlowerDeleteDO> { } src/main/java/com/mzl/flower/mapper/flower/FlowerMapper.java
@@ -46,4 +46,13 @@ void updateFlowerCategoryInfo(Long category); List<Long> searchInvalidHistory(@Param("userId") String userId); void updateBatchTypeRank(@Param("list") List<Flower> flowerList); void deleteBatchPhysics(@Param("list") List<Long> ids); void restoreFlowerBatch(@Param("list") List<Long> ids); List<Flower> getDeletdFlowByIds(@Param("list") List<Long> ids); } src/main/java/com/mzl/flower/service/flower/FlowerDeleteService.java
对比新文件 @@ -0,0 +1,16 @@ package com.mzl.flower.service.flower; import com.mzl.flower.entity.FlowerDeleteDO; import com.baomidou.mybatisplus.extension.service.IService; /** * <p> * 服务类 * </p> * * @author @TaoJie * @since 2024-09-09 */ public interface FlowerDeleteService extends IService<FlowerDeleteDO> { } src/main/java/com/mzl/flower/service/flower/FlowerService.java
@@ -6,8 +6,8 @@ import com.mzl.flower.config.security.SecurityUtils; import com.mzl.flower.constant.Constants; import com.mzl.flower.dto.request.flower.*; import com.mzl.flower.dto.request.flower.FlowerTagMultipleDTO; import com.mzl.flower.dto.response.flower.*; import com.mzl.flower.entity.FlowerDeleteDO; import com.mzl.flower.entity.customer.Collect; import com.mzl.flower.entity.customer.Customer; import com.mzl.flower.entity.flower.*; @@ -25,6 +25,7 @@ import com.mzl.flower.mapper.supplier.SupplierTypeMapper; import com.mzl.flower.service.BaseService; import com.mzl.flower.service.customer.BrowseService; import com.mzl.flower.service.payment.RedisLockService; import io.micrometer.core.instrument.util.StringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; @@ -32,14 +33,15 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; @Slf4j @Service @@ -82,6 +84,14 @@ @Autowired private OrderItemMapper orderItemMapper; @Autowired private RedisLockService lockService; @Autowired private FlowerDeleteService flowerDeleteService; private static final String FLOWER_KEY="com:mzl:flower:service:flower:%s:%s"; @Async public synchronized void updateFlowerSales(Order order){ List<OrderItem> items = orderItemMapper.selectList(new QueryWrapper<OrderItem>() @@ -97,6 +107,62 @@ public synchronized void updateCategoryInfo(Long category){ flowerMapper.updateFlowerCategoryInfo(category); } @Async public void updateFlowTypeRank(Long id,Long category,String level){ Flower flower =null; // 如果 id 不为空,则 category 和 level 可以为空 if (Objects.nonNull(id)) { flower = flowerMapper.selectById(id); if (flower == null) { throw new IllegalArgumentException("Flower not found for ID: " + id); } category = flower.getCategory(); // 使用从数据库中检索到的 category level = flower.getLevel(); // 使用从数据库中检索到的 level } else { // 如果 id 为空,则 category 和 level 必须提供 if (Objects.isNull(category) || StringUtils.isEmpty(level)) { throw new IllegalArgumentException("Category and level must be provided when ID is null"); } flower=new Flower(); flower.setCategory(category); flower.setLevel(level); } String key=String.format(FLOWER_KEY, flower.getCategory(),flower.getLevel()); boolean lock = lockService.getObjectLock(key, ""); if(!lock){ return; } try{ QueryWrapper<Flower> queryWrapper=new QueryWrapper<>(); queryWrapper.lambda().eq(Flower::getDeleted,false) .eq(Objects.nonNull(flower.getCategory()),Flower::getCategory,flower.getCategory()) .eq(StringUtils.isNotEmpty(flower.getLevel()),Flower::getLevel,flower.getLevel()) .orderByAsc(Flower::getPrice); final List<Flower> flowerList = flowerMapper.selectList(queryWrapper); AtomicInteger index = new AtomicInteger(1); flowerList.forEach(f -> f.setTypeRank(index.getAndIncrement())); if(!CollectionUtils.isEmpty(flowerList)){ flowerMapper.updateBatchTypeRank(flowerList); } }finally { lockService.releaseObjectLock(key,""); } } /** * 花农(供应商)提交商品 @@ -128,6 +194,8 @@ paramService.insertTableData(fc.getParamId(), g.getId(), params); } // 更新商品价格在这里的分类 updateFlowTypeRank(null,g.getCategory(),g.getLevel()); return g.getId(); } @@ -164,6 +232,9 @@ paramService.updateTableData(fc.getParamId(), g.getId(), params); } } // 更新商品价格在这里的分类 updateFlowTypeRank(null,g.getCategory(),g.getLevel()); return g.getId(); } @@ -386,10 +457,16 @@ } public void deleteFlower(Long id){ final Flower flower = flowerMapper.selectById(id); flowerMapper.deleteById(id); //清除购物车商品 cartMapper.delete(new QueryWrapper<Cart>().eq("flower_id", id)); // 更新商品价格在这里的分类 updateFlowTypeRank(null,flower.getCategory(),flower.getLevel()); } public void restoreFlower(Long id){ @@ -409,6 +486,8 @@ } f.setPrice(dto.getPrice()); flowerMapper.updateById(f); // 更新商品价格在这里的分类 updateFlowTypeRank(null,f.getCategory(),f.getLevel()); } public void editFlowerStock(FlowerStockDTO dto){ @@ -712,4 +791,62 @@ } } @Transactional public void deleteFlowerBatch(FlowerBatchDTO dto) { List<Flower> flowerList = flowerMapper.getDeletdFlowByIds(dto.getIds()); //物理删除 flowerMapper.deleteBatchPhysics(dto.getIds()); // 备份 if(!CollectionUtils.isEmpty(flowerList)){ backupFlower(flowerList); } } @Async public void backupFlower(List<Flower> flowerList) { // 备份 final List<Long> idList = flowerList.stream().map(flower -> flower.getId()).collect(Collectors.toList()); final List<FlowerDeleteDO> flowerDeleteList = flowerDeleteService.getBaseMapper().selectBatchIds(idList); // 遍历flowerList 根据ID查找 ,如果flowerDeleteList 存在,则放入到更新列表里面去,如果flowerDeleteList不存在,则添加到新增列表里面去 // 将查询到的 flowerDeleteList 的 ID 转为 Set 以便快速查找 Set<Long> existingIds = flowerDeleteList.stream() .map(FlowerDeleteDO::getId) .collect(Collectors.toSet()); // 使用 Stream 进行更新和插入分类 List<FlowerDeleteDO> updateList = flowerList.stream() .filter(flower -> existingIds.contains(flower.getId())) // 过滤出已存在的记录 .map(flower -> convertToFlowerDeleteDO(flower)) // 转换为 FlowerDeleteDO 对象 .collect(Collectors.toList()); List<FlowerDeleteDO> insertList = flowerList.stream() .filter(flower -> !existingIds.contains(flower.getId())) // 过滤出不存在的记录 .map(flower -> convertToFlowerDeleteDO(flower)) // 转换为 FlowerDeleteDO 对象 .collect(Collectors.toList()); // 批量执行更新和新增操作 if (!updateList.isEmpty()) { flowerDeleteService.updateBatchById(updateList); // 批量更新 } if (!insertList.isEmpty()) { flowerDeleteService.saveBatch(insertList); // 批量插入 } } @Transactional public void restoreFlowerBatch(FlowerBatchDTO dto) { flowerMapper.restoreFlowerBatch(dto.getIds()); } // 方法用于将 Flower 转换为 FlowerDeleteDO private FlowerDeleteDO convertToFlowerDeleteDO(Flower flower) { FlowerDeleteDO flowerDeleteDO=new FlowerDeleteDO(); BeanUtils.copyProperties(flower,flowerDeleteDO); // 其他需要备份的字段... return flowerDeleteDO; } } src/main/java/com/mzl/flower/service/impl/FlowerDeleteServiceImpl.java
对比新文件 @@ -0,0 +1,20 @@ package com.mzl.flower.service.impl; import com.mzl.flower.entity.FlowerDeleteDO; import com.mzl.flower.mapper.FlowerDeleteMapper; import com.mzl.flower.service.flower.FlowerDeleteService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; /** * <p> * 服务实现类 * </p> * * @author @TaoJie * @since 2024-09-09 */ @Service public class FlowerDeleteServiceImpl extends ServiceImpl<FlowerDeleteMapper, FlowerDeleteDO> implements FlowerDeleteService { } src/main/java/com/mzl/flower/web/supplier/FlowerSupplierController.java
@@ -145,4 +145,25 @@ flowerService.editFlowerStock(dto); return returnData(R.SUCCESS.getCode(), null); } @PostMapping("/list/delete/batch") @ApiOperation(value = "商品批量删除") @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "商品ids", required = true, dataType = "Long", paramType = "query") }) public ResponseEntity<ReturnDataDTO<?>> deleteFlowerBatch(@RequestBody FlowerBatchDTO dto) { flowerService.deleteFlowerBatch(dto); return returnData(R.SUCCESS.getCode(), null); } @PostMapping("/list/restore/batch") @ApiOperation(value = "商品批量恢复") @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "商品ids", required = true, dataType = "Long", paramType = "query") }) public ResponseEntity<ReturnDataDTO<?>> restoreFlowerBatch(@RequestBody FlowerBatchDTO dto) { flowerService.restoreFlowerBatch(dto); return returnData(R.SUCCESS.getCode(), null); } } src/main/resources/application-dev.yml
@@ -3,7 +3,7 @@ active: dev,swagger datasource: type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://47.99.58.211:3306/flower?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2b8 url: jdbc:mysql://47.99.58.211:3306/flower?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2b8&allowMultiQueries=true username: root password: Hmy@2024!*@& druid: src/main/resources/application-local.yml
@@ -3,7 +3,7 @@ active: local,swagger datasource: type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://47.99.58.211:3306/flower?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2b8 url: jdbc:mysql://47.99.58.211:3306/flower?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2b8&allowMultiQueries=true username: root password: Hmy@2024!*@& druid: src/main/resources/application-prod.yml
@@ -3,7 +3,7 @@ active: prod datasource: type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://127.0.0.1:3306/flower-prod?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2b8 url: jdbc:mysql://127.0.0.1:3306/flower-prod?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2b8&allowMultiQueries=true username: root password: Hmy@2024!*@& druid: src/main/resources/application-test.yml
@@ -3,7 +3,7 @@ active: test,swagger datasource: type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://47.99.58.211:3306/flower?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2b8 url: jdbc:mysql://47.99.58.211:3306/flower?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2b8&allowMultiQueries=true username: root password: Hmy@2024!*@& druid: src/main/resources/application.yml
@@ -67,8 +67,8 @@ wx: miniapp: appid: wx1441324401626290 #小程序appId 花店端 secret: bab595ac75f60eb33567511111a569a7 #secret花店端 appid: wx3203fd935a6ffe09 #小程序appId 花店端 secret: 9121c703fb0c416b21a8c289dd73ae9b #secret花店端 msgDataFormat: JSON mp: app-id: xxx #公众号appId @@ -77,14 +77,14 @@ wechat: merchantId: 1661512517 customer: appid: wx1441324401626290 #小程序appId secret: bab595ac75f60eb33567511111a569a7 #secret appid: wx1441324401626290 #小程序appId secret: bab595ac75f60eb33567511111a569a7 #secret partner: appid: wx6d0ecc4e18710458 #小程序appId secret: 22afb006e9b94ee97c47bbfded9151eb #secret appid: wx6d0ecc4e18710458 #小程序appId secret: 22afb006e9b94ee97c47bbfded9151eb #secret supplier: appid: wx3203fd935a6ffe09 #小程序appId secret: 9121c703fb0c416b21a8c289dd73ae9b #secret appid: wx3203fd935a6ffe09 #小程序appId secret: 9121c703fb0c416b21a8c289dd73ae9b #secret sms: verificationCode: SMS_301300012 #验证码通用模版 src/main/resources/mapper/flower/FlowerDeleteMapper.xml
对比新文件 @@ -0,0 +1,37 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.mzl.flower.mapper.FlowerDeleteMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.mzl.flower.entity.FlowerDeleteDO"> <result column="id" property="id" /> <result column="deleted" property="deleted" /> <result column="create_by" property="createBy" /> <result column="create_time" property="createTime" /> <result column="update_by" property="updateBy" /> <result column="update_time" property="updateTime" /> <result column="category" property="category" /> <result column="unit" property="unit" /> <result column="color" property="color" /> <result column="name" property="name" /> <result column="cover" property="cover" /> <result column="banners" property="banners" /> <result column="video" property="video" /> <result column="level" property="level" /> <result column="supplier_id" property="supplierId" /> <result column="price" property="price" /> <result column="stock" property="stock" /> <result column="status" property="status" /> <result column="tags" property="tags" /> <result column="audit_remarks" property="auditRemarks" /> <result column="audit_time" property="auditTime" /> <result column="shown" property="shown" /> <result column="sales" property="sales" /> <result column="description" property="description" /> <result column="recommend" property="recommend" /> <result column="real_sales" property="realSales" /> <result column="recommend_rank" property="recommendRank" /> <result column="type_rank" property="typeRank" /> </resultMap> </mapper> src/main/resources/mapper/flower/FlowerMapper.xml
@@ -1,6 +1,13 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.mzl.flower.mapper.flower.FlowerMapper"> <delete id="deleteBatchPhysics"> DELETE FROM t_flower WHERE id IN <foreach collection="list" item="id" open="(" separator="," close=")"> #{id} </foreach> </delete> <select id="selectFlowerList" resultType="com.mzl.flower.dto.response.flower.FlowerListDTO"> SELECT f.*, s.name supplierName, st.name supplierType, fc.name categoryStr @@ -386,10 +393,32 @@ FROM t_browse_his c left join t_flower f on c.flower_id = f.id WHERE f.deleted = 0 and c.deleted = 0 and f.status != 'UP' and c.user_id = #{userId} </select> <select id="getDeletdFlowByIds" resultType="com.mzl.flower.entity.flower.Flower"> select * from t_flower WHERE id IN <foreach collection="list" item="id" open="(" separator="," close=")"> #{id} </foreach> </select> <update id="updateFlowerCategoryInfo"> update t_flower f, t_flower_category fc set f.unit = fc.unit, f.color = fc.color where f.category = fc.id and fc.id = #{category} </update> <update id="updateBatchTypeRank"> <foreach collection="list" item="item" separator=";"> UPDATE t_flower SET type_rank = #{item.typeRank} WHERE id = #{item.id} </foreach> </update> <update id="restoreFlowerBatch"> update t_flower set deleted = 0 WHERE id IN <foreach collection="list" item="id" open="(" separator="," close=")"> #{id} </foreach> </update> </mapper>