300 lines
6.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}