秒杀 #3

Merged
czk merged 1 commits from czk into main 2024-04-24 14:41:49 +08:00
20 changed files with 707 additions and 4 deletions

View File

@ -0,0 +1,74 @@
package com.mall.common.domain.request;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.autoconfigure.batch.BatchDataSource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
*Spikes
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SpikesRequest {
/**
*
*/
private String spikesImg;
/**
*
*/
private String spikesManyImg;
/**
*
*/
private String spikesTitle;
/**
*
*/
private String spikesThings;
/**
*
*/
private String spikesUnit;
/**
*
*/
private Integer spikesNum;
/**
*
*/
private Date createTime;
/**
*
*/
private Date endTime;
/**
* (01)
*/
private Integer spikesState;
/**
* spuId
*/
private Long spuId;
/**
*
*/
private List<Sku> skuList;
@Data
public static class Sku{
private Long skuId; //商品id
private BigDecimal activityPrice; //秒杀价格
private Integer inventoryRestrict; //限制数量
}
}

View File

@ -0,0 +1,92 @@
package com.mall.common.domain.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.Date;
/**
*Vo
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ActivitySkuVo {
/**
* id
*/
private Long id;
/**
* spuId
*/
private Long spuId;
/**
* sku
*/
private String name;
/**
* id
*/
private Long categoryId;
/**
* id
*/
private Long brandId;
/**
*
*/
private String defaultImage;
/**
*
*/
private String title;
/**
*
*/
private String subtitle;
/**
*
*/
private BigDecimal price;
/**
*
*/
private BigDecimal activityPrice;
/**
*
*/
private Integer weight;
/**
*
*/
private Integer inventory;
/**
*
*/
private Integer inventoryRestrict;
/**
* id0
*/
private Integer spikesId;
/**
* id0
*/
private Integer bargainId;
/**
* id0
*/
private Integer groupId;
/**
*
*/
private Date startTime;
/**
*
*/
private Date endTime;
}

View File

@ -52,10 +52,10 @@
<version>1.2</version>
</dependency>
<!-- seata事务-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-alibaba-seata</artifactId>-->
<!-- </dependency>-->
<!-- canal-->
<dependency>
<groupId>top.javatool</groupId>

View File

@ -0,0 +1,13 @@
package com.mall.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
*server
*/
@SpringBootApplication
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class,args);
}
}

View File

@ -0,0 +1,39 @@
package com.mall.server.aop;
import com.mall.common.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Map;
/**
*aop
*/
@Aspect
@Component
@Slf4j
public class LogAnnotationAspect {
@Pointcut("execution(* com.mall.server.service.impl.*.*(..))")
private void allMethod(){}
//应用周围通知
@Around("allMethod()")
public void doAround(ProceedingJoinPoint call) throws Throwable{
long start = new Date().getTime();
String methodName = call.getSignature().getName(); // 获取方法名
Object[] args = call.getArgs(); // 获取方法的参数
call.proceed();
long end = new Date().getTime();
log.info("耗时:"+(end-start)/1000+"秒");
log.info(methodName+"()方法执行");
for (Object arg : args) {
log.info("参数:"+String.valueOf(arg));
}
}
}

View File

@ -0,0 +1,30 @@
package com.mall.server.controller;
import com.mall.common.domain.request.SpikesRequest;
import com.mall.common.result.Result;
import com.mall.server.service.SpikesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
*controller
*/
@RestController
@RequestMapping("spikes")
public class SpikesController {
@Autowired
private SpikesService spikesService;
/**
*
* @param spikesRequest
* @return
*/
@PostMapping("add")
public Result add(@RequestBody SpikesRequest spikesRequest){
return spikesService.add(spikesRequest);
}
}

View File

