身份验证

idcard
2024-05-05 15:36:55 +08:00
parent aa0a5492e3
commit 403b4c34c8
71 changed files with 1818 additions and 201 deletions

View File

@ -2,14 +2,13 @@ package com.group.auth.service.impl;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.group.auth.feign.UserService;
import com.group.auth.service.AuthService;
import com.group.auth.strategy.LoginContext;
import com.group.auth.strategy.LoginType;
import com.group.common.config.JwtUtils;
import com.group.common.constants.JwtConstants;
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.redis.RedisCache;
import com.group.common.result.R;
@ -17,7 +16,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**

View File

@ -2,7 +2,7 @@ package com.group.auth.strategy;
import com.alibaba.fastjson.JSON;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

View File

@ -2,9 +2,8 @@ package com.group.auth.strategy;
import com.alibaba.fastjson.JSON;
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.handle.BizException;
import com.group.common.redis.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

View File

@ -1,6 +1,6 @@
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;

View File

@ -19,6 +19,10 @@
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- bootstrap 启动器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
@ -134,5 +138,15 @@
<artifactId>xxl-job-core</artifactId>
<version>2.3.0</version>
</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>
</project>

View File

@ -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.TableName;

View File

@ -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 ;
}

View File

@ -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 ;
}

View File

@ -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.TableId;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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.TableName;
@ -29,34 +30,57 @@ public class UserEntity implements Serializable {
/**
*
*/
@TableField("user_name")
private String userName;
/**
*
*/
@TableField("user_pwd")
private String userPwd;
/**
*
*/
@TableField("user_phone")
private String userPhone;
/**
*
*/
@TableField("user_honor")
private Integer userHonor;
/**
*
*/
@TableField("user_residue")
private BigDecimal userResidue;
/**
*
*/
@TableField("user_score")
private Integer userScore;
/**
* (0- 1- 2-)
*/
@TableField("user_role")
private Integer userRole;
/**
*
*/
@TableField("user_address")
private String userAddress;
/**
*
*/
@TableField("user_card")
private String userCard;
/**
*
*/
@TableField("user_real_name")
private String userRealName;
/**
*
*/
@TableField("user_real_address")
private String userRealAddress;
}

View File

@ -257,4 +257,11 @@ public class RedisCache {
public Collection<String> keys (final String pattern) {
return redisTemplate.keys(pattern);
}
/**
*
*/
public void decreaseKey(String key){
redisTemplate.opsForValue().decrement(key);
}
}

View File

@ -0,0 +1,10 @@
package com.group.common.redis;
import org.springframework.context.annotation.Configuration;
/**
* redisson
*/
@Configuration
public class RedissonConfig {
}

View File

@ -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));
}
}

View File

@ -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);
}
}

View File

@ -14,6 +14,7 @@ spring:
allow-circular-references: true
# 允许定义相同的bean对象 去覆盖原有的
allow-bean-definition-overriding: true
web-application-type: reactive
cloud:
nacos:
discovery:
@ -26,4 +27,4 @@ spring:
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -3,13 +3,19 @@ package com.group.user.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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 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;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
/**
*
@ -38,6 +44,35 @@ public class UserController {
public R getUserByName(@PathVariable String name) {
UserEntity user = userService.getOne(new LambdaQueryWrapper<UserEntity>()
.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);
}
}

View File

@ -1,7 +1,7 @@
package com.group.user.mapper;
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;
/**

View File

@ -1,7 +1,7 @@
package com.group.user.mapper;
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;
/**

View File

@ -1,7 +1,7 @@
package com.group.user.mapper;
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;
/**

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -2,7 +2,7 @@ package com.group.user.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.group.common.result.R;
import com.group.user.pojo.CouponEntity;
import com.group.common.domin.pojo.CouponEntity;
/**
*

View File

@ -2,7 +2,7 @@ package com.group.user.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.group.common.result.R;
import com.group.user.pojo.RegistrationEntity;
import com.group.common.domin.pojo.RegistrationEntity;
/**
*

View File

@ -1,10 +1,18 @@
package com.group.user.service;
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> {
R getRealName(MultipartFile file);
R apply(ReqGroup reqGroup);
}

View File

@ -4,16 +4,17 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.group.common.constants.JwtConstants;
import com.group.common.result.R;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
/**
*
*/
@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, CouponEntity>
implements CouponService {

View File

@ -3,10 +3,11 @@ package com.group.user.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.util.UserUtil;
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.UserService;
import org.springframework.beans.factory.annotation.Autowired;
@ -34,14 +35,12 @@ public class RegistrationServiceImpl extends ServiceImpl<RegistrationMapper, Reg
@Autowired
private UserService userService;
private Integer getUserId() {
return Integer.valueOf(request.getHeader(JwtConstants.DETAILS_USER_ID));
}
@Override
public R sign() {
Integer userId = UserUtil.getUserId(request);
//通过用户id获取用户对象
UserEntity user = userService.getById(getUserId());
UserEntity user = userService.getById(userId);
// 获取当前日期时间
LocalDateTime currentDateTime = LocalDateTime.now();
// 获取当前日期的零点时间
@ -53,7 +52,7 @@ public class RegistrationServiceImpl extends ServiceImpl<RegistrationMapper, Reg
Date zero = Date.from(startOfToday.atZone(ZoneId.systemDefault()).toInstant());
//获取用户的签到记录
List<RegistrationEntity> list = list(new LambdaQueryWrapper<RegistrationEntity>()
.eq(RegistrationEntity::getUserId, getUserId())
.eq(RegistrationEntity::getUserId, userId)
.le(RegistrationEntity::getRegistrationDate, date)
.ge(RegistrationEntity::getRegistrationDate, seven));
//判断今天是否已经 签到过
@ -76,7 +75,7 @@ public class RegistrationServiceImpl extends ServiceImpl<RegistrationMapper, Reg
save(RegistrationEntity
.builder()
.registrationDate(new Date())
.userId(getUserId())
.userId(userId)
.registrationScore(num)
.build());
return R.ok("签到成功");

View File

@ -1,10 +1,24 @@
package com.group.user.service.impl;
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.common.domin.UserEntity;
import com.group.common.domin.pojo.UserEntity;
import com.group.user.pojo.*;
import com.group.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
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>
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));
}
}

