身份验证
parent
aa0a5492e3
commit
403b4c34c8
|
@ -2,14 +2,13 @@ package com.group.auth.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.group.auth.feign.UserService;
|
|
||||||
import com.group.auth.service.AuthService;
|
import com.group.auth.service.AuthService;
|
||||||
import com.group.auth.strategy.LoginContext;
|
import com.group.auth.strategy.LoginContext;
|
||||||
import com.group.auth.strategy.LoginType;
|
import com.group.auth.strategy.LoginType;
|
||||||
import com.group.common.config.JwtUtils;
|
import com.group.common.config.JwtUtils;
|
||||||
import com.group.common.constants.JwtConstants;
|
import com.group.common.constants.JwtConstants;
|
||||||
import com.group.common.constants.TokenConstants;
|
import com.group.common.constants.TokenConstants;
|
||||||
import com.group.common.domin.UserEntity;
|
import com.group.common.domin.pojo.UserEntity;
|
||||||
import com.group.common.domin.request.ReqLogin;
|
import com.group.common.domin.request.ReqLogin;
|
||||||
import com.group.common.redis.RedisCache;
|
import com.group.common.redis.RedisCache;
|
||||||
import com.group.common.result.R;
|
import com.group.common.result.R;
|
||||||
|
@ -17,7 +16,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.group.auth.strategy;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.group.auth.feign.UserService;
|
import com.group.auth.feign.UserService;
|
||||||
import com.group.common.domin.UserEntity;
|
import com.group.common.domin.pojo.UserEntity;
|
||||||
import com.group.common.domin.request.ReqLogin;
|
import com.group.common.domin.request.ReqLogin;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
|
@ -2,9 +2,8 @@ package com.group.auth.strategy;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.group.auth.feign.UserService;
|
import com.group.auth.feign.UserService;
|
||||||
import com.group.common.domin.UserEntity;
|
import com.group.common.domin.pojo.UserEntity;
|
||||||
import com.group.common.domin.request.ReqLogin;
|
import com.group.common.domin.request.ReqLogin;
|
||||||
import com.group.common.handle.BizException;
|
|
||||||
import com.group.common.redis.RedisCache;
|
import com.group.common.redis.RedisCache;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.group.auth.strategy;
|
package com.group.auth.strategy;
|
||||||
|
|
||||||
import com.group.common.domin.UserEntity;
|
import com.group.common.domin.pojo.UserEntity;
|
||||||
import com.group.common.domin.request.ReqLogin;
|
import com.group.common.domin.request.ReqLogin;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
<!-- bootstrap 启动器 -->
|
<!-- bootstrap 启动器 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
@ -134,5 +138,15 @@
|
||||||
<artifactId>xxl-job-core</artifactId>
|
<artifactId>xxl-job-core</artifactId>
|
||||||
<version>2.3.0</version>
|
<version>2.3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.redisson</groupId>
|
||||||
|
<artifactId>redisson</artifactId>
|
||||||
|
<version>3.16.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun.oss</groupId>
|
||||||
|
<artifactId>aliyun-sdk-oss</artifactId>
|
||||||
|
<version>3.15.1</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
|
@ -1,4 +1,4 @@
|
||||||
package com.group.user.pojo;
|
package com.group.common.domin.pojo;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.group.common.domin.pojo;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀订单表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("t_kill_order")
|
||||||
|
public class KillOrderEntity {
|
||||||
|
/**
|
||||||
|
* 秒杀订单主键
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Integer id ;
|
||||||
|
/**
|
||||||
|
* 秒杀商品id
|
||||||
|
*/
|
||||||
|
private Integer goodsId ;
|
||||||
|
/**
|
||||||
|
* 购买人id
|
||||||
|
*/
|
||||||
|
private Integer userId ;
|
||||||
|
/**
|
||||||
|
* 秒杀订单编号
|
||||||
|
*/
|
||||||
|
private String killId ;
|
||||||
|
/**
|
||||||
|
* 秒杀订单状态 1-未支付 2-支付成功 3-支付失败
|
||||||
|
*/
|
||||||
|
private Integer killState ;
|
||||||
|
/**
|
||||||
|
* 秒杀订单创建时间
|
||||||
|
*/
|
||||||
|
private Date orderCreate ;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.group.common.domin.pojo;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单支付详情类
|
||||||
|
*/
|
||||||
|
@TableName("t_pay_detail")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class PayDetail {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Integer payId ;
|
||||||
|
/**
|
||||||
|
* 订单支付金额
|
||||||
|
*/
|
||||||
|
@TableField("pay_title")
|
||||||
|
private BigDecimal payTitle ;
|
||||||
|
/**
|
||||||
|
* 订单id
|
||||||
|
*/
|
||||||
|
@TableField("pay_order")
|
||||||
|
private Integer payOrder ;
|
||||||
|
/**
|
||||||
|
* 支付宝编号
|
||||||
|
*/
|
||||||
|
@TableField("pay_pay")
|
||||||
|
private String payPay ;
|
||||||
|
/**
|
||||||
|
* 明细状态 1-待支付 2-已支付 3-支付失败
|
||||||
|
*/
|
||||||
|
@TableField("pay_state")
|
||||||
|
private Integer payState ;
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@TableField("pay_create")
|
||||||
|
private Date payCreate ;
|
||||||
|
/**
|
||||||
|
* 支付时间
|
||||||
|
*/
|
||||||
|
@TableField("pay_payed")
|
||||||
|
private Date payPayed ;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.group.user.pojo;
|
package com.group.common.domin.pojo;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.group.common.domin.pojo;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀表
|
||||||
|
|
||||||
|
*
|
||||||
|
* @author song
|
||||||
|
* @email song@gmail.com
|
||||||
|
* @date 2024-04-20 10:24:59
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("t_seckill")
|
||||||
|
public class SeckillEntity implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀id
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Integer seckillId;
|
||||||
|
/**
|
||||||
|
* 商品详情id
|
||||||
|
*/
|
||||||
|
private Integer seckillGoodsDetail;
|
||||||
|
/**
|
||||||
|
* 秒杀活动商品库存
|
||||||
|
*/
|
||||||
|
private String seckillInventory;
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Date seckillCreate;
|
||||||
|
/**
|
||||||
|
* 秒杀价格
|
||||||
|
*/
|
||||||
|
private BigDecimal seckillPrice;
|
||||||
|
/**
|
||||||
|
* 场次id
|
||||||
|
*/
|
||||||
|
private Integer sessionId;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.group.common.domin.pojo;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 场次实体表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("t_session")
|
||||||
|
public class SessionEntity {
|
||||||
|
/**
|
||||||
|
* 场次id
|
||||||
|
*/
|
||||||
|
private Integer sessionId;
|
||||||
|
/**
|
||||||
|
* 场次开始id
|
||||||
|
*/
|
||||||
|
private Date sessionBegin;
|
||||||
|
/**
|
||||||
|
* 场次结束id
|
||||||
|
*/
|
||||||
|
private Date sessionEnd;
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package com.group.common.domin;
|
package com.group.common.domin.pojo;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
@ -29,34 +30,57 @@ public class UserEntity implements Serializable {
|
||||||
/**
|
/**
|
||||||
* 用户名
|
* 用户名
|
||||||
*/
|
*/
|
||||||
|
@TableField("user_name")
|
||||||
private String userName;
|
private String userName;
|
||||||
/**
|
/**
|
||||||
* 用户密码
|
* 用户密码
|
||||||
*/
|
*/
|
||||||
|
@TableField("user_pwd")
|
||||||
private String userPwd;
|
private String userPwd;
|
||||||
/**
|
/**
|
||||||
* 用户手机
|
* 用户手机
|
||||||
*/
|
*/
|
||||||
|
@TableField("user_phone")
|
||||||
private String userPhone;
|
private String userPhone;
|
||||||
/**
|
/**
|
||||||
* 会员登记
|
* 会员登记
|
||||||
*/
|
*/
|
||||||
|
@TableField("user_honor")
|
||||||
private Integer userHonor;
|
private Integer userHonor;
|
||||||
/**
|
/**
|
||||||
* 用户余额
|
* 用户余额
|
||||||
*/
|
*/
|
||||||
|
@TableField("user_residue")
|
||||||
private BigDecimal userResidue;
|
private BigDecimal userResidue;
|
||||||
/**
|
/**
|
||||||
* 用户积分
|
* 用户积分
|
||||||
*/
|
*/
|
||||||
|
@TableField("user_score")
|
||||||
private Integer userScore;
|
private Integer userScore;
|
||||||
/**
|
/**
|
||||||
* 用户角色(0-普通用户 1-团长 2-客服)
|
* 用户角色(0-普通用户 1-团长 2-客服)
|
||||||
*/
|
*/
|
||||||
|
@TableField("user_role")
|
||||||
private Integer userRole;
|
private Integer userRole;
|
||||||
/**
|
/**
|
||||||
* 用户地址
|
* 用户地址
|
||||||
*/
|
*/
|
||||||
|
@TableField("user_address")
|
||||||
private String userAddress;
|
private String userAddress;
|
||||||
|
/**
|
||||||
|
* 身份证号
|
||||||
|
*/
|
||||||
|
@TableField("user_card")
|
||||||
|
private String userCard;
|
||||||
|
/**
|
||||||
|
* 用户真实姓名
|
||||||
|
*/
|
||||||
|
@TableField("user_real_name")
|
||||||
|
private String userRealName;
|
||||||
|
/**
|
||||||
|
* 用户户籍所在地
|
||||||
|
*/
|
||||||
|
@TableField("user_real_address")
|
||||||
|
private String userRealAddress;
|
||||||
|
|
||||||
}
|
}
|
|
@ -257,4 +257,11 @@ public class RedisCache {
|
||||||
public Collection<String> keys (final String pattern) {
|
public Collection<String> keys (final String pattern) {
|
||||||
return redisTemplate.keys(pattern);
|
return redisTemplate.keys(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将键对应的值递减
|
||||||
|
*/
|
||||||
|
public void decreaseKey(String key){
|
||||||
|
redisTemplate.opsForValue().decrement(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.group.common.redis;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* redisson配置类
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class RedissonConfig {
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.group.common.util;
|
||||||
|
|
||||||
|
|
||||||
|
import com.group.common.constants.JwtConstants;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户工具类
|
||||||
|
*/
|
||||||
|
public class UserUtil {
|
||||||
|
public static Integer getUserId(HttpServletRequest servletRequest){
|
||||||
|
return Integer.valueOf(servletRequest.getHeader(JwtConstants.DETAILS_USER_ID));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,71 +0,0 @@
|
||||||
package com.group.gateway.config;
|
|
||||||
|
|
||||||
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
|
|
||||||
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
|
|
||||||
import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.core.Ordered;
|
|
||||||
import org.springframework.core.annotation.Order;
|
|
||||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
|
||||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecation: 网关限流控件
|
|
||||||
* @author DongZl
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
public class GatewaySentinelConfig {
|
|
||||||
/**
|
|
||||||
* 查看解析器
|
|
||||||
*/
|
|
||||||
private final List<ViewResolver> viewResolvers;
|
|
||||||
/**
|
|
||||||
* 服务器编解码器配置
|
|
||||||
*/
|
|
||||||
private final ServerCodecConfigurer serverCodecConfigurer;
|
|
||||||
public GatewaySentinelConfig(ObjectProvider<List<ViewResolver>> viewResolversProvider,
|
|
||||||
ServerCodecConfigurer serverCodecConfigurer) {
|
|
||||||
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
|
|
||||||
this.serverCodecConfigurer = serverCodecConfigurer;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Sentinel 网关块异常处理程序
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
|
||||||
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
|
|
||||||
// 给 Spring Cloud Gateway 注册块异常处理程序。
|
|
||||||
return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化网关配置
|
|
||||||
*/
|
|
||||||
@PostConstruct
|
|
||||||
public void doInit() {
|
|
||||||
initGatewayRules();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 配置限流规则
|
|
||||||
*/
|
|
||||||
private void initGatewayRules() {
|
|
||||||
Set<GatewayFlowRule> rules = new HashSet<>();
|
|
||||||
rules.add(new GatewayFlowRule("cloud-user")
|
|
||||||
// 限流阈值
|
|
||||||
.setCount(1)
|
|
||||||
// 统计时间窗口,单位是秒,默认是 1 秒
|
|
||||||
.setIntervalSec(5)
|
|
||||||
);
|
|
||||||
//添加到限流规则当中
|
|
||||||
GatewayRuleManager.loadRules(rules);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,6 +14,7 @@ spring:
|
||||||
allow-circular-references: true
|
allow-circular-references: true
|
||||||
# 允许定义相同的bean对象 去覆盖原有的
|
# 允许定义相同的bean对象 去覆盖原有的
|
||||||
allow-bean-definition-overriding: true
|
allow-bean-definition-overriding: true
|
||||||
|
web-application-type: reactive
|
||||||
cloud:
|
cloud:
|
||||||
nacos:
|
nacos:
|
||||||
discovery:
|
discovery:
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.group.user.config;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.group.common.result.R;
|
||||||
|
import com.group.user.pojo.SelfDTO;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.Console;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 身份检测实现类
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Log4j2
|
||||||
|
public class CheckLifeImpl {
|
||||||
|
|
||||||
|
|
||||||
|
@Value("${song.life.url}")
|
||||||
|
private String httpUrl;
|
||||||
|
|
||||||
|
@Value("${song.appCode}")
|
||||||
|
private String appCode;
|
||||||
|
|
||||||
|
public R checkLife(String url,String motions){
|
||||||
|
|
||||||
|
HashMap<String, Object> params = new HashMap<>();
|
||||||
|
params.put("complexity", "1");
|
||||||
|
params.put("motions", motions);
|
||||||
|
params.put("url", url);
|
||||||
|
String body = HttpRequest.post(httpUrl)
|
||||||
|
.header("Authorization", "APPCODE "+appCode)
|
||||||
|
.form(params)
|
||||||
|
.execute()
|
||||||
|
.body();
|
||||||
|
if (!new JSONObject(body).get("code").equals(200)){
|
||||||
|
return R.error("视频上传不合格,请重新上传");
|
||||||
|
}
|
||||||
|
log.info(body);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.group.user.config;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.http.HttpResponse;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.group.common.result.R;
|
||||||
|
import com.group.user.pojo.IdCardPeople;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 身份证照片
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Log4j2
|
||||||
|
public class IdCardConfig {
|
||||||
|
|
||||||
|
@Value("${song.appCode}")
|
||||||
|
private String appCode;
|
||||||
|
|
||||||
|
@Value("${song.card.host}")
|
||||||
|
private String host;
|
||||||
|
|
||||||
|
@Value("${song.card.path}")
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private OssConfig ossConfig;
|
||||||
|
|
||||||
|
public IdCardPeople checkCard(MultipartFile file,String side){
|
||||||
|
|
||||||
|
|
||||||
|
String fileString = ossConfig.upload(file);
|
||||||
|
|
||||||
|
|
||||||
|
//configure配置
|
||||||
|
JSONObject configObj = new JSONObject();
|
||||||
|
configObj.put("side", side);
|
||||||
|
configObj.put("quality_info",false);
|
||||||
|
String config_str = configObj.toString();
|
||||||
|
|
||||||
|
//拼装请求body的json字符串
|
||||||
|
JSONObject requestObj = new JSONObject();
|
||||||
|
requestObj.put("image",fileString);
|
||||||
|
if (!configObj.isEmpty()){
|
||||||
|
requestObj.put("configure",config_str);
|
||||||
|
}
|
||||||
|
String body = requestObj.toString();
|
||||||
|
|
||||||
|
String string = HttpRequest.post(host + path)
|
||||||
|
.header("Authorization", "APPCODE " + appCode)
|
||||||
|
.header("Content-Type", "application/json; charset=UTF-8")
|
||||||
|
.body(body)
|
||||||
|
.execute()
|
||||||
|
.body();
|
||||||
|
log.info(string);
|
||||||
|
|
||||||
|
IdCardPeople idCardPeople = null;
|
||||||
|
try {
|
||||||
|
idCardPeople = JSON.parseObject(string, IdCardPeople.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("身份证格式不对");
|
||||||
|
}
|
||||||
|
return idCardPeople;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.group.user.config;
|
||||||
|
|
||||||
|
import com.aliyun.oss.*;
|
||||||
|
import com.aliyun.oss.common.comm.ResponseMessage;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import com.aliyun.oss.common.auth.*;
|
||||||
|
import com.aliyun.oss.model.PutObjectRequest;
|
||||||
|
import com.aliyun.oss.model.PutObjectResult;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.ObjectInput;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* oss相关配置
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Log4j2
|
||||||
|
public class OssConfig {
|
||||||
|
|
||||||
|
@Value("${song.oss.endpoint}")
|
||||||
|
private String endpoint;
|
||||||
|
@Value("${song.oss.accessKeyId}")
|
||||||
|
private String accessKeyId;
|
||||||
|
@Value("${song.oss.secretAccessKey}")
|
||||||
|
private String secretAccessKey;
|
||||||
|
@Value("${song.oss.bucketName}")
|
||||||
|
private String bucketName;
|
||||||
|
@Value("${song.oss.objectName}")
|
||||||
|
private String objectName;
|
||||||
|
|
||||||
|
public String upload(MultipartFile file) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
InputStream stream = file.getInputStream();
|
||||||
|
|
||||||
|
String fileName = file.getOriginalFilename();
|
||||||
|
//创建oss实例
|
||||||
|
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, secretAccessKey);
|
||||||
|
|
||||||
|
//上传文件
|
||||||
|
PutObjectRequest request = new PutObjectRequest(bucketName, objectName + fileName, stream);
|
||||||
|
|
||||||
|
ossClient.putObject(request);
|
||||||
|
|
||||||
|
Date date = new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7);
|
||||||
|
|
||||||
|
return ossClient.generatePresignedUrl(bucketName, objectName + fileName, date).toString();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.group.user.config;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.group.common.result.R;
|
||||||
|
import com.group.user.pojo.IdCard;
|
||||||
|
import com.group.user.pojo.IdCardEntity;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 身份证和姓名的正确校验
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Log4j2
|
||||||
|
public class RealID {
|
||||||
|
|
||||||
|
@Value("${song.check.url}")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Value("${song.appCode}")
|
||||||
|
private String appCode;
|
||||||
|
|
||||||
|
public R checkId(IdCard idCard){
|
||||||
|
|
||||||
|
HashMap<String, Object> map = new HashMap<>();
|
||||||
|
map.put("realName",idCard.getRealName());
|
||||||
|
map.put("cardNo",idCard.getCardNo());
|
||||||
|
|
||||||
|
String body = HttpRequest.post(url)
|
||||||
|
.header("Authorization", "APPCODE " + appCode)
|
||||||
|
.header("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
|
||||||
|
.form(map)
|
||||||
|
.execute()
|
||||||
|
.body();
|
||||||
|
if (!new JSONObject(body).get("error_code").equals(0)){
|
||||||
|
return R.error("未通过检测");
|
||||||
|
}
|
||||||
|
IdCardEntity idCardEntity = JSON.parseObject(body, IdCardEntity.class);
|
||||||
|
log.info(idCardEntity);
|
||||||
|
return R.ok().put("data",idCardEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,13 +3,19 @@ package com.group.user.controller;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.group.common.result.R;
|
import com.group.common.result.R;
|
||||||
import com.group.common.domin.UserEntity;
|
import com.group.common.domin.pojo.UserEntity;
|
||||||
|
import com.group.user.config.IdCardConfig;
|
||||||
|
import com.group.user.config.OssConfig;
|
||||||
|
import com.group.user.config.RealID;
|
||||||
|
import com.group.user.pojo.IdCard;
|
||||||
|
import com.group.user.pojo.ReqGroup;
|
||||||
import com.group.user.service.UserService;
|
import com.group.user.service.UserService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户控制层
|
* 用户控制层
|
||||||
|
@ -40,4 +46,33 @@ public class UserController {
|
||||||
.eq(UserEntity::getUserName, name));
|
.eq(UserEntity::getUserName, name));
|
||||||
return R.ok().put("data", JSON.toJSONString(user));
|
return R.ok().put("data", JSON.toJSONString(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请成为团长
|
||||||
|
*/
|
||||||
|
@PostMapping("/apply")
|
||||||
|
public R apply(@RequestBody ReqGroup reqGroup) {
|
||||||
|
|
||||||
|
return userService.apply(reqGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private OssConfig ossConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传视频或者照片
|
||||||
|
*/
|
||||||
|
@PostMapping("/upload")
|
||||||
|
public R upload(@RequestParam("file") MultipartFile file) {
|
||||||
|
return R.ok().put("data",ossConfig.upload(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传身份证正面照片获取用户真实姓名和身份证号
|
||||||
|
*/
|
||||||
|
@PostMapping("/getRealName")
|
||||||
|
public R getRealName(@RequestParam("file")MultipartFile file){
|
||||||
|
return userService.getRealName(file);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.group.user.mapper;
|
package com.group.user.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.group.user.pojo.CouponEntity;
|
import com.group.common.domin.pojo.CouponEntity;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.group.user.mapper;
|
package com.group.user.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.group.user.pojo.RegistrationEntity;
|
import com.group.common.domin.pojo.RegistrationEntity;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.group.user.mapper;
|
package com.group.user.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.group.common.domin.UserEntity;
|
import com.group.common.domin.pojo.UserEntity;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.group.user.pojo;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户实名信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class IdCard {
|
||||||
|
private String realName;
|
||||||
|
private String cardNo;
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.group.user.pojo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 持有人的相关信息
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public class IdCardEntity {
|
||||||
|
|
||||||
|
@JsonProperty("error_code")
|
||||||
|
private Integer errorCode;
|
||||||
|
@JsonProperty("reason")
|
||||||
|
private String reason;
|
||||||
|
@JsonProperty("result")
|
||||||
|
private ResultDTO result;
|
||||||
|
@JsonProperty("sn")
|
||||||
|
private String sn;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public static class ResultDTO {
|
||||||
|
@JsonProperty("realname")
|
||||||
|
private String realname;
|
||||||
|
@JsonProperty("idcard")
|
||||||
|
private String idcard;
|
||||||
|
@JsonProperty("isok")
|
||||||
|
private Boolean isok;
|
||||||
|
@JsonProperty("IdCardInfor")
|
||||||
|
private IdCardInforDTO idCardInfor;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public static class IdCardInforDTO {
|
||||||
|
@JsonProperty("province")
|
||||||
|
private String province;
|
||||||
|
@JsonProperty("city")
|
||||||
|
private String city;
|
||||||
|
@JsonProperty("district")
|
||||||
|
private String district;
|
||||||
|
@JsonProperty("area")
|
||||||
|
private String area;
|
||||||
|
@JsonProperty("sex")
|
||||||
|
private String sex;
|
||||||
|
@JsonProperty("birthday")
|
||||||
|
private String birthday;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
package com.group.user.pojo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 身份证正面信息
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public class IdCardPeople {
|
||||||
|
|
||||||
|
@JsonProperty("address")
|
||||||
|
private String address;
|
||||||
|
@JsonProperty("angle")
|
||||||
|
private Integer angle;
|
||||||
|
@JsonProperty("birth")
|
||||||
|
private String birth;
|
||||||
|
@JsonProperty("card_region")
|
||||||
|
private List<CardRegionDTO> cardRegion;
|
||||||
|
@JsonProperty("config_str")
|
||||||
|
private String configStr;
|
||||||
|
@JsonProperty("face_rect")
|
||||||
|
private FaceRectDTO faceRect;
|
||||||
|
@JsonProperty("face_rect_vertices")
|
||||||
|
private List<FaceRectVerticesDTO> faceRectVertices;
|
||||||
|
@JsonProperty("is_fake")
|
||||||
|
private Boolean isFake;
|
||||||
|
@JsonProperty("name")
|
||||||
|
private String name;
|
||||||
|
@JsonProperty("nationality")
|
||||||
|
private String nationality;
|
||||||
|
@JsonProperty("num")
|
||||||
|
private String num;
|
||||||
|
@JsonProperty("request_id")
|
||||||
|
private String requestId;
|
||||||
|
@JsonProperty("sex")
|
||||||
|
private String sex;
|
||||||
|
@JsonProperty("success")
|
||||||
|
private Boolean success;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public static class FaceRectDTO {
|
||||||
|
@JsonProperty("angle")
|
||||||
|
private Integer angle;
|
||||||
|
@JsonProperty("center")
|
||||||
|
private CenterDTO center;
|
||||||
|
@JsonProperty("size")
|
||||||
|
private SizeDTO size;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public static class CenterDTO {
|
||||||
|
@JsonProperty("x")
|
||||||
|
private Integer x;
|
||||||
|
@JsonProperty("y")
|
||||||
|
private Integer y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public static class SizeDTO {
|
||||||
|
@JsonProperty("height")
|
||||||
|
private Integer height;
|
||||||
|
@JsonProperty("width")
|
||||||
|
private Integer width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public static class CardRegionDTO {
|
||||||
|
@JsonProperty("x")
|
||||||
|
private Integer x;
|
||||||
|
@JsonProperty("y")
|
||||||
|
private Integer y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public static class FaceRectVerticesDTO {
|
||||||
|
@JsonProperty("x")
|
||||||
|
private Integer x;
|
||||||
|
@JsonProperty("y")
|
||||||
|
private Integer y;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.group.user.pojo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团长申请表单
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ReqGroup {
|
||||||
|
/**
|
||||||
|
* 活体视频 网址
|
||||||
|
*/
|
||||||
|
private String idCardUrl;
|
||||||
|
/**
|
||||||
|
* 用户真实姓名
|
||||||
|
*/
|
||||||
|
private String realName;
|
||||||
|
/**
|
||||||
|
* 身份证号
|
||||||
|
*/
|
||||||
|
private String cardNo;
|
||||||
|
/**
|
||||||
|
* 活体视频 动作
|
||||||
|
*/
|
||||||
|
private String motions;
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.group.user.pojo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频验证结果
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public class SelfDTO {
|
||||||
|
@JsonProperty("msg")
|
||||||
|
private String msg;
|
||||||
|
@JsonProperty("success")
|
||||||
|
private Boolean success;
|
||||||
|
@JsonProperty("code")
|
||||||
|
private Integer code;
|
||||||
|
@JsonProperty("data")
|
||||||
|
private DataDTO data;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public static class DataDTO {
|
||||||
|
@JsonProperty("order_no")
|
||||||
|
private String orderNo;
|
||||||
|
@JsonProperty("motions")
|
||||||
|
private MotionsDTO motions;
|
||||||
|
@JsonProperty("passed")
|
||||||
|
private Boolean passed;
|
||||||
|
@JsonProperty("feature_image_id")
|
||||||
|
private String featureImageId;
|
||||||
|
@JsonProperty("hack_score")
|
||||||
|
private Double hackScore;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public static class MotionsDTO {
|
||||||
|
@JsonProperty("score")
|
||||||
|
private Double score;
|
||||||
|
@JsonProperty("motion")
|
||||||
|
private String motion;
|
||||||
|
@JsonProperty("passed")
|
||||||
|
private Boolean passed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ package com.group.user.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.group.common.result.R;
|
import com.group.common.result.R;
|
||||||
import com.group.user.pojo.CouponEntity;
|
import com.group.common.domin.pojo.CouponEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 优惠券业务层
|
* 优惠券业务层
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.group.user.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.group.common.result.R;
|
import com.group.common.result.R;
|
||||||
import com.group.user.pojo.RegistrationEntity;
|
import com.group.common.domin.pojo.RegistrationEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 签到服务层
|
* 签到服务层
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
package com.group.user.service;
|
package com.group.user.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.group.common.domin.UserEntity;
|
import com.group.common.domin.pojo.UserEntity;
|
||||||
|
import com.group.common.result.R;
|
||||||
|
import com.group.user.pojo.ReqGroup;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户服务层
|
* 用户服务层
|
||||||
*/
|
*/
|
||||||
public interface UserService extends IService<UserEntity> {
|
public interface UserService extends IService<UserEntity> {
|
||||||
|
|
||||||
|
R getRealName(MultipartFile file);
|
||||||
|
|
||||||
|
R apply(ReqGroup reqGroup);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,17 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.group.common.constants.JwtConstants;
|
import com.group.common.constants.JwtConstants;
|
||||||
import com.group.common.result.R;
|
import com.group.common.result.R;
|
||||||
import com.group.user.mapper.CouponMapper;
|
import com.group.user.mapper.CouponMapper;
|
||||||
import com.group.user.pojo.CouponEntity;
|
import com.group.common.domin.pojo.CouponEntity;
|
||||||
import com.group.user.service.CouponService;
|
import com.group.user.service.CouponService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 优惠券实现层
|
* 优惠券实现层
|
||||||
*/
|
*/
|
||||||
|
@Service
|
||||||
public class CouponServiceImpl extends ServiceImpl<CouponMapper, CouponEntity>
|
public class CouponServiceImpl extends ServiceImpl<CouponMapper, CouponEntity>
|
||||||
implements CouponService {
|
implements CouponService {
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@ package com.group.user.service.impl;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.group.common.constants.JwtConstants;
|
import com.group.common.constants.JwtConstants;
|
||||||
import com.group.common.domin.UserEntity;
|
import com.group.common.domin.pojo.UserEntity;
|
||||||
import com.group.common.result.R;
|
import com.group.common.result.R;
|
||||||
|
import com.group.common.util.UserUtil;
|
||||||
import com.group.user.mapper.RegistrationMapper;
|
import com.group.user.mapper.RegistrationMapper;
|
||||||
import com.group.user.pojo.RegistrationEntity;
|
import com.group.common.domin.pojo.RegistrationEntity;
|
||||||
import com.group.user.service.RegistrationService;
|
import com.group.user.service.RegistrationService;
|
||||||
import com.group.user.service.UserService;
|
import com.group.user.service.UserService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -34,14 +35,12 @@ public class RegistrationServiceImpl extends ServiceImpl<RegistrationMapper, Reg
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
|
|
||||||
private Integer getUserId() {
|
|
||||||
return Integer.valueOf(request.getHeader(JwtConstants.DETAILS_USER_ID));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R sign() {
|
public R sign() {
|
||||||
|
Integer userId = UserUtil.getUserId(request);
|
||||||
//通过用户id获取用户对象
|
//通过用户id获取用户对象
|
||||||
UserEntity user = userService.getById(getUserId());
|
UserEntity user = userService.getById(userId);
|
||||||
// 获取当前日期时间
|
// 获取当前日期时间
|
||||||
LocalDateTime currentDateTime = LocalDateTime.now();
|
LocalDateTime currentDateTime = LocalDateTime.now();
|
||||||
// 获取当前日期的零点时间
|
// 获取当前日期的零点时间
|
||||||
|
@ -53,7 +52,7 @@ public class RegistrationServiceImpl extends ServiceImpl<RegistrationMapper, Reg
|
||||||
Date zero = Date.from(startOfToday.atZone(ZoneId.systemDefault()).toInstant());
|
Date zero = Date.from(startOfToday.atZone(ZoneId.systemDefault()).toInstant());
|
||||||
//获取用户的签到记录
|
//获取用户的签到记录
|
||||||
List<RegistrationEntity> list = list(new LambdaQueryWrapper<RegistrationEntity>()
|
List<RegistrationEntity> list = list(new LambdaQueryWrapper<RegistrationEntity>()
|
||||||
.eq(RegistrationEntity::getUserId, getUserId())
|
.eq(RegistrationEntity::getUserId, userId)
|
||||||
.le(RegistrationEntity::getRegistrationDate, date)
|
.le(RegistrationEntity::getRegistrationDate, date)
|
||||||
.ge(RegistrationEntity::getRegistrationDate, seven));
|
.ge(RegistrationEntity::getRegistrationDate, seven));
|
||||||
//判断今天是否已经 签到过
|
//判断今天是否已经 签到过
|
||||||
|
@ -76,7 +75,7 @@ public class RegistrationServiceImpl extends ServiceImpl<RegistrationMapper, Reg
|
||||||
save(RegistrationEntity
|
save(RegistrationEntity
|
||||||
.builder()
|
.builder()
|
||||||
.registrationDate(new Date())
|
.registrationDate(new Date())
|
||||||
.userId(getUserId())
|
.userId(userId)
|
||||||
.registrationScore(num)
|
.registrationScore(num)
|
||||||
.build());
|
.build());
|
||||||
return R.ok("签到成功");
|
return R.ok("签到成功");
|
||||||
|
|
|
@ -1,10 +1,24 @@
|
||||||
package com.group.user.service.impl;
|
package com.group.user.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.group.common.constants.JwtConstants;
|
||||||
|
import com.group.common.result.R;
|
||||||
|
import com.group.user.config.CheckLifeImpl;
|
||||||
|
import com.group.user.config.IdCardConfig;
|
||||||
|
import com.group.user.config.OssConfig;
|
||||||
|
import com.group.user.config.RealID;
|
||||||
import com.group.user.mapper.UserMapper;
|
import com.group.user.mapper.UserMapper;
|
||||||
import com.group.common.domin.UserEntity;
|
import com.group.common.domin.pojo.UserEntity;
|
||||||
|
import com.group.user.pojo.*;
|
||||||
import com.group.user.service.UserService;
|
import com.group.user.service.UserService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.xml.transform.Result;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户业务层
|
* 用户业务层
|
||||||
|
@ -13,4 +27,76 @@ import org.springframework.stereotype.Service;
|
||||||
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity>
|
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity>
|
||||||
implements UserService {
|
implements UserService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CheckLifeImpl checkLife;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IdCardConfig idCardConfig;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R getRealName(MultipartFile file) {
|
||||||
|
|
||||||
|
IdCardPeople idCardPeople = idCardConfig.checkCard(file, "face");
|
||||||
|
|
||||||
|
IdCard idCard = IdCard.builder()
|
||||||
|
.cardNo(idCardPeople.getNum())
|
||||||
|
.realName(idCardPeople.getName())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return R.ok().put("data", idCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RealID realID;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R apply(ReqGroup reqGroup) {
|
||||||
|
//判断用户是否已经修改状态了
|
||||||
|
Integer id = getId();
|
||||||
|
UserEntity user = getById(id);
|
||||||
|
if (user.getUserRole() == 1) {
|
||||||
|
return R.error("用户已经申请过了,请不要重复申请");
|
||||||
|
}
|
||||||
|
//使用异步进行活体检查
|
||||||
|
//checkLife.checkLife(reqGroup.getIdCardUrl(), reqGroup.getMotions())
|
||||||
|
CompletableFuture<R> future1 =
|
||||||
|
CompletableFuture.supplyAsync(() -> {
|
||||||
|
System.out.println("活体检测");
|
||||||
|
return checkLife.checkLife(reqGroup.getIdCardUrl(), reqGroup.getMotions());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
//使用身份证号和姓名校验身份
|
||||||
|
//realID.checkId(IdCard.builder().realName(reqGroup.getRealName()).cardNo(reqGroup.getCardNo()).build()
|
||||||
|
CompletableFuture<R> future2 =
|
||||||
|
CompletableFuture.supplyAsync(() -> {
|
||||||
|
System.out.println("校验身份");
|
||||||
|
return realID.checkId(IdCard.builder().realName(reqGroup.getRealName()).cardNo(reqGroup.getCardNo()).build());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
R result1 = future1.join();
|
||||||
|
R result2 = future2.join();
|
||||||
|
|
||||||
|
// 在这里处理两个结果的逻辑
|
||||||
|
if (result1.get("code").equals(0) && result2.get("code").equals(0)) {
|
||||||
|
IdCardEntity idCard = (IdCardEntity) result2.get("data");
|
||||||
|
user.setUserRealAddress(idCard.getResult().getIdCardInfor().getArea());
|
||||||
|
user.setUserRealName(reqGroup.getRealName());
|
||||||
|
user.setUserCard(reqGroup.getCardNo());
|
||||||
|
user.setUserRole(1);
|
||||||
|
//修改用户状态
|
||||||
|
updateById(user);
|
||||||
|
} else {
|
||||||
|
return R.error("身份认证失败");
|
||||||
|
}
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
private Integer getId() {
|
||||||
|
return Integer.valueOf(request.getHeader(JwtConstants.DETAILS_USER_ID));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +1,55 @@
|
||||||
package com.group.user.xxl.config;
|
//package com.group.user.xxl.config;
|
||||||
|
//
|
||||||
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
|
//import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
//import lombok.extern.log4j.Log4j2;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
//import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Bean;
|
//import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
//import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.Configuration;
|
//import org.springframework.context.annotation.Configuration;
|
||||||
|
//
|
||||||
|
//
|
||||||
/**
|
///**
|
||||||
* xxl-job的配置类
|
// * xxl-job的配置类
|
||||||
*/
|
// */
|
||||||
@ComponentScan(basePackages = "com.group.user.xxl.handle")
|
//@ComponentScan(basePackages = "com.group.user.xxl.handle")
|
||||||
@Configuration
|
//@Configuration
|
||||||
@Log4j2
|
//@Log4j2
|
||||||
public class JobConfig {
|
//public class JobConfig {
|
||||||
|
//
|
||||||
@Value("${xxl.job.admin.addresses}")
|
// @Value("${xxl.job.admin.addresses}")
|
||||||
private String adminAddresses;
|
// private String adminAddresses;
|
||||||
|
//
|
||||||
@Value("${xxl.job.executor.appname}")
|
// @Value("${xxl.job.executor.appname}")
|
||||||
private String appName;
|
// private String appName;
|
||||||
|
//
|
||||||
@Value("${xxl.job.executor.ip}")
|
// @Value("${xxl.job.executor.ip}")
|
||||||
private String ip;
|
// private String ip;
|
||||||
|
//
|
||||||
@Value("${xxl.job.executor.port}")
|
// @Value("${xxl.job.executor.port}")
|
||||||
private int port;
|
// private int port;
|
||||||
|
//
|
||||||
@Value("${xxl.job.accessToken}")
|
// @Value("${xxl.job.accessToken}")
|
||||||
private String accessToken;
|
// private String accessToken;
|
||||||
|
//
|
||||||
@Value("${xxl.job.executor.logpath}")
|
// @Value("${xxl.job.executor.logpath}")
|
||||||
private String logPath;
|
// private String logPath;
|
||||||
|
//
|
||||||
@Value("${xxl.job.executor.logretentiondays}")
|
// @Value("${xxl.job.executor.logretentiondays}")
|
||||||
private int logRetentionDays;
|
// private int logRetentionDays;
|
||||||
|
//
|
||||||
|
//
|
||||||
@Bean(initMethod = "start", destroyMethod = "destroy")
|
// @Bean(initMethod = "start", destroyMethod = "destroy")
|
||||||
public XxlJobSpringExecutor xxlJobExecutor() {
|
// public XxlJobSpringExecutor xxlJobExecutor() {
|
||||||
log.info(">>>>>>>>>>> xxl-job config init.");
|
// log.info(">>>>>>>>>>> xxl-job config init.");
|
||||||
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
|
// XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
|
||||||
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
|
// xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
|
||||||
xxlJobSpringExecutor.setAppname(appName);
|
// xxlJobSpringExecutor.setAppname(appName);
|
||||||
xxlJobSpringExecutor.setIp(ip);
|
// xxlJobSpringExecutor.setIp(ip);
|
||||||
xxlJobSpringExecutor.setPort(port);
|
// xxlJobSpringExecutor.setPort(port);
|
||||||
xxlJobSpringExecutor.setAccessToken(accessToken);
|
// xxlJobSpringExecutor.setAccessToken(accessToken);
|
||||||
xxlJobSpringExecutor.setLogPath(logPath);
|
// xxlJobSpringExecutor.setLogPath(logPath);
|
||||||
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
|
// xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
|
||||||
return xxlJobSpringExecutor;
|
// return xxlJobSpringExecutor;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
}
|
//}
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
package com.group.user.xxl.handle;
|
//package com.group.user.xxl.handle;
|
||||||
|
//
|
||||||
import com.xxl.job.core.context.XxlJobHelper;
|
//import com.xxl.job.core.context.XxlJobHelper;
|
||||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
//import com.xxl.job.core.handler.annotation.XxlJob;
|
||||||
import org.springframework.stereotype.Component;
|
//import org.springframework.stereotype.Component;
|
||||||
|
//
|
||||||
/**
|
///**
|
||||||
* xxl任务执行器
|
// * xxl任务执行器
|
||||||
*/
|
// */
|
||||||
@Component
|
//@Component
|
||||||
public class XxlHandle {
|
//public class XxlHandle {
|
||||||
|
//
|
||||||
@XxlJob("xxl")
|
// @XxlJob("xxl")
|
||||||
public void doSomeThing(){
|
// public void doSomeThing(){
|
||||||
System.out.println("hello");
|
// System.out.println("hello");
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
}
|
//}
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
# log config
|
## log config
|
||||||
logging.config=classpath:logback.xml
|
#logging.config=classpath:logback.xml
|
||||||
|
#
|
||||||
|
#
|
||||||
### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
|
#### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
|
||||||
xxl.job.admin.addresses=http://127.0.0.1:7070/xxl-job-admin
|
#xxl.job.admin.addresses=http://127.0.0.1:7070/xxl-job-admin
|
||||||
|
#
|
||||||
### xxl-job, access token
|
#### xxl-job, access token
|
||||||
xxl.job.accessToken=default_token
|
#xxl.job.accessToken=default_token
|
||||||
|
#
|
||||||
### xxl-job executor appname
|
#### xxl-job executor appname
|
||||||
xxl.job.executor.appname=xxl-job-executor-sample
|
#xxl.job.executor.appname=xxl-job-executor-sample
|
||||||
### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null
|
#### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null
|
||||||
|
#
|
||||||
### xxl-job executor server-info
|
#### xxl-job executor server-info
|
||||||
xxl.job.executor.ip=
|
#xxl.job.executor.ip=
|
||||||
xxl.job.executor.port=10001
|
#xxl.job.executor.port=10001
|
||||||
### xxl-job executor log-path
|
#### xxl-job executor log-path
|
||||||
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
|
#xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
|
||||||
### xxl-job executor log-retention-days
|
#### xxl-job executor log-retention-days
|
||||||
xxl.job.executor.logretentiondays=30
|
#xxl.job.executor.logretentiondays=30
|
||||||
|
|
|
@ -27,3 +27,27 @@ spring:
|
||||||
# 共享配置
|
# 共享配置
|
||||||
shared-configs:
|
shared-configs:
|
||||||
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
max-file-size: 10MB
|
||||||
|
max-request-size: 10MB
|
||||||
|
|
||||||
|
|
||||||
|
song:
|
||||||
|
life:
|
||||||
|
url: https://life.shumaidata.com/checklife
|
||||||
|
appCode: 5becad81f5c64b36a883ad8c7b66fa66
|
||||||
|
oss:
|
||||||
|
endpoint: oss-cn-shanghai.aliyuncs.com
|
||||||
|
accessKeyId: LTAI5tEhxBCDjWFy6D2SEX3y
|
||||||
|
secretAccessKey: gw5SQHr5T0P2UkCLYiAfgOxBwOpTTN
|
||||||
|
bucketName: song-mp4
|
||||||
|
objectName: mp4/
|
||||||
|
card:
|
||||||
|
host: https://cardnumber.market.alicloudapi.com
|
||||||
|
path: /rest/160601/ocr/ocr_idcard.json
|
||||||
|
check:
|
||||||
|
url: https://zidv2.market.alicloudapi.com/idcheck/Post
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<description>商品模块</description>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.song</groupId>
|
||||||
|
<artifactId>group-module</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>group_goods</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.song</groupId>
|
||||||
|
<artifactId>group-common</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.group.goods;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品模块启动类
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableFeignClients("com.group")
|
||||||
|
public class GoodsApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(GoodsApplication.class,args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.group.goods.controller;
|
||||||
|
|
||||||
|
import com.group.common.result.R;
|
||||||
|
import com.group.goods.service.SecKillService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀商品控制层
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/goods/secKill")
|
||||||
|
public class SecKillController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SecKillService secKillService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀商品 - 采用最简单方式进行实现
|
||||||
|
*/
|
||||||
|
@GetMapping("/buyGoodsByOne/{id}")
|
||||||
|
public R buyGoodsByOne(@PathVariable("id")Integer id){
|
||||||
|
return secKillService.buyGoodsByOne(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀方式 -- 采用降低锁粒度的方式实现
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀商品 -- 采用redisson信号量的方式进行解决这个问题
|
||||||
|
*/
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.group.goods.controller;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 场次信息控制层
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/session")
|
||||||
|
public class SessionController {
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.group.goods.feign;
|
||||||
|
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程调用秒杀订单方法
|
||||||
|
*/
|
||||||
|
@FeignClient(name = "song-order",path = "/order")
|
||||||
|
public interface KillOrderService {
|
||||||
|
|
||||||
|
@GetMapping("/killOrder/exitResult")
|
||||||
|
public boolean exitResult(@RequestParam Integer goodsId, Integer userId);
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.group.goods.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.group.common.domin.pojo.SeckillEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀商品持久层
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface SecKillMapper extends BaseMapper<SeckillEntity> {
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.group.goods.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.group.common.domin.pojo.SessionEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* session持久层
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface SessionMapper extends BaseMapper<SessionEntity> {
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.group.goods.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.group.common.domin.pojo.SeckillEntity;
|
||||||
|
import com.group.common.result.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀商品服务层
|
||||||
|
*/
|
||||||
|
public interface SecKillService extends IService<SeckillEntity> {
|
||||||
|
R buyGoodsByOne(Integer id);
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.group.goods.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.group.common.domin.pojo.SessionEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 场次服务层
|
||||||
|
*/
|
||||||
|
public interface SessionService extends IService<SessionEntity> {
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package com.group.goods.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.group.common.domin.pojo.KillOrderEntity;
|
||||||
|
import com.group.common.domin.pojo.SessionEntity;
|
||||||
|
import com.group.common.redis.RedisCache;
|
||||||
|
import com.group.common.result.R;
|
||||||
|
import com.group.common.util.UserUtil;
|
||||||
|
import com.group.goods.feign.KillOrderService;
|
||||||
|
import com.group.goods.mapper.SecKillMapper;
|
||||||
|
import com.group.common.domin.pojo.SeckillEntity;
|
||||||
|
import com.group.goods.service.SecKillService;
|
||||||
|
import com.group.goods.service.SessionService;
|
||||||
|
import org.redisson.Redisson;
|
||||||
|
import org.redisson.api.RLock;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀商品业务层
|
||||||
|
*/
|
||||||
|
public class SecKillServiceImpl extends ServiceImpl<SecKillMapper, SeckillEntity>
|
||||||
|
implements SecKillService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 场次信息数据获取
|
||||||
|
*/
|
||||||
|
@Autowired
|
||||||
|
private SessionService sessionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private KillOrderService killOrderService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisCache redisCache;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Redisson redisson;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R buyGoodsByOne(Integer id) {
|
||||||
|
//通过商品id获取商品信息
|
||||||
|
//获取redis中的所有数据
|
||||||
|
List<SeckillEntity> list = redisCache.getCacheList("secKill");
|
||||||
|
SeckillEntity secKill = list.stream().filter(c -> c.getSeckillId().equals(id)).collect(Collectors.toList()).get(0);
|
||||||
|
//首先校验该商品是否在当前时间段
|
||||||
|
//通过场次id获取商品场次的信息
|
||||||
|
SessionEntity session = sessionService.getById(secKill.getSessionId());
|
||||||
|
//当前时间毫秒值
|
||||||
|
long time = new Date().getTime();
|
||||||
|
if (session.getSessionBegin().getTime()>time){
|
||||||
|
throw new RuntimeException("场次尚未开始");
|
||||||
|
}
|
||||||
|
if (session.getSessionEnd().getTime()<time){
|
||||||
|
throw new RuntimeException("该场次已经结束");
|
||||||
|
}
|
||||||
|
RLock lock = redisson.getLock("productId:" + id);
|
||||||
|
|
||||||
|
//校验用户是否购买过
|
||||||
|
//获取用户id
|
||||||
|
Integer userId = UserUtil.getUserId(request);
|
||||||
|
//通过用户id和秒杀商品id,查询该用户是否第一次购买该商品
|
||||||
|
if (killOrderService.exitResult(id,userId)){
|
||||||
|
throw new RuntimeException("用户已购买该商品");
|
||||||
|
}
|
||||||
|
//根据id查询秒杀商品信息,判断库存是否足够
|
||||||
|
//库存信息存储在redis中,通过键"product_id:"+goods_id 来存储,通过键来获取商品库存
|
||||||
|
|
||||||
|
Integer stock = redisCache.getCacheObject("product_id:" + id);
|
||||||
|
if (stock<=0){
|
||||||
|
throw new RuntimeException("库存不足,请不要再次点击");
|
||||||
|
}
|
||||||
|
//减少库存,把数据同步到数据库和redis中
|
||||||
|
redisCache.decreaseKey("product_id:"+id);
|
||||||
|
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.group.goods.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.group.common.domin.pojo.SessionEntity;
|
||||||
|
import com.group.goods.mapper.SessionMapper;
|
||||||
|
import com.group.goods.service.SessionService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 场次信息业务层
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class SessionServiceImpl extends ServiceImpl<SessionMapper, SessionEntity>
|
||||||
|
implements SessionService {
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Tomcat
|
||||||
|
server:
|
||||||
|
port: 9004
|
||||||
|
# Spring
|
||||||
|
spring:
|
||||||
|
main:
|
||||||
|
allow-circular-references: true
|
||||||
|
jackson:
|
||||||
|
date-format: yyyy-MM-dd HH:mm:ss
|
||||||
|
time-zone: GMT+8
|
||||||
|
application:
|
||||||
|
# 应用名称
|
||||||
|
name: song-goods
|
||||||
|
profiles:
|
||||||
|
# 环境配置
|
||||||
|
active: dev
|
||||||
|
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
# 服务注册地址
|
||||||
|
server-addr: 124.221.178.252:8848
|
||||||
|
config:
|
||||||
|
# 配置中心地址
|
||||||
|
server-addr: 124.221.178.252:8848
|
||||||
|
# 配置文件格式
|
||||||
|
file-extension: yml
|
||||||
|
# 共享配置
|
||||||
|
shared-configs:
|
||||||
|
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<description>订单模块</description>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.song</groupId>
|
||||||
|
<artifactId>group-module</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>group_order</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.song</groupId>
|
||||||
|
<artifactId>group-common</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.group.order;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单模块启动类
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class OrderApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(OrderApplication.class,args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.group.order.config;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import com.alipay.api.AlipayApiException;
|
||||||
|
import com.alipay.api.AlipayClient;
|
||||||
|
import com.alipay.api.request.AlipayTradePagePayRequest;
|
||||||
|
import com.song.order.entity.PayEntity;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付宝封装工具
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class AliPay {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AlipayClient alipayClient;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AliPayConfig aliPayConfig;
|
||||||
|
|
||||||
|
public void pay(PayEntity payEntity, HttpServletResponse response) {
|
||||||
|
AlipayTradePagePayRequest request = getAlipayTradePagePayRequest(payEntity);
|
||||||
|
// 执行请求,拿到响应的结果,返回给浏览器
|
||||||
|
String form = "";
|
||||||
|
try {
|
||||||
|
form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
|
||||||
|
} catch (AlipayApiException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
response.setContentType("text/html;charset=" + aliPayConfig.getCharset());
|
||||||
|
try {
|
||||||
|
response.getWriter().write(form);// 直接将完整的表单html输出到页面
|
||||||
|
response.getWriter().flush();
|
||||||
|
response.getWriter().close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private AlipayTradePagePayRequest getAlipayTradePagePayRequest(PayEntity payEntity) {
|
||||||
|
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
|
||||||
|
request.setNotifyUrl(aliPayConfig.getNotifyUrl());
|
||||||
|
JSONObject bizContent = new JSONObject();
|
||||||
|
bizContent.set("out_trade_no", payEntity.getPayId()); // 我们自己生成的订单编号
|
||||||
|
bizContent.set("total_amount", payEntity.getPrice()); // 订单的总金额
|
||||||
|
bizContent.set("subject", payEntity.getOrderTitle()); // 支付的名称
|
||||||
|
bizContent.set("product_code", aliPayConfig.getProductCode());
|
||||||
|
request.setBizContent(bizContent.toString());
|
||||||
|
request.setReturnUrl(aliPayConfig.getReturnUrl());// 支付完成后自动跳转到本地页面的路径
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.group.order.config;
|
||||||
|
|
||||||
|
import com.alipay.api.AlipayClient;
|
||||||
|
import com.alipay.api.DefaultAlipayClient;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Data
|
||||||
|
@ConfigurationProperties(prefix = "alipay")
|
||||||
|
public class AliPayConfig {
|
||||||
|
|
||||||
|
// 支付宝的AppId
|
||||||
|
private String appId;
|
||||||
|
// 应用私钥
|
||||||
|
private String appPrivateKey;
|
||||||
|
// 支付宝公钥
|
||||||
|
private String alipayPublicKey;
|
||||||
|
// 支付宝通知本地的接口完整地址
|
||||||
|
private String notifyUrl;
|
||||||
|
//支付宝跳转的地址
|
||||||
|
private String gatewayUrl ;
|
||||||
|
private String format;
|
||||||
|
private String charset;
|
||||||
|
//签名方式
|
||||||
|
private String signType;
|
||||||
|
//回调本地地址
|
||||||
|
private String returnUrl;
|
||||||
|
|
||||||
|
private String productCode;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public AlipayClient alipayClient(){
|
||||||
|
return new DefaultAlipayClient(gatewayUrl,appId,appPrivateKey,format,charset,alipayPublicKey,signType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.group.order.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
import org.springframework.web.filter.CorsFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跨域配置
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class CorsConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CorsFilter corsFilter() {
|
||||||
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
|
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||||
|
corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
|
||||||
|
corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
|
||||||
|
corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
|
||||||
|
source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
|
||||||
|
return new CorsFilter(source);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.group.order.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.group.common.domin.pojo.KillOrderEntity;
|
||||||
|
import com.group.common.domin.pojo.PayDetail;
|
||||||
|
import com.group.common.result.R;
|
||||||
|
import com.group.order.payMethod.PayContext;
|
||||||
|
import com.group.order.payMethod.PayType;
|
||||||
|
import com.group.order.pojo.ReqPay;
|
||||||
|
import com.group.order.service.KillOrderService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀订单控制层
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/order/killOrder")
|
||||||
|
public class KillOrderController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private KillOrderService killOrderService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 利用商品id和用户id查询有购买记录
|
||||||
|
* 如果结果为false,证明该商品未被该用户购买
|
||||||
|
* 如果为true,证明该用户已经购买过该商品
|
||||||
|
*/
|
||||||
|
@GetMapping("/exitResult")
|
||||||
|
public boolean exitResult(@RequestParam Integer goodsId,Integer userId){
|
||||||
|
KillOrderEntity one = killOrderService.getOne(new LambdaQueryWrapper<KillOrderEntity>()
|
||||||
|
.eq(KillOrderEntity::getGoodsId, goodsId)
|
||||||
|
.eq(KillOrderEntity::getUserId, userId));
|
||||||
|
return one != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付秒杀订单
|
||||||
|
*/
|
||||||
|
@PostMapping("/payKill")
|
||||||
|
public R payKill(@RequestBody ReqPay pay){
|
||||||
|
return killOrderService.payKill(pay);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PayContext payContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试支付模式
|
||||||
|
*/
|
||||||
|
@GetMapping("/test")
|
||||||
|
public R test(@RequestParam Integer type){
|
||||||
|
// PayType pay = payContext.getPay(type);
|
||||||
|
// pay.pay(PayDetail.builder().build());
|
||||||
|
return R.ok("支付成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.group.order.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.group.common.domin.pojo.KillOrderEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀订单持久层
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface KillOrderMapper extends BaseMapper<KillOrderEntity> {
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.group.order.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.group.common.domin.pojo.PayDetail;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单详情持久层
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface PayDetailMapper extends BaseMapper<PayDetail> {
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.group.order.payMethod;
|
||||||
|
|
||||||
|
import com.group.common.domin.pojo.PayDetail;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付宝支付
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class AliPay implements PayType {
|
||||||
|
@Override
|
||||||
|
public void pay(PayDetail payDetail) {
|
||||||
|
System.out.println("支付宝支付");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return PayEnum.BYALI.getName();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.group.order.payMethod;
|
||||||
|
|
||||||
|
import com.group.common.domin.pojo.PayDetail;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 银行卡支付
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class CardPay implements PayType{
|
||||||
|
@Override
|
||||||
|
public void pay(PayDetail payDetail) {
|
||||||
|
System.out.println("银行卡支付");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return PayEnum.BYCARD.getName();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.group.order.payMethod;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付上下文
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class PayContext implements InitializingBean, ApplicationContextAware {
|
||||||
|
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
Map<String,PayType> map = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
applicationContext.getBeansOfType(PayType.class).values()
|
||||||
|
.stream().forEach(type->map.put(type.getName(),type));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
this.applicationContext=applicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过不同的类型数据获取不同的方法
|
||||||
|
*/
|
||||||
|
public PayType getPay(Integer type){
|
||||||
|
String payType=null;
|
||||||
|
if (type==1){
|
||||||
|
payType=PayEnum.BYALI.getName();
|
||||||
|
}
|
||||||
|
if (type==2){
|
||||||
|
payType=PayEnum.BYWECHAT.getName();
|
||||||
|
}
|
||||||
|
if (type==3){
|
||||||
|
payType=PayEnum.BYCARD.getName();
|
||||||
|
}
|
||||||
|
return map.getOrDefault(payType,new AliPay());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.group.order.payMethod;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付类型的枚举
|
||||||
|
*/
|
||||||
|
public enum PayEnum {
|
||||||
|
BYALI(1,"by_ali"),
|
||||||
|
BYWECHAT(2,"by_wechat"),
|
||||||
|
BYCARD(3,"by_card");
|
||||||
|
|
||||||
|
private Integer type;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
PayEnum(Integer type, String name) {
|
||||||
|
this.type = type;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.group.order.payMethod;
|
||||||
|
|
||||||
|
import com.group.common.domin.pojo.PayDetail;
|
||||||
|
import com.group.common.result.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽象接口
|
||||||
|
*/
|
||||||
|
public interface PayType {
|
||||||
|
|
||||||
|
public void pay(PayDetail payDetail);
|
||||||
|
|
||||||
|
public String getName();
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.group.order.payMethod;
|
||||||
|
|
||||||
|
import com.group.common.domin.pojo.PayDetail;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*微信支付
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class WeChat implements PayType{
|
||||||
|
@Override
|
||||||
|
public void pay(PayDetail payDetail) {
|
||||||
|
System.out.println("微信支付");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return PayEnum.BYWECHAT.getName();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.group.order.pojo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求支付类
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ReqPay {
|
||||||
|
/**
|
||||||
|
* 订单id
|
||||||
|
*/
|
||||||
|
private Integer orderId;
|
||||||
|
/**
|
||||||
|
* 支付金额
|
||||||
|
*/
|
||||||
|
private BigDecimal price;
|
||||||
|
/**
|
||||||
|
* 支付类型 1-支付宝 2-微信 3-银行卡
|
||||||
|
*/
|
||||||
|
private Integer type;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.group.order.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.group.common.domin.pojo.KillOrderEntity;
|
||||||
|
import com.group.common.result.R;
|
||||||
|
import com.group.order.pojo.ReqPay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀订单服务层
|
||||||
|
*/
|
||||||
|
public interface KillOrderService extends IService<KillOrderEntity> {
|
||||||
|
R payKill(ReqPay pay);
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.group.order.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.group.common.domin.pojo.KillOrderEntity;
|
||||||
|
|
||||||
|
import com.group.common.domin.pojo.PayDetail;
|
||||||
|
import com.group.common.result.R;
|
||||||
|
import com.group.order.mapper.KillOrderMapper;
|
||||||
|
import com.group.order.mapper.PayDetailMapper;
|
||||||
|
import com.group.order.payMethod.PayContext;
|
||||||
|
import com.group.order.payMethod.PayType;
|
||||||
|
import com.group.order.pojo.ReqPay;
|
||||||
|
import com.group.order.service.KillOrderService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀订单实现层
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class KillOrderServiceImpl extends ServiceImpl<KillOrderMapper, KillOrderEntity>
|
||||||
|
implements KillOrderService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PayDetailMapper payDetailMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PayContext payContext;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R payKill(ReqPay pay) {
|
||||||
|
//安全校验
|
||||||
|
//防止幂等性
|
||||||
|
KillOrderEntity order = getById(pay.getOrderId());
|
||||||
|
if (order.getKillState()!=1){
|
||||||
|
return R.error("订单已经支付,请不要重复支付");
|
||||||
|
}
|
||||||
|
//生成详细支付订单
|
||||||
|
PayDetail payDetail = PayDetail.builder()
|
||||||
|
.payPay(IdUtil.getSnowflakeNextIdStr())
|
||||||
|
.payOrder(pay.getOrderId())
|
||||||
|
.payCreate(new Date())
|
||||||
|
.payTitle(pay.getPrice())
|
||||||
|
.build();
|
||||||
|
payDetailMapper.insert(payDetail);
|
||||||
|
PayType pay1 = payContext.getPay(pay.getType());
|
||||||
|
pay1.pay(payDetail);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
# Tomcat
|
||||||
|
server:
|
||||||
|
port: 9004
|
||||||
|
# Spring
|
||||||
|
spring:
|
||||||
|
main:
|
||||||
|
allow-circular-references: true
|
||||||
|
jackson:
|
||||||
|
date-format: yyyy-MM-dd HH:mm:ss
|
||||||
|
time-zone: GMT+8
|
||||||
|
application:
|
||||||
|
# 应用名称
|
||||||
|
name: song-order
|
||||||
|
profiles:
|
||||||
|
# 环境配置
|
||||||
|
active: dev
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
# 服务注册地址
|
||||||
|
server-addr: 124.221.178.252:8848
|
||||||
|
config:
|
||||||
|
# 配置中心地址
|
||||||
|
server-addr: 124.221.178.252:8848
|
||||||
|
# 配置文件格式
|
||||||
|
file-extension: yml
|
||||||
|
# 共享配置
|
||||||
|
shared-configs:
|
||||||
|
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
max-file-size: 10MB
|
||||||
|
max-request-size: 10MB
|
||||||
|
|
||||||
|
|
||||||
|
song:
|
||||||
|
life:
|
||||||
|
url: https://life.shumaidata.com/checklife
|
||||||
|
appCode: 5becad81f5c64b36a883ad8c7b66fa66
|
||||||
|
oss:
|
||||||
|
endpoint: oss-cn-shanghai.aliyuncs.com
|
||||||
|
accessKeyId: LTAI5tEhxBCDjWFy6D2SEX3y
|
||||||
|
secretAccessKey: gw5SQHr5T0P2UkCLYiAfgOxBwOpTTN
|
||||||
|
bucketName: song-mp4
|
||||||
|
objectName: mp4/
|
||||||
|
card:
|
||||||
|
host: https://cardnumber.market.alicloudapi.com
|
||||||
|
path: /rest/160601/ocr/ocr_idcard.json
|
||||||
|
check:
|
||||||
|
url: https://zidv2.market.alicloudapi.com/idcheck/Post
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<modules>
|
<modules>
|
||||||
<module>group-user</module>
|
<module>group-user</module>
|
||||||
|
<module>group_order</module>
|
||||||
|
<module>group_goods</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|
Loading…
Reference in New Issue