@ -0,0 +1,84 @@
package com.mall.server.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
*Sku
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("pms_sku")
public class SkuEntity {
/**
* id
*/
private Long id;
/**
* spuId
*/
private Long spuId;
/**
* sku
*/
private String name;
/**
* id
*/
private Long categoryId;
/**
* id
*/
private Long brandId;
/**
*
*/
private String defaultImage;
/**
*
*/
private String title;
/**
*
*/
private String subtitle;
/**
*
*/
private BigDecimal price;
/**
*
*/
private BigDecimal activityPrice;
/**
*
*/
private Integer weight;
/**
*
*/
private Integer inventory;
/**
*
*/
private Integer inventoryRestrict;
/**
* id0
*/
private Integer spikesId;
/**
* id0
*/
private Integer bargainId;
/**
* id0
*/
private Integer groupId;
}

View File

@ -0,0 +1,67 @@
package com.mall.server.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
*
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("pms_spikes")
public class SpikesEntity {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long spikesId;
/**
*
*/
private String spikesImg;
/**
*
*/
private String spikesManyImg;
/**
*
*/
private String spikesTitle;
/**
*
*/
private String spikesThings;
/**
*
*/
private String spikesUnit;
/**
*
*/
private Integer spikesNum;
/**
*
*/
private Date createTime;
/**
*
*/
private Date endTime;
/**
* (01)
*/
private Integer spikesState;
/**
* 01
*/
private Integer isDelete;
}

View File

@ -0,0 +1,52 @@
package com.mall.server.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
*Spu
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("pms_spu")
public class SpuEntity {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
*
*/
private String name;
/**
*id
*/
private Long categoryId;
/**
*id
*/
private Long brandId;
/**
*[0 - 1 - ]
*/
private Integer publishStatus;
/**
*
*/
private Date createTime;
/**
*
*/
private Date updateTime;
}

View File