View File

@ -1,55 +1,55 @@
package com.group.user.xxl.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* xxl-job
*/
@ComponentScan(basePackages = "com.group.user.xxl.handle")
@Configuration
@Log4j2
public class JobConfig {
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.executor.appname}")
private String appName;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean(initMethod = "start", destroyMethod = "destroy")
public XxlJobSpringExecutor xxlJobExecutor() {
log.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appName);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
}
//package com.group.user.xxl.config;
//
//import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
//import lombok.extern.log4j.Log4j2;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.ComponentScan;
//import org.springframework.context.annotation.Configuration;
//
//
///**
// * xxl-job的配置类
// */
//@ComponentScan(basePackages = "com.group.user.xxl.handle")
//@Configuration
//@Log4j2
//public class JobConfig {
//
// @Value("${xxl.job.admin.addresses}")
// private String adminAddresses;
//
// @Value("${xxl.job.executor.appname}")
// private String appName;
//
// @Value("${xxl.job.executor.ip}")
// private String ip;
//
// @Value("${xxl.job.executor.port}")
// private int port;
//
// @Value("${xxl.job.accessToken}")
// private String accessToken;
//
// @Value("${xxl.job.executor.logpath}")
// private String logPath;
//
// @Value("${xxl.job.executor.logretentiondays}")
// private int logRetentionDays;
//
//
// @Bean(initMethod = "start", destroyMethod = "destroy")
// public XxlJobSpringExecutor xxlJobExecutor() {
// log.info(">>>>>>>>>>> xxl-job config init.");
// XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
// xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
// xxlJobSpringExecutor.setAppname(appName);
// xxlJobSpringExecutor.setIp(ip);
// xxlJobSpringExecutor.setPort(port);
// xxlJobSpringExecutor.setAccessToken(accessToken);
// xxlJobSpringExecutor.setLogPath(logPath);
// xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
// return xxlJobSpringExecutor;
// }
//
//}

View File

@ -1,18 +1,18 @@
package com.group.user.xxl.handle;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.stereotype.Component;
/**
* xxl
*/
@Component
public class XxlHandle {
@XxlJob("xxl")
public void doSomeThing(){
System.out.println("hello");
}
}
//package com.group.user.xxl.handle;
//
//import com.xxl.job.core.context.XxlJobHelper;
//import com.xxl.job.core.handler.annotation.XxlJob;
//import org.springframework.stereotype.Component;
//
///**
// * xxl任务执行器
// */
//@Component
//public class XxlHandle {
//
// @XxlJob("xxl")
// public void doSomeThing(){
// System.out.println("hello");
// }
//
//}

View File

@ -1,23 +1,23 @@
# log config
logging.config=classpath:logback.xml
### 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, access token
xxl.job.accessToken=default_token
### xxl-job executor appname
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 server-info
xxl.job.executor.ip=
xxl.job.executor.port=10001
### xxl-job executor log-path
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### xxl-job executor log-retention-days
xxl.job.executor.logretentiondays=30
#
#
## log config
#logging.config=classpath:logback.xml
#
#
#### 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, access token
#xxl.job.accessToken=default_token
#
#### xxl-job executor appname
#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 server-info
#xxl.job.executor.ip=
#xxl.job.executor.port=10001
#### xxl-job executor log-path
#xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
#### xxl-job executor log-retention-days
#xxl.job.executor.logretentiondays=30

View File

@ -27,3 +27,27 @@ spring:
# 共享配置
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

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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
*/
}

View File

@ -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 {
}

View File

@ -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);
}

View File

@ -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> {
}

View File

@ -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> {
}

View File

@ -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);
}

View File

@ -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> {
}

View File

@ -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;
}
}

View File

@ -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 {
}

View File

@ -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}

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
/**
* idid
* 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("支付成功");
}
}

View File

@ -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> {
}

View File

@ -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> {
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -14,6 +14,8 @@
<packaging>pom</packaging>
<modules>
<module>group-user</module>
<module>group_order</module>
<module>group_goods</module>
</modules>
<properties>