Browse Source

feature1.0.0-img:添加支付宝支付及用户vip功能

feature-1.0-img-prototype
chengkun 3 years ago
parent
commit
bf7a78b680
  1. 20
      bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/utils/DateUtils.java
  2. 16
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/config/AlipayConfig.java
  3. 5
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/constants/RedisKeyConstant.java
  4. 29
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/constants/UserVipOrderStatusConstant.java
  5. 24
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/constants/UserVipTypeConstant.java
  6. 26
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/FhMiniController.java
  7. 10
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/TiktokMiniController.java
  8. 26
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/WxMiniController.java
  9. 34
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/domain/UserVipRecord.java
  10. 33
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/PayUserVipDto.java
  11. 15
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/UserVipRecordService.java
  12. 98
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java
  13. 8
      bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/UserVipRecordMapper.xml

20
bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/utils/DateUtils.java

@ -8,7 +8,9 @@ import java.time.LocalDateTime;
import java.time.LocalTime; import java.time.LocalTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.commons.lang3.time.DateFormatUtils;
/** /**
@ -176,4 +178,22 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
return Date.from(zdt.toInstant()); return Date.from(zdt.toInstant());
} }
/**
* 给指定日期添加指定添加的天数 返回添加后的天数
*
* @param d 指定的日期
* @param day 指定添加的天数
* @return 添加后的天数
*/
public static Date getDateAfter(Date d, int day) {
Calendar now = Calendar.getInstance();
now.setTime(d);
now.set(Calendar.DATE, now.get(Calendar.DATE) + day);
return now.getTime();
}
public static void main(String[] args) {
System.out.println(getDateAfter(new Date(), 365));
}
} }

16
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/config/AlipayConfig.java

@ -27,6 +27,9 @@ public class AlipayConfig{
@Value("${alipay.privateKey}") @Value("${alipay.privateKey}")
private String privateKey; private String privateKey;
@Value("${alipay.publicKey}")
private String publicKey;
@Value("${alipay.certPath}") @Value("${alipay.certPath}")
private String certPath; private String certPath;
@ -35,4 +38,17 @@ public class AlipayConfig{
@Value("${alipay.rootPath}") @Value("${alipay.rootPath}")
private String rootPath; private String rootPath;
@Value("${alipay.notifyUrl}")
private String notifyUrl;
@Value("${alipay.returnUrl}")
private String returnUrl;
@Value("${alipay.signType}")
private String signType;
@Value("${alipay.charset}")
private String charset;
} }

5
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/constants/RedisKeyConstant.java

@ -101,4 +101,9 @@ public class RedisKeyConstant {
* 艺术家上传键 * 艺术家上传键
*/ */
public static final String CREATOR_UPLOAD_KEY="bnyer.img.creator.upload:"; public static final String CREATOR_UPLOAD_KEY="bnyer.img.creator.upload:";
/**
* 用户会员vip锁键
*/
public static final String PAY_USER_VIP_LOCK_KEY = "bnyer.img.userVip.lock:";
} }

29
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/constants/UserVipOrderStatusConstant.java

@ -0,0 +1,29 @@
package com.bnyer.img.constants;
/**
* 用户会员vip支付常量
* @author chengkun
* @date 2022/4/21 18:12
*/
public class UserVipOrderStatusConstant {
/**
* 待支付
*/
public static final String UN_PAY = "0";
/**
* 已支付
*/
public static final String PAYED = "1";
/**
* 支付失败
*/
public static final String PAY_FAIL = "2";
/**
* 支付失败
*/
public static final String PAY_EXCEPTION = "3";
}

24
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/constants/UserVipTypeConstant.java

@ -0,0 +1,24 @@
package com.bnyer.img.constants;
/**
* 用户会员vip常量
* @author chengkun
* @date 2022/4/21 18:12
*/
public class UserVipTypeConstant {
/**
* 月卡
*/
public static final String MONTH_CARD = "0";
/**
* 季卡
*/
public static final String SEASON_CARD = "1";
/**
* 年卡
*/
public static final String YEAR_CARD = "2";
}