@ -0,0 +1,38 @@
package com.mall.server.enumerate;
import lombok.Data;
/**
*
*/
public enum ActivityEnum {
SPIKES(0,"秒杀未开启"),
BARGAIN(0,"砍价未开启"),
GROUP(0,"拼团未开启");
private Integer code;
private String msg;
ActivityEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

View File

@ -0,0 +1,12 @@
package com.mall.server.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mall.server.domain.SkuEntity;
import org.apache.ibatis.annotations.Mapper;
/**
*SkuMapperr
*/
@Mapper
public interface SkuMapper extends BaseMapper<SkuEntity> {
}

View File

@ -0,0 +1,12 @@
package com.mall.server.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mall.server.domain.SpikesEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* mapper
*/
@Mapper
public interface SpikesMapper extends BaseMapper<SpikesEntity> {
}

View File

@ -0,0 +1,12 @@
package com.mall.server.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mall.server.domain.SpuEntity;
import org.apache.ibatis.annotations.Mapper;
/**
*spuMapper
*/
@Mapper
public interface SpuMapper extends BaseMapper<SpuEntity> {
}

View File

@ -0,0 +1,10 @@
package com.mall.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mall.server.domain.SkuEntity;
/**
*SkuService
*/
public interface SkuService extends IService<SkuEntity> {
}

View File

@ -0,0 +1,14 @@
package com.mall.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mall.common.domain.request.SpikesRequest;
import com.mall.common.result.Result;
import com.mall.server.domain.SpikesEntity;
/**
*service
*/
public interface SpikesService extends IService<SpikesEntity> {
Result add(SpikesRequest spikesRequest);
}

View File

@ -0,0 +1,10 @@
package com.mall.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mall.server.domain.SpuEntity;
/**
*spuService
*/
public interface SpuService extends IService<SpuEntity> {
}

View File

@ -0,0 +1,14 @@
package com.mall.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mall.server.domain.SkuEntity;
import com.mall.server.mapper.SkuMapper;
import com.mall.server.service.SkuService;
import org.springframework.stereotype.Service;
/**
*SkuServiceImpl
*/
@Service
public class SkuServiceImpl extends ServiceImpl<SkuMapper, SkuEntity>
implements SkuService {
}

View File

@ -0,0 +1,107 @@
package com.mall.server.service.impl;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mall.common.domain.request.SpikesRequest;
import com.mall.common.domain.vo.ActivitySkuVo;
import com.mall.common.redis.RedisCache;
import com.mall.common.result.Result;
import com.mall.server.domain.SkuEntity;
import com.mall.server.domain.SpikesEntity;
import com.mall.server.enumerate.ActivityEnum;
import com.mall.server.mapper.SpikesMapper;
import com.mall.server.service.SkuService;
import com.mall.server.service.SpikesService;
import com.mall.server.service.SpuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundZSetOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
*serviceImpl
*/
@Service
public class SpikesServiceImpl extends ServiceImpl<SpikesMapper, SpikesEntity>
implements SpikesService {
@Autowired
private SpikesMapper spikesMapper;
@Autowired
private SpuService spuService;
@Autowired
private SkuService skuService;
@Autowired
private RedisCache redisCache;
@Autowired
private RedisTemplate redisTemplate;
@Transactional
@Override
public Result add(SpikesRequest spikesRequest) {
//秒杀表信息
int spikesId = spikesMapper.insert(
SpikesEntity.builder()
.spikesImg(spikesRequest.getSpikesImg())
.spikesManyImg(spikesRequest.getSpikesManyImg())
.spikesTitle(spikesRequest.getSpikesTitle())
.spikesThings(spikesRequest.getSpikesThings())
.spikesUnit(spikesRequest.getSpikesUnit())
.spikesNum(spikesRequest.getSpikesNum())
.createTime(spikesRequest.getCreateTime())
.endTime(spikesRequest.getEndTime())
.spikesState(spikesRequest.getSpikesState())
.build()
);
//修改sku商品信息
skuService.updateBatchById(
spikesRequest.getSkuList().stream().map(c->
SkuEntity.builder()
.id(c.getSkuId())
.inventoryRestrict(c.getInventoryRestrict())
.activityPrice(c.getActivityPrice())
.spikesId(spikesId).build()
).collect(Collectors.toList())
);
//遍历修改后的sku商品信息作转换
List<ActivitySkuVo> activitySkuVoList = skuService.list(
new LambdaQueryWrapper<SkuEntity>()
.eq(SkuEntity::getSpikesId, spikesId)
).stream().map(c ->
ActivitySkuVo.builder()
.id(c.getId())
.spuId(c.getSpuId())
.name(c.getName())
.categoryId(c.getCategoryId())
.brandId(c.getBrandId())
.defaultImage(c.getDefaultImage())
.title(c.getTitle())
.subtitle(c.getSubtitle())
.price(c.getPrice())
.activityPrice(c.getActivityPrice())
.weight(c.getWeight())
.inventory(c.getInventory())
.inventoryRestrict(c.getInventoryRestrict())
.spikesId(c.getSpikesId())
.bargainId(c.getBargainId())
.groupId(c.getGroupId())
.startTime(spikesRequest.getCreateTime())
.endTime(spikesRequest.getEndTime()).build()).collect(Collectors.toList());
activitySkuVoList.forEach(c->{
//redis秒杀信息存在时间
long expire = c.getEndTime().getTime() - System.currentTimeMillis()/1000/1000;
redisCache.setCacheObject("spikes_"+c.getId(),c,expire, TimeUnit.MINUTES);
});
return Result.success(true,"添加秒杀成功");
}
}

View File

@ -0,0 +1,16 @@
package com.mall.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mall.server.domain.SpuEntity;
import com.mall.server.mapper.SpuMapper;
import com.mall.server.service.SpuService;
import org.springframework.stereotype.Service;
/**
*spuServiceImpl
*/
@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, SpuEntity>
implements SpuService {
}

View File

@ -0,0 +1,7 @@
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mall.common.config.MybatisPlusConfig,\
com.mall.common.config.RedisConfig,\
com.mall.common.redis.RedisCache,\
com.mall.common.config.ThreadPoolConfig,\
com.mall.common.handler.GlobalExceptionHandler