Compare commits

...

3 Commits

Author SHA1 Message Date
liuzhehao c2c0df10b6 登录 2024-04-25 10:53:52 +08:00
czk e0ba3f4023 Merge pull request '秒杀' (#3) from czk into main
Reviewed-on: #3
2024-04-24 14:41:49 +08:00
czk d9237a949b 秒杀 2024-04-24 14:39:01 +08:00
37 changed files with 1542 additions and 10 deletions

View File

@ -0,0 +1,31 @@
package com.mall.auth.config;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
@Log4j2
public class ConfirmCallbackConfig implements RabbitTemplate.ConfirmCallback {
@Autowired
private RabbitTemplate rabbitTemplate;
@PostConstruct
public void init(){
rabbitTemplate.setConfirmCallback(this);
}
@Override
public void confirm(CorrelationData correlationData, boolean b, String s) {
if(b){//消费者投递broker 状态,true表示成功
log.info("消息发送成功!");
}else{
log.error("消息发送异常,异常原因:{}",s);
}
}
}

View File

@ -0,0 +1,27 @@
package com.mall.auth.config;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class ReturnCallbackConfig implements RabbitTemplate.ReturnsCallback {
@Autowired
private RabbitTemplate rabbitTemplate;
@PostConstruct
public void init(){
rabbitTemplate.setReturnsCallback(this);
}
@Override
public void returnedMessage(ReturnedMessage returnedMessage) {
System.out.println("消息"+returnedMessage.getMessage().toString()+"被交换机"+returnedMessage.getExchange()+"回退!"
+"退回原因为:"+returnedMessage.getReplyText());
}
}

View File

@ -0,0 +1,80 @@
package com.mall.auth.controller;
import com.mall.auth.service.AuthService;
import com.mall.common.domain.UserInfo;
import com.mall.common.domain.request.LoginRequest;
import com.mall.common.domain.vo.LoginVo;
import com.mall.common.domain.vo.UserInfoVo;
import com.mall.common.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* @Author: lzh
* @CreateTime: 2024-04-22 17:00
* @Description: TODO
* @Version: 1.0
*/
@RestController
@Slf4j
public class AuthController {
@Autowired
private AuthService authService;
/**
*
* @param loginVo
* @return Result
*/
@PostMapping("/login")
public Result login(@RequestBody LoginVo loginVo){
Result result = authService.login(loginVo);
return result;
}
/**
*
* @param loginRequest
* @return Result
*/
@PostMapping("send/code/{phone}")
public Result sendCode(@RequestBody LoginRequest loginRequest){
Result result = authService.sendCode(loginRequest);
return result;
}
/**
*
* @param loginRequest
* @return Result
*/
@PostMapping("phoneLogin")
public Result phoneLogin(@RequestBody LoginRequest loginRequest) {
Result result = authService.phoneLogin(loginRequest);
return result;
}
/**
*
* @param userInfoVo
* @return Result
*/
@PostMapping("phoneRegister")
public Result phoneRegister(@RequestBody UserInfoVo userInfoVo) {
Result result = authService.phoneRegister(userInfoVo);
return result;
}
/**
*
* @return Result
*/
@GetMapping("getUserInfo/{userId}")
public Result<UserInfo> userInfo() {
Result<UserInfo> result = authService.userInfo();
return result;
}
}

View File

@ -0,0 +1,24 @@
package com.mall.auth.feign;
import com.mall.common.domain.UserInfo;
import com.mall.common.result.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
/**
* @Author: lzh
* @CreateTime: 2024-04-22 17:16
* @Description: TODO
* @Version: 1.0
*/
@FeignClient(name = "czk-user")
public interface UserServiceFeign {
@PostMapping("findLogin/{username}/{password}")
public Result<UserInfo> findLogin(@PathVariable String username,@PathVariable String password);
@GetMapping("findPhone/{phone}")
public Result<UserInfo> findPhone(@PathVariable("phone") String phone);
@PostMapping("register")
public Result<UserInfo> register(@RequestBody UserInfo userInfo);
}

View File

@ -0,0 +1,19 @@
package com.mall.auth.service;
import com.mall.common.domain.UserInfo;
import com.mall.common.domain.request.LoginRequest;
import com.mall.common.domain.vo.LoginVo;
import com.mall.common.domain.vo.UserInfoVo;
import com.mall.common.result.Result;
public interface AuthService {
Result login(LoginVo loginVo);
Result sendCode(LoginRequest loginRequest);
Result phoneLogin(LoginRequest loginRequest);
Result phoneRegister(UserInfoVo userInfo);
Result<UserInfo> userInfo();
}

View File

@ -0,0 +1,160 @@
package com.mall.auth.service.impl;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.mall.auth.feign.UserServiceFeign;
import com.mall.auth.service.AuthService;
import com.mall.common.constant.JwtConstants;
import com.mall.common.constant.RabbitConstants;
import com.mall.common.constant.TokenConstants;
import com.mall.common.domain.UserInfo;
import com.mall.common.domain.request.LoginRequest;
import com.mall.common.domain.response.JwtResponse;
import com.mall.common.domain.vo.LoginVo;
import com.mall.common.domain.vo.UserInfoVo;
import com.mall.common.redis.RedisCache;
import com.mall.common.result.BizException;
import com.mall.common.result.Result;
import com.mall.common.utils.IdUtils;
import com.mall.common.utils.JwtUtils;
import com.mall.common.utils.StringUtils;
import io.jsonwebtoken.lang.Assert;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* @Author: lzh
* @CreateTime: 2024-04-22 17:01
* @Description: TODO
* @Version: 1.0
*/
@Service
@Log4j2
public class AuthServiceImpl implements AuthService {
@Resource
private RedisCache redisCache;
@Autowired
private HttpServletRequest request;
@Autowired
private UserServiceFeign userServiceFeign;
@Autowired
private RabbitTemplate rabbitTemplate;
@Override
public Result login(LoginVo loginVo) {
Result<UserInfo> result = userServiceFeign.findLogin(loginVo.getUsername(),loginVo.getPassword());
UserInfo data = result.getData();
Assert.notNull(
data,"用户不存在"
);
// String password = SecureUtil.md5(
// loginVo.getPassword()+ "|" + data.getSalt()
// );
if (!loginVo.getPassword().equals(data.getPassword())){
throw new BizException("密码错误");
}
HashMap<String, Object> map = new HashMap<>();
map.put(JwtConstants.USER_KEY,data.getId());
String token = JwtUtils.createToken(map);
redisCache.setCacheObject(TokenConstants.LOGIN_TOKEN_KEY+token,data,TokenConstants.EXPIRATION, TimeUnit.HOURS);
JwtResponse jwtResponse = new JwtResponse();
jwtResponse.setToken(token);
jwtResponse.setEndTim(TokenConstants.EXPIRATION);
return Result.success(jwtResponse);
}
@Override
public Result sendCode(LoginRequest loginRequest) {
Result<UserInfo> result = userServiceFeign.findPhone(loginRequest.getPhone());
UserInfo data = result.getData();
Assert.notNull(
data,"请注册"
);
String code = RandomUtil.randomNumbers(6);
redisCache.setCacheObject("send_code"+loginRequest.getPhone(),code);
//rabbitTemplate发消息
// rabbitTemplate.convertAndSend(RabbitConstants.SEND_CODE_BY_PHONE,"",message -> {
// message.getMessageProperties().setMessageId(UUID.randomUUID().toString().replaceAll("-",""));
// return message;
// });
return Result.success("发送成功,验证码为:"+code);
}
@Override
public Result phoneLogin(LoginRequest loginRequest) {
Result<UserInfo> result = userServiceFeign.findPhone(loginRequest.getPhone());
UserInfo data = result.getData();
Assert.notNull(
data,"请注册"
);
if (StringUtils.isAllBlank(loginRequest.getCode(),loginRequest.getCode())){
throw new BizException(408,"手机号验证码为空");
}
String code = redisCache.getCacheObject("send_code" + loginRequest.getPhone());
if (StringUtils.isBlank(code)){
throw new BizException(408,"验证码已过期");
}
if (!loginRequest.getCode().equals(code)){
throw new BizException(408,"验证码错误");
}
HashMap<String, Object> map = new HashMap<>();
String userKey = IdUtils.genId();
map.put(JwtConstants.USER_KEY,userKey);
String token = JwtUtils.createToken(map);
redisCache.setCacheObject(TokenConstants.LOGIN_TOKEN_KEY+token,data,TokenConstants.EXPIRATION, TimeUnit.HOURS);
JwtResponse jwtResponse = new JwtResponse();
jwtResponse.setToken(token);
jwtResponse.setEndTim(TokenConstants.EXPIRATION);
return Result.success(jwtResponse);
}
@Override
public Result phoneRegister(UserInfoVo userInfoVo) {
String salt = RandomUtil.randomNumbers(6);
String password = SecureUtil.md5(userInfoVo.getPassword()+ "|" + salt);
UserInfo userInfo = UserInfo.builder()
.username(userInfoVo.getUsername())
.password(password)
.salt(salt)
.nickname(userInfoVo.getNickname())
.phone(userInfoVo.getPhone())
.email(userInfoVo.getEmail())
.header(userInfoVo.getHeader())
.gender(userInfoVo.getGender())
.birthday(userInfoVo.getBirthday())
.city(userInfoVo.getCity())
.role(userInfoVo.getRole())
.sign(userInfoVo.getSign())
.sourceType(userInfoVo.getSourceType())
.integration(userInfoVo.getIntegration())
.status(userInfoVo.getStatus())
.identityFront(userInfoVo.getIdentityFront())
.identityReverse(userInfoVo.getIdentityReverse())
.identityAuthentication(userInfoVo.getIdentityAuthentication())
.checkState(userInfoVo.getCheckState())
.createTime(new Date())
.build();
userServiceFeign.register(userInfo);
return Result.success("注册成功");
}
@Override
public Result<UserInfo> userInfo() {
String token = request.getHeader(TokenConstants.LOGIN_TOKEN_KEY);
if (StringUtils.isBlank(token)){
throw new BizException(401,"未登录");
}
UserInfo userInfo = redisCache.getCacheObject(TokenConstants.LOGIN_TOKEN_KEY + token);
return Result.success(userInfo);
}
}

View File

@ -78,12 +78,12 @@
<!-- <version>3.3.0</version>-->
<!-- </dependency>-->
<!--糊涂工具-->
<!-- <dependency>-->
<!-- <groupId>cn.hutool</groupId>-->
<!-- <artifactId>hutool-all</artifactId>-->
<!-- <version>4.1.1</version>-->
<!-- </dependency>-->
<!-- FastJson2 json工具 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.1.1</version>
</dependency>
<!--FastJson2 json工具-->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
@ -153,6 +153,21 @@
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.83</version>
</dependency>
<!--RabbitMQ依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>2.0.1</version>
</dependency>
</dependencies>

View File

@ -0,0 +1,107 @@
package com.mall.common.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.models.auth.In;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("user_info")
public class UserInfo {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
*
*/
private String username;
/**
*
*/
private String password;
/**
*
*/
private String salt;
/**
*
*/
private String nickname;
/**
*
*/
private String phone;
/**
*
*/
private String email;
/**
*
*/
private String header;
/**
*
*/
private Integer gender;
/**
*
*/
private Date birthday;
/**
*
*/
private String city;
/**
*
*/
private String role;
/**
*
*/
private String sign;
/**
*
*/
private Integer sourceType;
/**
*
*/
private int integration;
/**
*
*/
private Integer status;
/**
*
*/
private String identityFront;
/**
*
*/
private String identityReverse;
/**
*
*/
private String identityAuthentication;
/**
*
*/
private Integer checkState;
/**
*
*/
private Date createTime;
}

View File

@ -0,0 +1,15 @@
package com.mall.common.domain.request;
import lombok.Data;
/**
* @Author: lzh
* @CreateTime: 2024-04-22 18:48
* @Description: TODO
* @Version: 1.0
*/
@Data
public class LoginRequest {
private String phone;
private String code;
}

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,21 @@
package com.mall.common.domain.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: lzh
* @CreateTime: 2024-04-22 18:34
* @Description: TODO
* @Version: 1.0
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class JwtResponse {
private String token;
private Long endTim;
}

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

@ -0,0 +1,15 @@
package com.mall.common.domain.vo;
import lombok.Data;
/**
* @Author: lzh
* @CreateTime: 2024-04-22 17:03
* @Description: TODO
* @Version: 1.0
*/
@Data
public class LoginVo {
private String username;
private String password;
}

View File

@ -0,0 +1,105 @@
package com.mall.common.domain.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* @Author: lzh
* @CreateTime: 2024-04-22 19:45
* @Description: TODO
* @Version: 1.0
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserInfoVo {
/**
* id
*/
private Long id;
/**
*
*/
private String username;
/**
*
*/
private String password;
/**
*
*/
private String salt;
/**
*
*/
private String nickname;
/**
*
*/
private String phone;
/**
*
*/
private String email;
/**
*
*/
private String header;
/**
*
*/
private Integer gender;
/**
*
*/
private Date birthday;
/**
*
*/
private String city;
/**
*
*/
private String role;
/**
*
*/
private String sign;
/**
*
*/
private Integer sourceType;
/**
*
*/
private int integration;
/**
*
*/
private Integer status;
/**
*
*/
private String identityFront;
/**
*
*/
private String identityReverse;
/**
*
*/
private String identityAuthentication;
/**
*
*/
private Integer checkState;
/**
*
*/
private Date createTime;
}

View File

@ -0,0 +1,87 @@
package com.mall.common.utils;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import lombok.extern.log4j.Log4j2;
import java.util.Map;
/**
*
*/
@Log4j2
public class TelSmsUtils {
/**
* AccessKeyaccessKeySecretAPI访
*/
private static String accessKeyId = "LTAIEVXszCmcd1T5";
private static String accessKeySecret = "2zHwciQXln8wExSEnkIYtRTSwLeRNd";
/**
* 访
*/
private static String endpoint = "dysmsapi.aliyuncs.com";
/**
*
*/
private static String signName = "登录验证";
/**
*
*/
private static Client client;
static {
log.info("初始化短信服务开始");
long startTime = System.currentTimeMillis();
try {
client = initClient();
log.info("初始化短信成功:{}",signName);
} catch (Exception e) {
e.printStackTrace();
}
log.info("初始化短信服务结束:耗时:{}MS",(System.currentTimeMillis()-startTime));
}
/**
*
* @return
* @throws Exception
*/
private static Client initClient() throws Exception{
Config config = new Config()
// 您的AccessKey ID
.setAccessKeyId(accessKeyId)
// 您的AccessKey Secret
.setAccessKeySecret(accessKeySecret);
// 访问的域名
config.endpoint = endpoint;
return new Client(config);
}
/**
*
* @param tel
* @param templateCode SMS_153991546
* @param sendDataMap
*/
public static String sendSms(String tel , String templateCode , Map<String,String> sendDataMap){
SendSmsRequest sendSmsRequest = new SendSmsRequest()
.setPhoneNumbers(tel)
.setSignName(signName)
.setTemplateCode(templateCode)
.setTemplateParam(JSONObject.toJSONString(sendDataMap));
SendSmsResponse sendSmsResponse = null;
try {
log.info("发送短信验证码:消息内容是:【{}】", JSONObject.toJSONString(sendDataMap));
sendSmsResponse = client.sendSms(sendSmsRequest);
} catch (Exception e) {
log.error("短信发送异常,手机号:【{}】,短信内容:【{}】,异常信息:【{}】", tel, sendDataMap, e);
}
return JSONObject.toJSONString(sendSmsResponse.getBody());
}
}

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

View File

@ -0,0 +1,55 @@
package com.mall.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mall.common.domain.UserInfo;
import com.mall.common.result.Result;
import com.mall.system.service.UserService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* @Author: lzh
* @CreateTime: 2024-04-22 17:05
* @Description: TODO
* @Version: 1.0
*/
@RestController
public class UserController {
@Resource
private UserService userService;
/**
*
* @return userInfo
*/
@PostMapping("findLogin/{username}/{password}")
public Result<UserInfo> findLogin(@PathVariable String username, @PathVariable String password){
LambdaQueryWrapper<UserInfo> userInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
userInfoLambdaQueryWrapper.eq(UserInfo::getUsername,username)
.eq(UserInfo::getPassword,password);
UserInfo userInfo = userService.getOne(userInfoLambdaQueryWrapper);
return Result.success(userInfo);
}
/**
*
* @return userInfo
*/
@GetMapping("findPhone/{phone}")
public Result<UserInfo> findPhone(@PathVariable("phone") String phone){
Result result = userService.findPhone(phone);
return result;
}
/**
*
* @return userInfo
*/
@PostMapping("register")
public Result<UserInfo> register(@RequestBody UserInfo userInfo){
userService.register(userInfo);
return Result.success();
}
}

View File

@ -0,0 +1,15 @@
package com.mall.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mall.common.domain.UserInfo;
import org.mapstruct.Mapper;
/**
* @Author: lzh
* @CreateTime: 2024-04-22 17:13
* @Description: TODO
* @Version: 1.0
*/
@Mapper
public interface UserMapper extends BaseMapper<UserInfo> {
}

View File

@ -0,0 +1,12 @@
package com.mall.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mall.common.domain.UserInfo;
import com.mall.common.result.Result;
public interface UserService extends IService<UserInfo> {
Result findPhone(String phone);
void register(UserInfo userInfo);
}

View File

@ -0,0 +1,41 @@
package com.mall.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mall.common.domain.UserInfo;
import com.mall.common.result.Result;
import com.mall.system.mapper.UserMapper;
import com.mall.system.service.UserService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @Author: lzh
* @CreateTime: 2024-04-22 17:06
* @Description: TODO
* @Version: 1.0
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserInfo>
implements UserService {
@Resource
private UserMapper userMapper;
@Override
public Result findPhone(String phone) {
UserInfo userInfo = this.getOne(new QueryWrapper<UserInfo>().lambda()
.eq(UserInfo::getPhone, phone));
return Result.success(userInfo);
}
@Override
public void register(UserInfo userInfo) {
//校验手机号
if (this.getOne(new QueryWrapper<UserInfo>().lambda()
.eq(UserInfo::getPhone, userInfo.getPhone())) != null) {
throw new RuntimeException("手机号已存在");
}
this.save(userInfo);
}
}