26
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/FhMiniController.java

@ -64,6 +64,12 @@ public class FhMiniController extends BaseController {
@Autowired @Autowired
private BzDataService bzDataService; private BzDataService bzDataService;
@Autowired
private UserVipService userVipService;
@Autowired
private UserVipRecordService userVipRecordService;
//@TokenCheck //@TokenCheck
@ApiOperation(value="查询banner列表") @ApiOperation(value="查询banner列表")
@GetMapping(value = "/listBanner") @GetMapping(value = "/listBanner")
@ -290,4 +296,24 @@ public class FhMiniController extends BaseController {
} }
return AjaxResult.error(); return AjaxResult.error();
} }
//@TokenCheck
@ApiOperation(value="获取用户会员vip列表")
@GetMapping(value = "/queryUserVipList")
public AjaxResult queryUserVipList(){
return AjaxResult.success(userVipService.queryFront());
}
//@TokenCheck
@ApiOperation(value="支付购买用户会员vip")
@PostMapping(value = "/payUserVip")
public AjaxResult payUserVip(@Validated @RequestBody @ApiParam("购买会员vip对象") PayUserVipDto dto){
log.debug("【微信图文小程序】支付购买用户会员vip参数为:{}", JSON.toJSONString(dto));
boolean b = userVipRecordService.payUserVip(dto);
if(b){
return AjaxResult.success("购买支付成功!");
}else{
return AjaxResult.error("购买支付失败!");
}
}
} }

10
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/TiktokMiniController.java

@ -65,6 +65,9 @@ public class TiktokMiniController extends BaseController {
@Autowired @Autowired
private BzDataService bzDataService; private BzDataService bzDataService;
@Autowired
private UserVipService userVipService;
//@TokenCheck //@TokenCheck
@ApiOperation(value="查询banner列表") @ApiOperation(value="查询banner列表")
@GetMapping(value = "/listBanner") @GetMapping(value = "/listBanner")
@ -293,4 +296,11 @@ public class TiktokMiniController extends BaseController {
} }
return AjaxResult.error(); return AjaxResult.error();
} }
//@TokenCheck
@ApiOperation(value="获取用户会员vip列表")
@GetMapping(value = "/queryUserVipList")
public AjaxResult queryUserVipList(){
return AjaxResult.success(userVipService.queryFront());
}
} }

26
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/WxMiniController.java

@ -64,6 +64,12 @@ public class WxMiniController extends BaseController {
@Autowired @Autowired
private BzDataService bzDataService; private BzDataService bzDataService;
@Autowired
private UserVipService userVipService;
@Autowired
private UserVipRecordService userVipRecordService;
//@TokenCheck //@TokenCheck
@ApiOperation(value="查询banner列表") @ApiOperation(value="查询banner列表")
@GetMapping(value = "/listBanner") @GetMapping(value = "/listBanner")
@ -290,4 +296,24 @@ public class WxMiniController extends BaseController {
} }
return AjaxResult.error(); return AjaxResult.error();
} }
//@TokenCheck
@ApiOperation(value="获取用户会员vip列表")
@GetMapping(value = "/queryUserVipList")
public AjaxResult queryUserVipList(){
return AjaxResult.success(userVipService.queryFront());
}
//@TokenCheck
@ApiOperation(value="支付购买用户会员vip")
@PostMapping(value = "/payUserVip")
public AjaxResult payUserVip(@Validated @RequestBody @ApiParam("购买会员vip对象") PayUserVipDto dto){
log.debug("【微信图文小程序】支付购买用户会员vip参数为:{}", JSON.toJSONString(dto));
boolean b = userVipRecordService.payUserVip(dto);
if(b){
return AjaxResult.success("购买支付成功!");
}else{
return AjaxResult.error("购买支付失败!");
}
}
} }

34
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/domain/UserVipRecord.java

