肝病算一算后台api初始化
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
package service
|
||||
|
||||
type BaseClassService struct {
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/app"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
|
||||
"gorm.io/gorm"
|
||||
"hepa-calc-admin-api/api/dao"
|
||||
"hepa-calc-admin-api/api/model"
|
||||
"hepa-calc-admin-api/config"
|
||||
"hepa-calc-admin-api/extend/weChat"
|
||||
"hepa-calc-admin-api/global"
|
||||
"hepa-calc-admin-api/utils"
|
||||
"time"
|
||||
)
|
||||
|
||||
type OrderMemberService struct {
|
||||
}
|
||||
|
||||
// CancelOrderMember 取消会员订单
|
||||
// cancelReason:订单取消原因(1:主动取消 2:后台取消 3:支付超时取消)
|
||||
func (r *OrderMemberService) CancelOrderMember(tx *gorm.DB, userId, orderId int64, cancelReason int) (bool, error) {
|
||||
// 检测多次请求
|
||||
redisKey := "CancelOrderMember" + fmt.Sprintf("%d", userId) + fmt.Sprintf("%d", orderId)
|
||||
res, _ := global.Redis.Get(context.Background(), redisKey).Result()
|
||||
if res != "" {
|
||||
return false, errors.New("请勿重复操作")
|
||||
}
|
||||
|
||||
defer func(redisKey string) {
|
||||
global.Redis.Del(context.Background(), redisKey)
|
||||
}(redisKey)
|
||||
|
||||
// 添加缓存
|
||||
_, err := global.Redis.Set(context.Background(), redisKey, "1", (10)*time.Second).Result()
|
||||
if err != nil {
|
||||
return false, errors.New("取消订单失败")
|
||||
}
|
||||
|
||||
// 获取订单数据
|
||||
orderMemberDao := dao.OrderMemberDao{}
|
||||
maps := make(map[string]interface{})
|
||||
maps["order_id"] = orderId
|
||||
orderMember, err := orderMemberDao.GetOrderMember(maps)
|
||||
if err != nil {
|
||||
return false, errors.New("订单异常")
|
||||
}
|
||||
|
||||
// 订单状态(1:待支付 2:已完成 3:已取消)
|
||||
if orderMember.OrderStatus == 2 {
|
||||
return false, errors.New("订单已完成,无法取消")
|
||||
}
|
||||
|
||||
if orderMember.OrderStatus == 3 {
|
||||
return false, errors.New("订单已取消,请勿重复操作")
|
||||
}
|
||||
|
||||
// 取消状态(0:否 1:是)
|
||||
if orderMember.CancelStatus == 1 {
|
||||
return false, errors.New("订单已取消")
|
||||
}
|
||||
|
||||
// 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
|
||||
if orderMember.PayStatus == 2 {
|
||||
return false, errors.New("订单已支付,无法取消")
|
||||
}
|
||||
|
||||
// 订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常 7:部分退款)
|
||||
if orderMember.RefundStatus == 1 {
|
||||
return false, errors.New("订单已申请退款")
|
||||
}
|
||||
|
||||
if orderMember.RefundStatus == 2 {
|
||||
return false, errors.New("订单退款中")
|
||||
}
|
||||
|
||||
if orderMember.RefundStatus == 3 {
|
||||
return false, errors.New("订单已退款成功")
|
||||
}
|
||||
|
||||
if orderMember.RefundStatus == 6 {
|
||||
return false, errors.New("订单退款异常")
|
||||
}
|
||||
|
||||
// 修改订单为取消
|
||||
orderMemberData := make(map[string]interface{})
|
||||
orderMemberData["order_status"] = 3
|
||||
if cancelReason == 3 {
|
||||
// 支付超时取消
|
||||
orderMemberData["pay_status"] = 5
|
||||
}
|
||||
orderMemberData["cancel_status"] = 1
|
||||
orderMemberData["cancel_time"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
orderMemberData["cancel_remarks"] = utils.OrderCancelReasonToString(cancelReason)
|
||||
orderMemberData["updated_at"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
err = orderMemberDao.EditOrderMemberById(tx, orderId, orderMemberData)
|
||||
if err != nil {
|
||||
return false, errors.New("订单取消失败")
|
||||
}
|
||||
|
||||
// 退还订单优惠卷
|
||||
if orderMember.CouponAmountTotal != 0 {
|
||||
// 获取订单优惠卷数据
|
||||
orderMemberCouponDao := dao.OrderMemberCouponDao{}
|
||||
orderMemberCoupon, err := orderMemberCouponDao.GetOrderMemberCouponByOrderId(orderId)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return false, errors.New("订单取消失败")
|
||||
}
|
||||
|
||||
userCouponService := &UserCouponService{}
|
||||
userCouponService.ReturnUserCoupon(tx, orderMemberCoupon.UserCouponId)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// GetJsapiPrepay 获取jsapi预支付交易会话标识
|
||||
func (r *OrderMemberService) GetJsapiPrepay(m *model.OrderMember) (prepay *jsapi.PrepayWithRequestPaymentResponse, err error) {
|
||||
// 获取用户数据
|
||||
userDao := dao.UserDao{}
|
||||
user, err := userDao.GetUserById(m.UserId)
|
||||
if err != nil || user == nil {
|
||||
return nil, errors.New("用户错误")
|
||||
}
|
||||
|
||||
if user.OpenId != "" {
|
||||
return nil, errors.New("发起支付失败")
|
||||
}
|
||||
|
||||
jsapiRequest := weChat.JsapiRequest{
|
||||
AppId: config.C.Wechat.AppId,
|
||||
MchId: config.C.Wechat.Pay1281030301.MchId,
|
||||
Description: "肝病算一算",
|
||||
OutTradeNo: m.OrderNo,
|
||||
NotifyUrl: config.C.Wechat.RefundNotifyDomain + config.C.Wechat.RefundNotifyUrl,
|
||||
Amount: weChat.JsapiRequestAmountRequest{
|
||||
Total: int64(m.PaymentAmountTotal * 100),
|
||||
Currency: "CNY",
|
||||
},
|
||||
Payer: weChat.JsapiRequestPayerRequest{OpenId: user.OpenId},
|
||||
}
|
||||
|
||||
prepay, err = jsapiRequest.GetJsapiPrepay()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return prepay, nil
|
||||
}
|
||||
|
||||
// GetAppPrepay 获取app预支付交易会话标识
|
||||
func (r *OrderMemberService) GetAppPrepay(m *model.OrderMember) (prepay *app.PrepayWithRequestPaymentResponse, err error) {
|
||||
// 获取用户数据
|
||||
userDao := dao.UserDao{}
|
||||
user, err := userDao.GetUserById(m.UserId)
|
||||
if err != nil || user == nil {
|
||||
return nil, errors.New("用户错误")
|
||||
}
|
||||
|
||||
if user.OpenId != "" {
|
||||
return nil, errors.New("发起支付失败")
|
||||
}
|
||||
|
||||
appRequest := weChat.AppRequest{
|
||||
AppId: config.C.Wechat.AppId,
|
||||
MchId: config.C.Wechat.Pay1281030301.MchId,
|
||||
Description: "肝病算一算",
|
||||
OutTradeNo: m.OrderNo,
|
||||
NotifyUrl: config.C.Wechat.RefundNotifyDomain + config.C.Wechat.RefundNotifyUrl,
|
||||
Amount: weChat.AppRequestAmountRequest{
|
||||
Total: int64(m.PaymentAmountTotal * 100),
|
||||
Currency: "CNY",
|
||||
},
|
||||
}
|
||||
|
||||
prepay, err = appRequest.GetAppPrepay()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return prepay, nil
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/app"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
|
||||
"gorm.io/gorm"
|
||||
"hepa-calc-admin-api/api/dao"
|
||||
"hepa-calc-admin-api/api/model"
|
||||
"hepa-calc-admin-api/config"
|
||||
"hepa-calc-admin-api/extend/rabbitMq"
|
||||
"hepa-calc-admin-api/extend/weChat"
|
||||
"hepa-calc-admin-api/global"
|
||||
"hepa-calc-admin-api/utils"
|
||||
"time"
|
||||
)
|
||||
|
||||
type OrderSingleService struct {
|
||||
}
|
||||
|
||||
// AddOrderSingle 创建单项订单
|
||||
// payChannel:支付渠道(1:h5支付 2:app支付 3:会员支付)
|
||||
func (r *OrderSingleService) AddOrderSingle(tx *gorm.DB, UserId, QuestionId int64, UserCouponId *int64, payChannel int, orderPrice float64) (orderSingle *model.OrderSingle, err error) {
|
||||
// 检测并发请求
|
||||
redisKey := "AddOrderSingle" + fmt.Sprintf("%d", UserId) + fmt.Sprintf("%d", QuestionId)
|
||||
res, _ := global.Redis.Get(context.Background(), redisKey).Result()
|
||||
if res != "" {
|
||||
return nil, errors.New("请勿重复操作")
|
||||
}
|
||||
|
||||
defer func(redisKey string) {
|
||||
global.Redis.Del(context.Background(), redisKey)
|
||||
}(redisKey)
|
||||
|
||||
// 添加缓存
|
||||
_, err = global.Redis.Set(context.Background(), redisKey, "1", (10)*time.Second).Result()
|
||||
if err != nil {
|
||||
return nil, errors.New("生成订单失败")
|
||||
}
|
||||
|
||||
// 获取题目数据
|
||||
questionDao := dao.QuestionDao{}
|
||||
question, err := questionDao.GetQuestionById(QuestionId)
|
||||
if err != nil {
|
||||
return nil, errors.New("题目异常")
|
||||
}
|
||||
|
||||
// 检测题目
|
||||
questionService := &QuestionService{}
|
||||
isNormal, err := questionService.CheckQuestion(question)
|
||||
if err != nil || isNormal == false {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var amountTotal *float64 // 总金额
|
||||
var couponAmountTotal float64 // 优惠卷总金额
|
||||
var paymentAmountTotal float64 // 实际付款金额
|
||||
var orderStatus int // 订单状态(1:待支付 2:已完成 3:已取消)
|
||||
var payStatus int // 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
|
||||
var payTime *time.Time // 支付时间
|
||||
var escrowTradeNo string // 第三方支付流水号
|
||||
|
||||
// 获取问题最终价格
|
||||
amountTotal, err = questionService.GetUserBuyPrice(UserId, QuestionId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if amountTotal == nil {
|
||||
return nil, errors.New("价格错误")
|
||||
}
|
||||
|
||||
// 检测用户优惠卷
|
||||
var userCoupon *model.UserCoupon
|
||||
if UserCouponId != nil {
|
||||
// 获取优惠卷数据
|
||||
UserCouponDao := dao.UserCouponDao{}
|
||||
userCoupon, err = UserCouponDao.GetUserCouponPreloadById(*UserCouponId)
|
||||
if err != nil {
|
||||
return nil, errors.New("优惠券异常")
|
||||
}
|
||||
|
||||
userCouponService := &UserCouponService{}
|
||||
isCanUse, err := userCouponService.CheckUserCoupon(userCoupon, QuestionId, 1, *amountTotal)
|
||||
if err != nil || isCanUse == false {
|
||||
return nil, errors.New("价格异常")
|
||||
}
|
||||
|
||||
// 优惠卷总金额
|
||||
couponAmountTotal = userCoupon.Coupon.CouponPrice
|
||||
}
|
||||
|
||||
// 会员支付
|
||||
if payChannel == 3 {
|
||||
paymentAmountTotal = 0 // 实际付款金额
|
||||
orderStatus = 2 // 订单状态(1:待支付 2:已完成 3:已取消)
|
||||
payStatus = 2 // 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
|
||||
|
||||
now := time.Now()
|
||||
payTime = &now // 支付时间
|
||||
|
||||
escrowTradeNo = "GD" + global.Snowflake.Generate().String() // 第三方支付流水号
|
||||
} else {
|
||||
// 实际付款金额
|
||||
paymentAmountTotal = *amountTotal - couponAmountTotal
|
||||
if orderPrice != paymentAmountTotal {
|
||||
return nil, errors.New("价格异常")
|
||||
}
|
||||
|
||||
orderStatus = 1 // 订单状态(1:待支付 2:已完成 3:已取消)
|
||||
payStatus = 1 // 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
|
||||
payTime = nil // 支付时间
|
||||
}
|
||||
|
||||
// 生成订单号
|
||||
orderNo := global.Snowflake.Generate().String()
|
||||
|
||||
// 创建订单
|
||||
orderSingle = &model.OrderSingle{
|
||||
UserId: UserId,
|
||||
QuestionId: QuestionId,
|
||||
OrderStatus: orderStatus,
|
||||
IsDelete: 0,
|
||||
PayChannel: payChannel,
|
||||
PayStatus: payStatus,
|
||||
PayTime: payTime,
|
||||
RefundStatus: 0,
|
||||
OrderNo: orderNo,
|
||||
EscrowTradeNo: escrowTradeNo,
|
||||
AmountTotal: *amountTotal,
|
||||
CouponAmountTotal: couponAmountTotal,
|
||||
PaymentAmountTotal: paymentAmountTotal,
|
||||
CancelStatus: 0,
|
||||
CancelTime: nil,
|
||||
CancelRemarks: "",
|
||||
OrderRemarks: "",
|
||||
}
|
||||
|
||||
orderSingleDao := dao.OrderSingleDao{}
|
||||
orderSingle, err = orderSingleDao.AddOrderSingle(tx, orderSingle)
|
||||
if err != nil {
|
||||
return nil, errors.New("订单创建失败")
|
||||
}
|
||||
|
||||
// 创建优惠卷表
|
||||
if userCoupon != nil {
|
||||
orderSingleCoupon := &model.OrderSingleCoupon{
|
||||
OrderId: orderSingle.OrderId,
|
||||
UserCouponId: *UserCouponId,
|
||||
CouponName: userCoupon.Coupon.CouponName,
|
||||
CouponUsePrice: userCoupon.Coupon.CouponPrice,
|
||||
}
|
||||
|
||||
orderSingleCouponDao := dao.OrderSingleCouponDao{}
|
||||
orderSingleCoupon, err = orderSingleCouponDao.AddOrderSingleCoupon(tx, orderSingleCoupon)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return nil, errors.New("订单创建失败")
|
||||
}
|
||||
|
||||
// 修改优惠卷使用状态
|
||||
userCouponDao := dao.UserCouponDao{}
|
||||
|
||||
userCouponData := make(map[string]interface{})
|
||||
userCouponData["user_coupon_status"] = 1
|
||||
userCouponData["coupon_use_date"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
err := userCouponDao.EditUserCouponById(tx, userCoupon.UserCouponId, userCouponData)
|
||||
if err != nil {
|
||||
return nil, errors.New("订单创建失败")
|
||||
}
|
||||
}
|
||||
|
||||
// 增加未支付取消订单延迟队列
|
||||
if payChannel == 1 || payChannel == 2 {
|
||||
delay := 30 * time.Minute
|
||||
|
||||
if config.C.Env == "dev" {
|
||||
delay = 3 * time.Minute
|
||||
}
|
||||
|
||||
data := make(map[string]interface{})
|
||||
data["order_id"] = fmt.Sprintf("%d", orderSingle.OrderId)
|
||||
data["order_no"] = orderSingle.OrderNo
|
||||
data["user_id"] = fmt.Sprintf("%d", orderSingle.UserId)
|
||||
data["order_type"] = 1
|
||||
data["pay_channel"] = orderSingle.PayChannel
|
||||
|
||||
p := rabbitMq.PublishS{
|
||||
QueueName: "cancel.unpay.order.delay.queue",
|
||||
ExchangeName: "amqp.delay.direct",
|
||||
RoutingKey: "CancelUnPayOrder",
|
||||
Message: data,
|
||||
Delay: delay,
|
||||
}
|
||||
err := p.PublishWithDelay()
|
||||
if err != nil {
|
||||
utils.LogJsonErr("添加处理取消未支付订单队列失败:", err.Error())
|
||||
return nil, errors.New("订单创建失败")
|
||||
}
|
||||
}
|
||||
|
||||
return orderSingle, nil
|
||||
}
|
||||
|
||||
// CancelOrderSingle 取消单项订单
|
||||
// cancelReason:订单取消原因(1:主动取消 2:后台取消 3:支付超时取消)
|
||||
func (r *OrderSingleService) CancelOrderSingle(tx *gorm.DB, userId, orderId int64, cancelReason int) (bool, error) {
|
||||
// 检测多次请求
|
||||
redisKey := "CancelOrderSingle" + fmt.Sprintf("%d", userId) + fmt.Sprintf("%d", orderId)
|
||||
res, _ := global.Redis.Get(context.Background(), redisKey).Result()
|
||||
if res != "" {
|
||||
return false, errors.New("请勿重复操作")
|
||||
}
|
||||
|
||||
defer func(redisKey string) {
|
||||
global.Redis.Del(context.Background(), redisKey)
|
||||
}(redisKey)
|
||||
|
||||
// 添加缓存
|
||||
_, err := global.Redis.Set(context.Background(), redisKey, "1", (10)*time.Second).Result()
|
||||
if err != nil {
|
||||
return false, errors.New("取消订单失败")
|
||||
}
|
||||
|
||||
// 获取订单数据
|
||||
orderSingleDao := dao.OrderSingleDao{}
|
||||
maps := make(map[string]interface{})
|
||||
maps["order_id"] = orderId
|
||||
orderSingle, err := orderSingleDao.GetOrderSingle(maps)
|
||||
if err != nil {
|
||||
return false, errors.New("订单异常")
|
||||
}
|
||||
|
||||
// 订单状态(1:待支付 2:已完成 3:已取消)
|
||||
if orderSingle.OrderStatus == 2 {
|
||||
return false, errors.New("订单已完成,无法取消")
|
||||
}
|
||||
|
||||
if orderSingle.OrderStatus == 3 {
|
||||
return false, errors.New("订单已取消,请勿重复操作")
|
||||
}
|
||||
|
||||
// 取消状态(0:否 1:是)
|
||||
if orderSingle.CancelStatus == 1 {
|
||||
return false, errors.New("订单已取消")
|
||||
}
|
||||
|
||||
// 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
|
||||
if orderSingle.PayStatus == 2 {
|
||||
return false, errors.New("订单已支付,无法取消")
|
||||
}
|
||||
|
||||
// 订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常 7:部分退款)
|
||||
if orderSingle.RefundStatus == 1 {
|
||||
return false, errors.New("订单已申请退款")
|
||||
}
|
||||
|
||||
if orderSingle.RefundStatus == 2 {
|
||||
return false, errors.New("订单退款中")
|
||||
}
|
||||
|
||||
if orderSingle.RefundStatus == 3 {
|
||||
return false, errors.New("订单已退款成功")
|
||||
}
|
||||
|
||||
if orderSingle.RefundStatus == 6 {
|
||||
return false, errors.New("订单退款异常")
|
||||
}
|
||||
|
||||
// 修改订单为取消
|
||||
orderSingleData := make(map[string]interface{})
|
||||
orderSingleData["order_status"] = 3
|
||||
if cancelReason == 3 {
|
||||
// 支付超时取消
|
||||
orderSingleData["pay_status"] = 5
|
||||
}
|
||||
orderSingleData["cancel_status"] = 1
|
||||
orderSingleData["cancel_time"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
orderSingleData["cancel_remarks"] = utils.OrderCancelReasonToString(cancelReason)
|
||||
orderSingleData["updated_at"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
err = orderSingleDao.EditOrderSingleById(tx, orderId, orderSingleData)
|
||||
if err != nil {
|
||||
return false, errors.New("订单取消失败")
|
||||
}
|
||||
|
||||
// 退还订单优惠卷
|
||||
if orderSingle.CouponAmountTotal != 0 {
|
||||
// 获取订单优惠卷数据
|
||||
orderSingleCouponDao := dao.OrderSingleCouponDao{}
|
||||
orderSingleCoupon, err := orderSingleCouponDao.GetOrderSingleCouponByOrderId(orderId)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return false, errors.New("订单取消失败")
|
||||
}
|
||||
|
||||
userCouponService := &UserCouponService{}
|
||||
userCouponService.ReturnUserCoupon(tx, orderSingleCoupon.UserCouponId)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// GetJsapiPrepay 获取jsapi预支付交易会话标识
|
||||
func (r *OrderSingleService) GetJsapiPrepay(m *model.OrderSingle) (prepay *jsapi.PrepayWithRequestPaymentResponse, err error) {
|
||||
// 获取用户数据
|
||||
userDao := dao.UserDao{}
|
||||
user, err := userDao.GetUserById(m.UserId)
|
||||
if err != nil || user == nil {
|
||||
return nil, errors.New("用户错误")
|
||||
}
|
||||
|
||||
if user.OpenId == "" {
|
||||
return nil, errors.New("发起支付失败")
|
||||
}
|
||||
|
||||
jsapiRequest := weChat.JsapiRequest{
|
||||
AppId: config.C.Wechat.AppId,
|
||||
MchId: config.C.Wechat.Pay1281030301.MchId,
|
||||
Description: "肝病算一算",
|
||||
OutTradeNo: m.OrderNo,
|
||||
NotifyUrl: config.C.Wechat.RefundNotifyDomain + config.C.Wechat.RefundNotifyUrl,
|
||||
Amount: weChat.JsapiRequestAmountRequest{
|
||||
Total: int64(m.PaymentAmountTotal * 100),
|
||||
Currency: "CNY",
|
||||
},
|
||||
Payer: weChat.JsapiRequestPayerRequest{OpenId: user.OpenId},
|
||||
}
|
||||
|
||||
prepay, err = jsapiRequest.GetJsapiPrepay()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return prepay, nil
|
||||
}
|
||||
|
||||
// GetAppPrepay 获取app预支付交易会话标识
|
||||
func (r *OrderSingleService) GetAppPrepay(m *model.OrderSingle) (prepay *app.PrepayWithRequestPaymentResponse, err error) {
|
||||
// 获取用户数据
|
||||
userDao := dao.UserDao{}
|
||||
user, err := userDao.GetUserById(m.UserId)
|
||||
if err != nil || user == nil {
|
||||
return nil, errors.New("用户错误")
|
||||
}
|
||||
|
||||
if user.OpenId == "" {
|
||||
return nil, errors.New("发起支付失败")
|
||||
}
|
||||
|
||||
appRequest := weChat.AppRequest{
|
||||
AppId: config.C.Wechat.AppId,
|
||||
MchId: config.C.Wechat.Pay1281030301.MchId,
|
||||
Description: "肝病算一算",
|
||||
OutTradeNo: m.OrderNo,
|
||||
NotifyUrl: config.C.Wechat.RefundNotifyDomain + config.C.Wechat.RefundNotifyUrl,
|
||||
Amount: weChat.AppRequestAmountRequest{
|
||||
Total: int64(m.PaymentAmountTotal * 100),
|
||||
Currency: "CNY",
|
||||
},
|
||||
}
|
||||
|
||||
prepay, err = appRequest.GetAppPrepay()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return prepay, nil
|
||||
}
|
||||
|
||||
// CompleteUnPayOrderSingle 完成未支付单项订单-开通会员成功时使用
|
||||
func (r *OrderSingleService) CompleteUnPayOrderSingle(tx *gorm.DB, userId int64) (bool, error) {
|
||||
// 获取所有未支付单项订单
|
||||
orderSingleDao := dao.OrderSingleDao{}
|
||||
maps := make(map[string]interface{})
|
||||
maps["user_id"] = userId
|
||||
maps["order_status"] = 1
|
||||
maps["pay_status"] = 1
|
||||
maps["cancel_status"] = 0
|
||||
orderSingles, err := orderSingleDao.GetOrderSingleList(maps)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, single := range orderSingles {
|
||||
// 生成第三方支付流水号
|
||||
escrowTradeNo := "GD" + global.Snowflake.Generate().String()
|
||||
|
||||
orderSingleData := make(map[string]interface{})
|
||||
orderSingleData["order_status"] = 2
|
||||
orderSingleData["pay_status"] = 2
|
||||
orderSingleData["pay_time"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
orderSingleData["escrow_trade_no"] = escrowTradeNo
|
||||
orderSingleData["updated_at"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
err = orderSingleDao.EditOrderSingleById(tx, single.OrderId, orderSingleData)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// 增加题目支付次数
|
||||
questionDao := dao.QuestionDao{}
|
||||
err = questionDao.Inc(tx, single.QuestionId, "pay_count", 1)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"hepa-calc-admin-api/extend/aliyun"
|
||||
"hepa-calc-admin-api/global"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PublicService struct {
|
||||
}
|
||||
|
||||
// GetPhoneCode 获取手机验证码
|
||||
func (r *PublicService) GetPhoneCode(scene int, phone string) (bool, error) {
|
||||
var sendCodeCount int // // 获取验证码最大次数
|
||||
var code string // 验证码
|
||||
var templateCode string // 短信模版
|
||||
|
||||
// 登录获取验证码
|
||||
if scene == 1 {
|
||||
// 验证发送次数
|
||||
res, _ := global.Redis.Get(context.Background(), "login_code_count_"+phone).Result()
|
||||
if res != "" {
|
||||
sendCodeCount, err := strconv.Atoi(res)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if sendCodeCount > 3 {
|
||||
// 超出规定时间内最大获取次数
|
||||
return false, errors.New("手机号超出规定时间内最大获取次数,请您稍后再试")
|
||||
}
|
||||
}
|
||||
|
||||
// 生成随机数
|
||||
rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
code = strconv.Itoa(rand.Intn(9000) + 1000)
|
||||
|
||||
// 模版
|
||||
templateCode = "SMS_243055263"
|
||||
|
||||
sendCodeCount = sendCodeCount + 1
|
||||
}
|
||||
|
||||
if code == "" || templateCode == "" {
|
||||
return false, errors.New("验证码发送失败,请您稍后再试")
|
||||
}
|
||||
|
||||
// 发送验证码
|
||||
templateParam := make(map[string]interface{})
|
||||
templateParam["code"] = code
|
||||
err := aliyun.SendSms(phone, templateCode, "获取验证码", templateParam)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// 记录发送次数
|
||||
if sendCodeCount != 0 {
|
||||
_, err = global.Redis.Set(context.Background(), "login_code_count_"+phone, time.Now().Unix(), 60*5*time.Second).Result()
|
||||
if err != nil {
|
||||
return false, errors.New("验证码发送失败,请您稍后再试")
|
||||
}
|
||||
}
|
||||
|
||||
// 设置验证码有效期
|
||||
_, err = global.Redis.Set(context.Background(), "login_code_"+phone, code, 60*5*time.Second).Result()
|
||||
if err != nil {
|
||||
return false, errors.New("验证码发送失败,请您稍后再试")
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// GetUserIP 获取用户ip
|
||||
func (r *PublicService) GetUserIP(h *http.Request) string {
|
||||
forwarded := h.Header.Get("X-FORWARDED-FOR")
|
||||
if forwarded != "" {
|
||||
return forwarded
|
||||
}
|
||||
return h.RemoteAddr
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"hepa-calc-admin-api/api/dao"
|
||||
"hepa-calc-admin-api/api/dto"
|
||||
"hepa-calc-admin-api/api/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
type QuestionService struct {
|
||||
}
|
||||
|
||||
// GetHotList 获取算一算热榜-人气数最高的9个
|
||||
func (r *QuestionService) GetHotList() (m []*model.Question, err error) {
|
||||
questionDao := dao.QuestionDao{}
|
||||
|
||||
maps := make(map[string]interface{})
|
||||
maps["question_status"] = 1
|
||||
maps["is_hide"] = 0
|
||||
questions, err := questionDao.GetQuestionOrderLimitList(maps, "click_count desc", 9)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return questions, nil
|
||||
}
|
||||
|
||||
// GetRecommendList 获取为你推荐-后台指定的推广
|
||||
func (r *QuestionService) GetRecommendList() (m []*model.Question, err error) {
|
||||
questionDao := dao.QuestionDao{}
|
||||
|
||||
maps := make(map[string]interface{})
|
||||
maps["question_status"] = 1
|
||||
maps["is_hide"] = 0
|
||||
maps["is_recommend"] = 1
|
||||
questions, err := questionDao.GetQuestionList(maps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return questions, nil
|
||||
}
|
||||
|
||||
// GetGuessUserLIkeList 获取猜你喜欢-暂用公众参与过的最新算一算,至多显示3个。若未参与,则指定或者随机显示3个
|
||||
func (r *QuestionService) GetGuessUserLIkeList(userId int64) (m []*model.Question, err error) {
|
||||
orderSingleDao := dao.OrderSingleDao{}
|
||||
questionDao := dao.QuestionDao{}
|
||||
|
||||
var questions []*model.Question
|
||||
|
||||
if userId != 0 {
|
||||
maps := make(map[string]interface{})
|
||||
maps["user_id"] = userId
|
||||
orderSingles, err := orderSingleDao.GetOrderSingleOrderList(maps, "created_at desc", 3)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 参与过
|
||||
if len(orderSingles) > 0 {
|
||||
for i, single := range orderSingles {
|
||||
questions[i] = single.Question
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 未参与过/未指定用户
|
||||
if len(questions) == 0 {
|
||||
maps := make(map[string]interface{})
|
||||
maps["question_status"] = 1
|
||||
maps["is_hide"] = 0
|
||||
questions, err = questionDao.GetQuestionListRand(maps, 3)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return questions, nil
|
||||
}
|
||||
|
||||
// CheckUserCollectionQuestion 检测问题是否被用户收藏
|
||||
func (r *QuestionService) CheckUserCollectionQuestion(userId, questionId int64) (bool, error) {
|
||||
userCollectionDao := dao.UserCollectionDao{}
|
||||
|
||||
maps := make(map[string]interface{})
|
||||
maps["user_id"] = userId
|
||||
maps["question_id"] = questionId
|
||||
userCollection, err := userCollectionDao.GetUserCollection(maps)
|
||||
if userCollection == nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// CheckUserBuyQuestion 检测用户是否购买过该问题
|
||||
func (r *QuestionService) CheckUserBuyQuestion(userId, questionId int64) bool {
|
||||
orderSingleDao := dao.OrderSingleDao{}
|
||||
orderSingle, _ := orderSingleDao.GetUserFirstTimeBuyOrderSingle(userId, questionId)
|
||||
if orderSingle == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUserFirstTimeBuyPrice 获取用户首次购买价格
|
||||
func (r *QuestionService) GetUserFirstTimeBuyPrice(userId, questionId int64) (f *float64, err error) {
|
||||
// 检测用户是否购买过该问题
|
||||
isFirstBuy := r.CheckUserBuyQuestion(userId, questionId)
|
||||
if isFirstBuy == false {
|
||||
// 未购买过
|
||||
systemSingleDao := dao.SystemSingleDao{}
|
||||
|
||||
maps := make(map[string]interface{})
|
||||
systemSingle, err := systemSingleDao.GetSystemSingle(maps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &systemSingle.FirstTimePrice, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// GetQuestionBuyCount 获取问题被购买数量
|
||||
func (r *QuestionService) GetQuestionBuyCount(userId, questionId int64) (c int, err error) {
|
||||
// 未购买过
|
||||
orderSingleDao := dao.OrderSingleDao{}
|
||||
|
||||
maps := make(map[string]interface{})
|
||||
maps["user_id"] = userId
|
||||
maps["question_id"] = questionId
|
||||
maps["order_status"] = 2
|
||||
maps["refund_status"] = 0
|
||||
buyCount, err := orderSingleDao.GetOrderSingleCount(maps)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return int(buyCount), nil
|
||||
}
|
||||
|
||||
// GetUserBuyPrice 获取问题最终价格
|
||||
func (r *QuestionService) GetUserBuyPrice(userId, questionId int64) (p *float64, err error) {
|
||||
// 获取问题详情
|
||||
questionDao := dao.QuestionDao{}
|
||||
question, err := questionDao.GetQuestionById(questionId)
|
||||
if err != nil {
|
||||
return nil, errors.New("题目异常")
|
||||
}
|
||||
|
||||
// 检测用户是否购买过该问题
|
||||
isFirstBuy := r.CheckUserBuyQuestion(userId, questionId)
|
||||
if isFirstBuy == false {
|
||||
// 未购买过
|
||||
systemSingleDao := dao.SystemSingleDao{}
|
||||
|
||||
maps := make(map[string]interface{})
|
||||
systemSingle, err := systemSingleDao.GetSystemSingle(maps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p = &systemSingle.FirstTimePrice
|
||||
}
|
||||
|
||||
// 处理问题优惠价格
|
||||
if p == nil {
|
||||
p = r.HandleQuestionDiscountPrice(question.DiscountPrice, question.DiscountEndTime)
|
||||
}
|
||||
|
||||
if p == nil {
|
||||
p = &question.Price
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// CheckQuestion 检测题目
|
||||
func (r *QuestionService) CheckQuestion(m *model.Question) (bool, error) {
|
||||
if m.QuestionStatus != 1 {
|
||||
return false, errors.New("题目异常")
|
||||
}
|
||||
|
||||
if m.IsHide != 0 {
|
||||
return false, errors.New("题目异常")
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// HandleQuestionDiscountPrice 处理问题优惠价格
|
||||
func (r *QuestionService) HandleQuestionDiscountPrice(discountPrice *float64, discountEndTime *time.Time) (p *float64) {
|
||||
// 优惠价格
|
||||
if discountPrice != nil {
|
||||
// 检测是否超出优惠时间
|
||||
now := time.Now()
|
||||
if discountEndTime.Before(now) {
|
||||
p = nil
|
||||
} else {
|
||||
p = discountPrice
|
||||
}
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// GetQuestionBaseClass 获取问题关联分类
|
||||
func (r *QuestionService) GetQuestionBaseClass(questionId int64) (g []*dto.BaseClassDto, err error) {
|
||||
questionClassDao := dao.QuestionClassDao{}
|
||||
questionClass, _ := questionClassDao.GetQuestionClassListByQuestionId(questionId)
|
||||
if len(questionClass) > 0 {
|
||||
baseClassDao := dao.BaseClassDao{}
|
||||
for _, class := range questionClass {
|
||||
baseClass, err := baseClassDao.GetBaseClassById(class.ClassId)
|
||||
if err != nil {
|
||||
return nil, errors.New("题目异常")
|
||||
}
|
||||
|
||||
baseClassDto := dto.GetBaseClassDto(baseClass)
|
||||
|
||||
g = append(g, baseClassDto)
|
||||
}
|
||||
}
|
||||
|
||||
return g, nil
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package service
|
||||
|
||||
import "hepa-calc-admin-api/api/model"
|
||||
|
||||
type SystemMemberService struct {
|
||||
}
|
||||
|
||||
// GetSystemMemberBuyPrice 获取会员购买价格
|
||||
func (r *SystemMemberService) GetSystemMemberBuyPrice(m *model.SystemMember) (p float64) {
|
||||
p = m.Price
|
||||
|
||||
if m.DiscountPrice != nil {
|
||||
p = *m.DiscountPrice
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"gorm.io/gorm"
|
||||
"hepa-calc-admin-api/api/dao"
|
||||
"hepa-calc-admin-api/api/model"
|
||||
"hepa-calc-admin-api/extend/aliyun"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserService struct {
|
||||
}
|
||||
|
||||
// HandleUserAvatar 处理用户头像
|
||||
func (r *UserService) HandleUserAvatar(wxAvatar string) (avatar string, err error) {
|
||||
if wxAvatar == "" {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// 发送GET请求
|
||||
resp, err := http.Get(wxAvatar)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer func(Body io.ReadCloser) {
|
||||
_ = Body.Close()
|
||||
}(resp.Body)
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return "", errors.New("请求失败")
|
||||
}
|
||||
|
||||
// 读取响应体
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 设置文件名字
|
||||
now := time.Now()
|
||||
dateTimeString := now.Format("20060102150405") // 当前时间字符串
|
||||
rand.New(rand.NewSource(time.Now().UnixNano())) // 设置随机数
|
||||
ossPath := "user/avatar/" + dateTimeString + fmt.Sprintf("%d", rand.Intn(9000)+1000) + ".png"
|
||||
|
||||
// 上传oss
|
||||
_, err = aliyun.PutObjectByte(ossPath, respBody)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
ossPath = "/" + ossPath
|
||||
|
||||
return ossPath, nil
|
||||
}
|
||||
|
||||
// CheckUserMember 检测用户会员
|
||||
func (r *UserService) CheckUserMember(user *model.User) bool {
|
||||
if user.IsMember == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
if user.MemberExpireDate.Before(now) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// CheckUserBuyOrderMember 检测用户是否购买过会员
|
||||
func (r *UserService) CheckUserBuyOrderMember(userId int64) bool {
|
||||
orderMemberDao := dao.OrderMemberDao{}
|
||||
orderMember, _ := orderMemberDao.GetUserFirstTimeBuyOrderMember(userId)
|
||||
if orderMember == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// AddUserMemberValidDate 增加用户会员过期时间
|
||||
func (r *UserService) AddUserMemberValidDate(tx *gorm.DB, user *model.User, d int) bool {
|
||||
userData := make(map[string]interface{})
|
||||
if user.IsMember == 0 {
|
||||
userData["is_member"] = 1
|
||||
}
|
||||
|
||||
if user.MemberExpireDate == nil {
|
||||
userData["is_member"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
} else {
|
||||
userData["is_member"] = user.MemberExpireDate.Add(time.Duration(d) * 24 * time.Hour)
|
||||
}
|
||||
|
||||
userDao := dao.UserDao{}
|
||||
err := userDao.EditUserById(tx, user.UserId, userData)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"hepa-calc-admin-api/api/dao"
|
||||
"hepa-calc-admin-api/api/model"
|
||||
"hepa-calc-admin-api/global"
|
||||
)
|
||||
|
||||
type UserCollectionService struct {
|
||||
}
|
||||
|
||||
// GetUserCollectionQuestionStatus 检测用户收藏状态
|
||||
func (r *UserCollectionService) GetUserCollectionQuestionStatus(userId, questionId int64) bool {
|
||||
userCollectionDao := dao.UserCollectionDao{}
|
||||
|
||||
maps := make(map[string]interface{})
|
||||
maps["user_id"] = userId
|
||||
maps["question_id"] = questionId
|
||||
userCollection, _ := userCollectionDao.GetUserCollection(maps)
|
||||
if userCollection == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// PutUserCollection 收藏题目
|
||||
func (r *UserCollectionService) PutUserCollection(userId, questionId int64) (bool, error) {
|
||||
// 检测用户收藏状态
|
||||
IsCollection := r.GetUserCollectionQuestionStatus(userId, questionId)
|
||||
if IsCollection == true {
|
||||
// 已收藏
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// 开始事务
|
||||
tx := global.Db.Begin()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
userCollection := &model.UserCollection{
|
||||
UserId: userId,
|
||||
QuestionId: questionId,
|
||||
}
|
||||
|
||||
userCollectionDao := dao.UserCollectionDao{}
|
||||
userCollection, err := userCollectionDao.AddUserCollection(tx, userCollection)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return false, errors.New("收藏失败")
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// PutUserCollectionCancel 取消收藏题目
|
||||
func (r *UserCollectionService) PutUserCollectionCancel(userId, questionId int64) (bool, error) {
|
||||
// 检测用户收藏状态
|
||||
IsCollection := r.GetUserCollectionQuestionStatus(userId, questionId)
|
||||
if IsCollection == false {
|
||||
// 已收藏
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// 开始事务
|
||||
tx := global.Db.Begin()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
userCollectionDao := dao.UserCollectionDao{}
|
||||
|
||||
maps := make(map[string]interface{})
|
||||
maps["user_id"] = userId
|
||||
maps["question_id"] = questionId
|
||||
err := userCollectionDao.DeleteUserCollection(tx, maps)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return false, errors.New("取消收藏失败")
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
return true, nil
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"gorm.io/gorm"
|
||||
"hepa-calc-admin-api/api/dao"
|
||||
"hepa-calc-admin-api/api/dto"
|
||||
"hepa-calc-admin-api/api/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserCouponService struct {
|
||||
}
|
||||
|
||||
// CheckUserCoupon 检测用户优惠卷
|
||||
// orderType:类型(1:单项 2:会员)
|
||||
func (r *UserCouponService) CheckUserCoupon(m *model.UserCoupon, id int64, orderType int, amountTotal float64) (bool, error) {
|
||||
if m.UserCouponStatus == 1 {
|
||||
return false, errors.New("优惠卷异常")
|
||||
}
|
||||
|
||||
if m.UserCouponStatus == 2 {
|
||||
return false, errors.New("优惠卷已过期,无法使用")
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
validEndTime := time.Time(m.ValidEndTime)
|
||||
if validEndTime.Before(now) {
|
||||
return false, errors.New("优惠卷已过期,无法使用")
|
||||
}
|
||||
|
||||
if m.Coupon == nil {
|
||||
return false, errors.New("优惠卷异常")
|
||||
}
|
||||
|
||||
// 检测优惠卷状态
|
||||
if m.Coupon.CouponStatus == 2 {
|
||||
return false, errors.New("优惠卷已失效,无法使用")
|
||||
}
|
||||
|
||||
if m.Coupon.CouponStatus == 3 {
|
||||
return false, errors.New("优惠卷无法使用")
|
||||
}
|
||||
|
||||
if m.Coupon.CouponStatus == 4 {
|
||||
return false, errors.New("优惠卷异常,无法使用")
|
||||
}
|
||||
|
||||
// 检测价格
|
||||
if m.Coupon.CouponType == 2 {
|
||||
if *m.Coupon.WithAmount > amountTotal {
|
||||
return false, errors.New("优惠卷不符合满减金额标准,无法使用")
|
||||
}
|
||||
}
|
||||
|
||||
// 单项
|
||||
if orderType == 1 {
|
||||
if m.Coupon.ApplicationScope != 1 && m.Coupon.ApplicationScope != 2 {
|
||||
return false, errors.New("优惠卷无法使用")
|
||||
}
|
||||
|
||||
if id != *m.Coupon.QuestionId {
|
||||
return false, errors.New("优惠卷无法使用")
|
||||
}
|
||||
}
|
||||
|
||||
// 会员
|
||||
if orderType == 2 {
|
||||
if m.Coupon.ApplicationScope != 1 && m.Coupon.ApplicationScope != 3 {
|
||||
return false, errors.New("优惠卷无法使用")
|
||||
}
|
||||
|
||||
if id != *m.Coupon.SystemMemberId {
|
||||
return false, errors.New("优惠卷无法使用")
|
||||
}
|
||||
}
|
||||
|
||||
// 检测优惠劵过期时间
|
||||
if m.Coupon.ValidType == 1 {
|
||||
validEndTime = time.Time(*m.Coupon.ValidEndTime)
|
||||
if validEndTime.Before(now) {
|
||||
return false, errors.New("优惠卷已过期,无法使用")
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// ReturnUserCoupon 退还优惠卷
|
||||
func (r *UserCouponService) ReturnUserCoupon(tx *gorm.DB, userCouponId int64) bool {
|
||||
// 获取优惠卷数据
|
||||
UserCouponDao := dao.UserCouponDao{}
|
||||
userCoupon, err := UserCouponDao.GetUserCouponPreloadById(userCouponId)
|
||||
if err != nil {
|
||||
// 无该优惠卷数据,无需处理
|
||||
return true
|
||||
}
|
||||
|
||||
userCouponDao := dao.UserCouponDao{}
|
||||
userCouponData := make(map[string]interface{})
|
||||
|
||||
// 检测优惠卷过期时间。判断是否需要退还
|
||||
now := time.Now()
|
||||
validEndTime := time.Time(userCoupon.ValidEndTime)
|
||||
if validEndTime.Before(now) {
|
||||
userCouponData["user_coupon_status"] = 3
|
||||
} else {
|
||||
userCouponData["user_coupon_status"] = 0
|
||||
}
|
||||
|
||||
userCouponData["coupon_use_date"] = nil
|
||||
err = userCouponDao.EditUserCouponById(tx, userCoupon.UserCouponId, userCouponData)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUserUsableQuestionCoupon 获取用户可使用优惠卷-单项
|
||||
func (r *UserCouponService) GetUserUsableQuestionCoupon(userId, questionId int64, amountTotal float64) (g []*dto.UserCouponDto, err error) {
|
||||
// 获取用户数据
|
||||
userDao := dao.UserDao{}
|
||||
user, err := userDao.GetUserById(userId)
|
||||
if err != nil || user == nil {
|
||||
return nil, errors.New("用户错误")
|
||||
}
|
||||
|
||||
// 检测用户会员
|
||||
userService := &UserService{}
|
||||
isMember := userService.CheckUserMember(user)
|
||||
if isMember == true {
|
||||
// 会员无需使用优惠卷
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// 获取用户优惠卷
|
||||
UserCouponDao := dao.UserCouponDao{}
|
||||
|
||||
maps := make(map[string]interface{})
|
||||
maps["user_id"] = userId
|
||||
maps["user_coupon_status"] = 0
|
||||
userCoupons, err := UserCouponDao.GetUserCouponPreloadList(maps)
|
||||
if err != nil {
|
||||
return nil, errors.New("优惠券异常")
|
||||
}
|
||||
|
||||
//定义返回数据
|
||||
var responses []*model.UserCoupon
|
||||
|
||||
for _, userCoupon := range userCoupons {
|
||||
isCanUse, err := r.CheckUserCoupon(userCoupon, questionId, 1, amountTotal)
|
||||
if err != nil || isCanUse == false {
|
||||
continue
|
||||
}
|
||||
|
||||
responses = append(responses, userCoupon)
|
||||
}
|
||||
|
||||
g = dto.GetUserCouponListDto(responses)
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
// GetUserUsableMemberCoupon 获取用户可使用优惠卷-会员
|
||||
func (r *UserCouponService) GetUserUsableMemberCoupon(userId, systemMemberId int64, amountTotal float64) (g []*dto.UserCouponDto, err error) {
|
||||
// 获取用户数据
|
||||
userDao := dao.UserDao{}
|
||||
user, err := userDao.GetUserById(userId)
|
||||
if err != nil || user == nil {
|
||||
return nil, errors.New("用户错误")
|
||||
}
|
||||
|
||||
// 检测用户会员
|
||||
userService := &UserService{}
|
||||
isMember := userService.CheckUserMember(user)
|
||||
if isMember == true {
|
||||
// 会员无需使用优惠卷
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// 获取用户优惠卷
|
||||
UserCouponDao := dao.UserCouponDao{}
|
||||
|
||||
maps := make(map[string]interface{})
|
||||
maps["user_id"] = userId
|
||||
maps["user_coupon_status"] = 0
|
||||
userCoupons, err := UserCouponDao.GetUserCouponPreloadList(maps)
|
||||
if err != nil {
|
||||
return nil, errors.New("优惠券异常")
|
||||
}
|
||||
|
||||
//定义返回数据
|
||||
var responses []*model.UserCoupon
|
||||
|
||||
for _, userCoupon := range userCoupons {
|
||||
isCanUse, err := r.CheckUserCoupon(userCoupon, systemMemberId, 2, amountTotal)
|
||||
if err != nil || isCanUse == false {
|
||||
continue
|
||||
}
|
||||
|
||||
responses = append(responses, userCoupon)
|
||||
}
|
||||
|
||||
g = dto.GetUserCouponListDto(responses)
|
||||
|
||||
return g, nil
|
||||
}
|
||||
Reference in New Issue
Block a user