300 lines
6.9 KiB
Go
300 lines
6.9 KiB
Go
package v1
|
||
|
||
import (
|
||
"encoding/json"
|
||
"errors"
|
||
"fmt"
|
||
"hospital-open-api/api/dao"
|
||
dtoV1 "hospital-open-api/api/dto/v1"
|
||
"hospital-open-api/api/model"
|
||
requestsV1 "hospital-open-api/api/requests/v1"
|
||
"hospital-open-api/api/service"
|
||
"hospital-open-api/extend/rabbitMq"
|
||
"hospital-open-api/global"
|
||
"hospital-open-api/utils"
|
||
"strconv"
|
||
"time"
|
||
)
|
||
|
||
// CouponService 优惠卷
|
||
type CouponService struct {
|
||
}
|
||
|
||
// ReceiveCoupon 领取优惠卷
|
||
func (r *CouponService) ReceiveCoupon(req requestsV1.ReceiveCoupon) (g *dtoV1.ReceiveCouponDto, err error) {
|
||
// 获取用户数据
|
||
userDao := dao.UserDao{}
|
||
|
||
maps := make(map[string]interface{})
|
||
maps["mobile"] = req.Mobile
|
||
maps["user_type"] = 1
|
||
user, _ := userDao.GetUser(maps)
|
||
if user == nil {
|
||
g = &dtoV1.ReceiveCouponDto{
|
||
Status: 2,
|
||
Message: "未注册互联网医院患者端",
|
||
Data: nil,
|
||
}
|
||
return g, nil
|
||
}
|
||
|
||
// 获取患者数据
|
||
userPatientDao := dao.UserPatientDao{}
|
||
userPatient, _ := userPatientDao.GetUserPatientByUserId(user.UserId)
|
||
if userPatient == nil {
|
||
g = &dtoV1.ReceiveCouponDto{
|
||
Status: 2,
|
||
Message: "未注册互联网医院患者端",
|
||
Data: nil,
|
||
}
|
||
return g, err
|
||
}
|
||
|
||
// 将 id 转换为 int64 类型
|
||
couponId, err := strconv.ParseInt(req.CouponId, 10, 64)
|
||
if err != nil {
|
||
return g, errors.New("内部错误")
|
||
}
|
||
|
||
// 获取优惠卷数据
|
||
couponDao := dao.CouponDao{}
|
||
coupon, _ := couponDao.GetCouponById(couponId)
|
||
if coupon == nil {
|
||
return nil, errors.New("非法优惠卷")
|
||
}
|
||
|
||
// 检测优惠卷状态
|
||
if coupon.CouponStatus != 1 {
|
||
return nil, errors.New("存在错误优惠卷")
|
||
}
|
||
|
||
// 检测发放优惠卷数量
|
||
if req.Quantity <= 0 {
|
||
g = &dtoV1.ReceiveCouponDto{
|
||
Status: 0,
|
||
Message: "优惠卷数量错误",
|
||
Data: nil,
|
||
}
|
||
return g, nil
|
||
}
|
||
|
||
// 检测优惠卷剩余数量
|
||
remainingQuantity := coupon.CouponCount - coupon.CouponTakeCount
|
||
if remainingQuantity <= 0 {
|
||
g = &dtoV1.ReceiveCouponDto{
|
||
Status: 0,
|
||
Message: "优惠卷数量不足,领取失败",
|
||
Data: nil,
|
||
}
|
||
return g, nil
|
||
}
|
||
|
||
if remainingQuantity < req.Quantity {
|
||
g = &dtoV1.ReceiveCouponDto{
|
||
Status: 0,
|
||
Message: "优惠卷数量不足,领取失败",
|
||
Data: nil,
|
||
}
|
||
return g, nil
|
||
}
|
||
|
||
// 获取当前时间
|
||
now := time.Now()
|
||
|
||
// 检测优惠卷过期时间
|
||
if coupon.ValidType == 1 {
|
||
// 1:绝对时效
|
||
validStartTime := time.Time(coupon.ValidStartTime)
|
||
if now.Before(validStartTime) {
|
||
g = &dtoV1.ReceiveCouponDto{
|
||
Status: 0,
|
||
Message: "优惠卷还未启用",
|
||
Data: nil,
|
||
}
|
||
return g, nil
|
||
}
|
||
|
||
validEndTime := time.Time(coupon.ValidEndTime)
|
||
if now.After(validEndTime) {
|
||
g = &dtoV1.ReceiveCouponDto{
|
||
Status: 0,
|
||
Message: "优惠卷已过期",
|
||
Data: nil,
|
||
}
|
||
return g, nil
|
||
}
|
||
|
||
// 即将过期检测
|
||
now = now.Add(time.Minute * 10)
|
||
// 1:绝对时效
|
||
validStartTime = time.Time(coupon.ValidStartTime)
|
||
if now.Before(validStartTime) {
|
||
g = &dtoV1.ReceiveCouponDto{
|
||
Status: 0,
|
||
Message: "优惠卷还未启用",
|
||
Data: nil,
|
||
}
|
||
return g, nil
|
||
}
|
||
|
||
validEndTime = time.Time(coupon.ValidEndTime)
|
||
if now.After(validEndTime) {
|
||
g = &dtoV1.ReceiveCouponDto{
|
||
Status: 0,
|
||
Message: "优惠卷即将过期",
|
||
Data: nil,
|
||
}
|
||
return g, nil
|
||
}
|
||
}
|
||
|
||
// 检测优惠卷过期时间
|
||
now = now.Add(time.Minute * 10)
|
||
if coupon.ValidType == 1 {
|
||
|
||
}
|
||
|
||
// 检测用户是否已领取该优惠卷
|
||
userCouponDao := dao.UserCouponDao{}
|
||
|
||
maps = make(map[string]interface{})
|
||
maps["user_id"] = user.UserId
|
||
maps["coupon_id"] = coupon.CouponId
|
||
maps["user_coupon_status"] = 0
|
||
userCoupons, _ := userCouponDao.GetUserCouponList(maps)
|
||
if len(userCoupons) > 0 {
|
||
g = &dtoV1.ReceiveCouponDto{
|
||
Status: 0,
|
||
Message: "重复领取",
|
||
Data: nil,
|
||
}
|
||
return g, nil
|
||
}
|
||
|
||
// 开始事务
|
||
tx := global.Db.Begin()
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
tx.Rollback()
|
||
}
|
||
}()
|
||
|
||
// 添加用户优惠卷表
|
||
UserCouponModel := &model.UserCoupon{
|
||
UserId: user.UserId,
|
||
PatientId: userPatient.PatientId,
|
||
CouponId: couponId,
|
||
CouponUseDate: nil,
|
||
}
|
||
|
||
// 有效类型(1:绝对时效,xxx-xxx时间段有效 2:相对时效 n天内有效)
|
||
if coupon.ValidType == 1 {
|
||
UserCouponModel.ValidStartTime = time.Time(coupon.ValidStartTime)
|
||
UserCouponModel.ValidEndTime = time.Time(coupon.ValidEndTime)
|
||
}
|
||
|
||
if coupon.ValidType == 2 {
|
||
UserCouponModel.ValidStartTime = now
|
||
UserCouponModel.ValidEndTime = now.AddDate(0, 0, coupon.ValidDays)
|
||
}
|
||
|
||
userCoupon, _ := userCouponDao.AddUserCoupon(tx, UserCouponModel)
|
||
if userCoupon == nil {
|
||
tx.Rollback()
|
||
return nil, errors.New("发放失败")
|
||
}
|
||
|
||
// 增加优惠卷发放数量
|
||
err = couponDao.Inc(tx, couponId, "coupon_take_count", req.Quantity)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return nil, errors.New("发放失败")
|
||
}
|
||
|
||
// 添加弹窗表
|
||
if coupon.IsPopup == 1 {
|
||
popupModel := &model.Popup{
|
||
UserId: user.UserId,
|
||
AppType: 1,
|
||
ClientType: 1,
|
||
PopupType: 2,
|
||
PopupTitle: "新人红包福利",
|
||
PopupContent: "",
|
||
}
|
||
|
||
popupContent := make(map[string]interface{})
|
||
popupContent["user_coupon_id"] = fmt.Sprintf("%d", userCoupon.UserCouponId)
|
||
popupContent["coupon_price"] = coupon.CouponPrice
|
||
popupContent["application_scope"] = coupon.ApplicationScope
|
||
popupContent["inquiry_type"] = coupon.InquiryType
|
||
popupContent["valid_type"] = coupon.ValidType
|
||
popupContent["valid_days"] = coupon.ValidDays
|
||
popupContent["valid_start_time"] = coupon.ValidStartTime
|
||
popupContent["valid_end_time"] = coupon.ValidEndTime
|
||
|
||
popupContentData, err := json.Marshal(popupContent)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return nil, errors.New("发放失败")
|
||
}
|
||
|
||
popupModel.PopupContent = string(popupContentData)
|
||
|
||
popupDao := dao.PopupDao{}
|
||
popup, _ := popupDao.AddPopup(tx, popupModel)
|
||
if popup == nil {
|
||
tx.Rollback()
|
||
return nil, errors.New("发放失败")
|
||
}
|
||
}
|
||
|
||
// 增加优惠卷过期队列
|
||
// 计算当天的结束时间
|
||
year, month, day := now.Date()
|
||
location := now.Location()
|
||
endOfDay := time.Date(year, month, day, 23, 59, 59, 0, location)
|
||
if userCoupon.ValidEndTime.Before(endOfDay) {
|
||
// 需添加队列
|
||
// 建立队列连接
|
||
rabbitMQ, err := rabbitMq.NewRabbitMQClient()
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return g, errors.New("内部错误")
|
||
}
|
||
|
||
defer rabbitMQ.Close()
|
||
|
||
data := make(map[string]interface{})
|
||
data["user_coupon_id"] = fmt.Sprintf("%d", userCoupon.UserCouponId)
|
||
|
||
delay := userCoupon.ValidEndTime.Sub(time.Now())
|
||
|
||
if delay < 10 {
|
||
delay = 10 * time.Second
|
||
}
|
||
|
||
err = rabbitMQ.PublishWithDelay("user.coupon.expired.delay.queue", "amqp.delay.direct", "UserCouponExpired", data, delay)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return nil, err
|
||
}
|
||
|
||
go func() {
|
||
// 发送通知
|
||
res, _ := service.PatientDistributeCoupon(coupon.CouponName, user.UserId)
|
||
if !res {
|
||
utils.LogJsonError("优惠卷通知发送失败")
|
||
}
|
||
}()
|
||
}
|
||
|
||
tx.Commit()
|
||
|
||
g = &dtoV1.ReceiveCouponDto{
|
||
Status: 1,
|
||
Message: "成功",
|
||
Data: nil,
|
||
}
|
||
return g, nil
|
||
}
|