@ -4,9 +4,11 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField; 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;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@ -29,6 +31,13 @@ public class UserVipRecord extends BaseDomain {
@ApiModelProperty(value="主键id") @ApiModelProperty(value="主键id")
private Long id; private Long id;
/**
* 订单id
*/
@TableField(value = "order_id")
@ApiModelProperty(value="订单id")
private String orderId;
/** /**
* 用户手机号 * 用户手机号
*/ */
@ -47,6 +56,7 @@ public class UserVipRecord extends BaseDomain {
* 开始时间 * 开始时间
*/ */
@TableField(value = "start_time") @TableField(value = "start_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value="开始时间") @ApiModelProperty(value="开始时间")
private Date startTime; private Date startTime;
@ -54,8 +64,30 @@ public class UserVipRecord extends BaseDomain {
* 到期时间 * 到期时间
*/ */
@TableField(value = "end_time") @TableField(value = "end_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value="到期时间") @ApiModelProperty(value="到期时间")
private Date endTime; private Date endTime;
/**
* 支付金额
*/
@TableField(value = "price")
@ApiModelProperty(value="支付金额")
private BigDecimal price;
/**
* vip类型状态(0->月卡;1->季卡;2->年卡)
*/
@TableField(value = "type")
@ApiModelProperty(value="vip类型状态(0->月卡;1->季卡;2->年卡)")
private String type;
/**
* 支付状态(0->待支付;1->已支付;2->支付失败;3->支付异常)
*/
@TableField(value = "status")
@ApiModelProperty(value="支付状态(0->待支付;1->已支付;2->支付失败;3->支付异常)")
private String status;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
} }

33
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/PayUserVipDto.java

@ -0,0 +1,33 @@
package com.bnyer.img.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
@Getter
@Setter
@ApiModel("用户会员vip支付接收类")
public class PayUserVipDto implements Serializable {
@NotBlank(message = "手机号不能为空!")
@ApiModelProperty(value="手机号")
private String phone;
@NotNull(message = "用户vipId不能为空!")
@ApiModelProperty(value="用户vip表id")
private Long userVipId;
@NotBlank(message = "vip类型状态不能为空!")
@ApiModelProperty(value="vip类型状态(0->月卡;1->季卡;2->年卡)")
private String type;
@NotBlank(message = "支付金额不能为空!")
@ApiModelProperty(value="支付金额")
private String price;
}

15
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/UserVipRecordService.java

@ -0,0 +1,15 @@
package com.bnyer.img.service;
import com.bnyer.img.domain.UserVipRecord;
import com.bnyer.img.dto.PayUserVipDto;
public interface UserVipRecordService {
/**
* 下单并支付会员vip
* @param param 用户vip参数对象
* @return -
*/
boolean payUserVip(PayUserVipDto param);
}

98
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java

@ -0,0 +1,98 @@
package com.bnyer.img.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.bnyer.common.core.exception.ServiceException;
import com.bnyer.common.core.utils.DateUtils;
import com.bnyer.common.core.utils.StringUtils;
import com.bnyer.common.core.utils.uuid.IdUtils;
import com.bnyer.common.redis.service.RedissonService;
import com.bnyer.img.constants.RedisKeyConstant;
import com.bnyer.img.constants.UserVipOrderStatusConstant;
import com.bnyer.img.constants.UserVipTypeConstant;
import com.bnyer.img.domain.UserVip;
import com.bnyer.img.domain.UserVipRecord;
import com.bnyer.img.dto.PayUserVipDto;
import com.bnyer.img.dto.UserVipPageDto;
import com.bnyer.img.mapper.UserVipMapper;
import com.bnyer.img.mapper.UserVipRecordMapper;
import com.bnyer.img.service.UserVipRecordService;
import com.bnyer.img.service.UserVipService;
import com.bnyer.img.vo.UserVipVo;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Service
@Slf4j
public class UserVipServiceRecordImpl implements UserVipRecordService {
@Autowired
private UserVipRecordMapper userVipRecordMapper;
@Autowired
private RedissonService redissonService;
@Override
public boolean payUserVip(PayUserVipDto param) {
UserVipRecord userVipRecord = new UserVipRecord();
//生成订单id
userVipRecord.setOrderId(IdUtil.getSnowflakeNextIdStr());
//获取分布式锁
RLock lock = redissonService.getRLock(RedisKeyConstant.PAY_USER_VIP_LOCK_KEY + userVipRecord.getOrderId());
try{
if(lock.tryLock(500, 10000, TimeUnit.MILLISECONDS)){
//调用支付
//保存订单
userVipRecord.setCreateTime(new Date());
userVipRecord.setUpdateTime(new Date());
userVipRecord.setPrice(new BigDecimal(param.getPrice()));
userVipRecord.setStatus(UserVipOrderStatusConstant.UN_PAY);
userVipRecord.setIsShow("1");
Date startTime = new Date();
userVipRecord.setStartTime(startTime);
if(userVipRecord.getType().equals(UserVipTypeConstant.MONTH_CARD)){
//计算月卡(30天)的结束时间
userVipRecord.setEndTime(DateUtils.getDateAfter(startTime, 30));
}else if(userVipRecord.getType().equals(UserVipTypeConstant.SEASON_CARD)){
//结算季卡(90天)的结束时间
userVipRecord.setEndTime(DateUtils.getDateAfter(startTime, 90));
}else{
//计算年卡(365天)的结束时间
userVipRecord.setEndTime(DateUtils.getDateAfter(startTime, 365));
}
}else{
userVipRecord.setStatus(UserVipOrderStatusConstant.PAY_EXCEPTION);
log.error("用户会员vip支付异常,锁被占用!");
throw new ServiceException("系统繁忙,请稍候重试!");
}
}catch (Exception e){
userVipRecord.setStatus(UserVipOrderStatusConstant.PAY_FAIL);
log.error("用户会员vip支付失败!错误原因为【{}】",e.getMessage());
throw new ServiceException("系统繁忙,请勿重复操作!");
}finally {
int insert = userVipRecordMapper.insert(userVipRecord);
if(insert > 0){
return true;
}
//释放锁
if(lock.isHeldByCurrentThread()){
lock.unlock();
log.info("用户会员vip支付操作执行完毕,释放锁成功!");
}
}
return false;
}
}

8
bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/UserVipRecordMapper.xml

@ -5,10 +5,14 @@
<!--@mbg.generated--> <!--@mbg.generated-->
<!--@Table img_user_vip_record--> <!--@Table img_user_vip_record-->
<id column="id" jdbcType="BIGINT" property="id" /> <id column="id" jdbcType="BIGINT" property="id" />
<result column="order_id" jdbcType="VARCHAR" property="orderId" />
<result column="phone" jdbcType="VARCHAR" property="phone" /> <result column="phone" jdbcType="VARCHAR" property="phone" />
<result column="user_vip_id" jdbcType="BIGINT" property="userVipId" /> <result column="user_vip_id" jdbcType="BIGINT" property="userVipId" />
<result column="start_time" jdbcType="TIMESTAMP" property="startTime" /> <result column="start_time" jdbcType="TIMESTAMP" property="startTime" />
<result column="end_time" jdbcType="TIMESTAMP" property="endTime" /> <result column="end_time" jdbcType="TIMESTAMP" property="endTime" />
<result column="price" jdbcType="DECIMAL" property="price" />
<result column="type" jdbcType="CHAR" property="type" />
<result column="status" jdbcType="CHAR" property="status" />
<result column="is_show" jdbcType="CHAR" property="isShow" /> <result column="is_show" jdbcType="CHAR" property="isShow" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" /> <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" /> <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
@ -16,7 +20,7 @@
</resultMap> </resultMap>
<sql id="Base_Column_List"> <sql id="Base_Column_List">
<!--@mbg.generated--> <!--@mbg.generated-->
id, phone, user_vip_id, start_time, end_time, is_show, create_time, update_time, id,order_id, phone,price,status, user_vip_id, start_time, end_time,type, is_show, create_time, update_time,
sort sort
</sql> </sql>
</mapper> </mapper>

Loading…
Cancel
Save