增加了微信支付
This commit is contained in:
parent
8c84ed3656
commit
a525a67a01
@ -12,4 +12,5 @@ type Api struct {
|
||||
OrderSingle // 订单-单项
|
||||
SystemMember // 会员配置
|
||||
OrderMember // 订单-会员
|
||||
CallBack // 回调
|
||||
}
|
||||
|
||||
23
api/controller/CallBack.go
Normal file
23
api/controller/CallBack.go
Normal file
@ -0,0 +1,23 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"hepa-calc-api/api/responses"
|
||||
"hepa-calc-api/extend/weChat"
|
||||
"hepa-calc-api/utils"
|
||||
)
|
||||
|
||||
// CallBack 回调
|
||||
type CallBack struct{}
|
||||
|
||||
// WxJsapiPay 微信支付回调-jsapi
|
||||
func (r *CallBack) WxJsapiPay(c *gin.Context) {
|
||||
notifyReq, err := weChat.ParseNotify(c)
|
||||
if err != nil {
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
// 记录日志
|
||||
utils.LogJsonErr("微信支付回调-jsapi", notifyReq)
|
||||
}
|
||||
@ -1,13 +1,17 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"hepa-calc-api/api/dao"
|
||||
"hepa-calc-api/api/dto"
|
||||
"hepa-calc-api/api/requests"
|
||||
"hepa-calc-api/api/responses"
|
||||
"hepa-calc-api/api/service"
|
||||
"hepa-calc-api/global"
|
||||
"hepa-calc-api/utils"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type OrderMember struct{}
|
||||
@ -56,3 +60,157 @@ func (b *OrderMember) GetOrderMemberPage(c *gin.Context) {
|
||||
result["data"] = g
|
||||
responses.OkWithData(result, c)
|
||||
}
|
||||
|
||||
// AddOrderMember 创建会员订单
|
||||
func (b *OrderMember) AddOrderMember(c *gin.Context) {
|
||||
orderMemberRequest := requests.OrderMemberRequest{}
|
||||
req := orderMemberRequest.AddOrderMember
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := global.Validate.Struct(req); err != nil {
|
||||
responses.FailWithMessage(utils.Translate(err), c)
|
||||
return
|
||||
}
|
||||
|
||||
userId := c.GetInt64("UserId")
|
||||
|
||||
// 将 id 转换为 int64 类型
|
||||
systemMemberId, err := strconv.ParseInt(req.SystemMemberId, 10, 64)
|
||||
if err != nil {
|
||||
responses.Fail(c)
|
||||
return
|
||||
}
|
||||
|
||||
// 用户优惠卷id
|
||||
var userCouponId *int64
|
||||
if req.UserCouponId != "" {
|
||||
id, err := strconv.ParseInt(req.UserCouponId, 10, 64)
|
||||
if err != nil {
|
||||
responses.Fail(c)
|
||||
return
|
||||
}
|
||||
|
||||
userCouponId = &id
|
||||
}
|
||||
|
||||
if req.OrderPrice < 0 {
|
||||
responses.FailWithMessage("价格错误", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 开始事务
|
||||
tx := global.Db.Begin()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
// 创建会员订单
|
||||
orderMemberService := service.OrderMemberService{}
|
||||
orderMember, err := orderMemberService.AddOrderMember(tx, userId, systemMemberId, userCouponId, req.PayChannel, req.OrderPrice)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
|
||||
// 处理返回值
|
||||
orderId := fmt.Sprintf("%d", orderMember.OrderId)
|
||||
|
||||
responses.OkWithData(orderId, c)
|
||||
}
|
||||
|
||||
// GetOrderMemberPay 获取会员订单支付数据
|
||||
func (b *OrderMember) GetOrderMemberPay(c *gin.Context) {
|
||||
orderMemberRequest := requests.OrderMemberRequest{}
|
||||
req := orderMemberRequest.GetOrderMemberPay
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := global.Validate.Struct(req); err != nil {
|
||||
responses.FailWithMessage(utils.Translate(err), c)
|
||||
return
|
||||
}
|
||||
|
||||
userId := c.GetInt64("UserId")
|
||||
|
||||
id := c.Param("order_id")
|
||||
if id == "" {
|
||||
responses.FailWithMessage("缺少参数", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 将 id 转换为 int64 类型
|
||||
orderId, err := strconv.ParseInt(id, 10, 64)
|
||||
if err != nil {
|
||||
responses.Fail(c)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取订单数据
|
||||
orderMemberDao := dao.OrderMemberDao{}
|
||||
maps := make(map[string]interface{})
|
||||
maps["user_id"] = userId
|
||||
maps["order_id"] = orderId
|
||||
orderMember, err := orderMemberDao.GetOrderMember(maps)
|
||||
if err != nil {
|
||||
responses.FailWithMessage("订单异常", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 检测订单状态(1:待支付 2:已完成 3:已取消)
|
||||
if orderMember.OrderStatus != 1 {
|
||||
responses.FailWithMessage("订单状态异常", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
|
||||
if orderMember.PayStatus != 1 {
|
||||
responses.FailWithMessage("订单支付状态异常", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 验证订单过期支付时间
|
||||
now := time.Now()
|
||||
validTime := time.Time(orderMember.CreatedAt).Add(30 * time.Minute)
|
||||
if validTime.Before(now) {
|
||||
responses.FailWithMessage("订单已过期", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 处理返回值
|
||||
g := dto.GetOrderMemberPayDto(orderMember)
|
||||
|
||||
// 获取预支付交易会话标识
|
||||
if req.ClientType == 1 {
|
||||
orderMemberService := service.OrderMemberService{}
|
||||
prepay, err := orderMemberService.GetJsapiPrepay(orderMember)
|
||||
if err != nil {
|
||||
responses.FailWithMessage("发起支付失败", c)
|
||||
return
|
||||
}
|
||||
|
||||
g.PrepayJsapi = prepay
|
||||
} else {
|
||||
orderMemberService := service.OrderMemberService{}
|
||||
prepay, err := orderMemberService.GetAppPrepay(orderMember)
|
||||
if err != nil {
|
||||
responses.FailWithMessage("发起支付失败", c)
|
||||
return
|
||||
}
|
||||
|
||||
g.PrepayApp = prepay
|
||||
}
|
||||
|
||||
responses.OkWithData(g, c)
|
||||
}
|
||||
|
||||
@ -97,6 +97,25 @@ func (b *OrderSingle) AddOrderSingle(c *gin.Context) {
|
||||
userCouponId = &id
|
||||
}
|
||||
|
||||
// 获取用户数据
|
||||
userDao := dao.UserDao{}
|
||||
user, err := userDao.GetUserById(userId)
|
||||
if err != nil || user == nil {
|
||||
responses.FailWithMessage("用户错误", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 检测是否会员
|
||||
if req.PayChannel == 3 && user.IsMember == 0 {
|
||||
responses.FailWithMessage("非法操作", c)
|
||||
return
|
||||
}
|
||||
|
||||
if req.OrderPrice < 0 {
|
||||
responses.FailWithMessage("价格错误", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 开始事务
|
||||
tx := global.Db.Begin()
|
||||
defer func() {
|
||||
@ -107,7 +126,7 @@ func (b *OrderSingle) AddOrderSingle(c *gin.Context) {
|
||||
|
||||
// 创建单项订单
|
||||
orderSingleService := service.OrderSingleService{}
|
||||
orderSingle, err := orderSingleService.AddOrderSingle(tx, userId, questionId, userCouponId, req.PayChannel)
|
||||
orderSingle, err := orderSingleService.AddOrderSingle(tx, userId, questionId, userCouponId, req.PayChannel, req.OrderPrice)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"hepa-calc-api/global"
|
||||
"hepa-calc-api/utils"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Question struct{}
|
||||
@ -99,12 +100,16 @@ func (r *Question) GetQuestion(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 检测问题是否被用户收藏
|
||||
questionService := service.QuestionService{}
|
||||
|
||||
// 处理问题优惠价格
|
||||
question.DiscountPrice = questionService.HandleQuestionDiscountPrice(question.DiscountPrice, question.DiscountEndTime)
|
||||
|
||||
// 检测用户收藏状态
|
||||
userCollectionService := service.UserCollectionService{}
|
||||
IsCollection := userCollectionService.CheckUserCollectionQuestion(userId, questionId)
|
||||
IsCollection := userCollectionService.GetUserCollectionQuestionStatus(userId, questionId)
|
||||
|
||||
// 获取用户首次购买价格
|
||||
questionService := service.QuestionService{}
|
||||
firstTimePrice, err := questionService.GetUserFirstTimeBuyPrice(userId, questionId)
|
||||
if err != nil {
|
||||
responses.FailWithMessage("题目错误", c)
|
||||
@ -112,7 +117,7 @@ func (r *Question) GetQuestion(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 获取问题被购买数量
|
||||
buyCount, err := questionService.GetQuestionBuyCount(userId, questionId)
|
||||
buyCount, _ := questionService.GetQuestionBuyCount(userId, questionId)
|
||||
|
||||
g := dto.GetQuestionDto(question)
|
||||
|
||||
@ -127,3 +132,117 @@ func (r *Question) GetQuestion(c *gin.Context) {
|
||||
|
||||
responses.OkWithData(g, c)
|
||||
}
|
||||
|
||||
// GetQuestionBuyStatus 获取问题购买状态
|
||||
func (r *Question) GetQuestionBuyStatus(c *gin.Context) {
|
||||
// 购买状态(0:否 1:是)
|
||||
var status int
|
||||
userId := c.GetInt64("UserId")
|
||||
|
||||
id := c.Param("question_id")
|
||||
if id == "" {
|
||||
responses.FailWithMessage("缺少参数", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 将 id 转换为 int64 类型
|
||||
questionId, err := strconv.ParseInt(id, 10, 64)
|
||||
if err != nil {
|
||||
responses.Fail(c)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取题目数据
|
||||
questionDao := dao.QuestionDao{}
|
||||
question, err := questionDao.GetQuestionById(questionId)
|
||||
if err != nil {
|
||||
responses.FailWithMessage("题目错误", c)
|
||||
return
|
||||
}
|
||||
|
||||
if question.QuestionStatus != 1 {
|
||||
responses.FailWithMessage("题目错误", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取用户数据
|
||||
userDao := dao.UserDao{}
|
||||
user, err := userDao.GetUserById(userId)
|
||||
if err != nil || user == nil {
|
||||
responses.FailWithMessage("用户错误", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 检测用户会员
|
||||
userService := service.UserService{}
|
||||
isMember := userService.CheckUserMember(user)
|
||||
if isMember == true {
|
||||
// 用户为会员,可直接查看
|
||||
status = 1
|
||||
responses.OkWithData(status, c)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取单项配置
|
||||
systemSingleDao := dao.SystemSingleDao{}
|
||||
|
||||
maps := make(map[string]interface{})
|
||||
systemSingle, err := systemSingleDao.GetSystemSingle(maps)
|
||||
if err != nil {
|
||||
responses.FailWithMessage("内部错误", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取用户订单
|
||||
orderSingleDao := dao.OrderSingleDao{}
|
||||
maps = make(map[string]interface{})
|
||||
maps["user_id"] = userId
|
||||
maps["question_id"] = questionId
|
||||
orderSingles, err := orderSingleDao.GetOrderSingleList(maps)
|
||||
if err != nil {
|
||||
responses.FailWithMessage("用户错误", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 是否购买过(0:否 1:是)
|
||||
var isBuy int
|
||||
for _, single := range orderSingles {
|
||||
// 订单状态(1:待支付 2:已完成 3:已取消)
|
||||
if single.OrderStatus != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
|
||||
if single.PayStatus != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常 7:部分退款)
|
||||
if single.RefundStatus != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 取消状态(0:否 1:是)
|
||||
if single.CancelStatus == 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 判断是否还在有效期内
|
||||
now := time.Now()
|
||||
ValidTime := single.PayTime.Add(time.Duration(systemSingle.ValidDays))
|
||||
if ValidTime.Before(now) {
|
||||
continue
|
||||
}
|
||||
|
||||
isBuy = 1
|
||||
break
|
||||
}
|
||||
|
||||
if isBuy == 1 {
|
||||
status = 1
|
||||
responses.OkWithData(status, c)
|
||||
return
|
||||
}
|
||||
|
||||
responses.OkWithData(status, c)
|
||||
}
|
||||
|
||||
@ -1,27 +1,40 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"hepa-calc-api/api/dao"
|
||||
"hepa-calc-api/api/dto"
|
||||
"hepa-calc-api/api/responses"
|
||||
"hepa-calc-api/api/service"
|
||||
)
|
||||
|
||||
type SystemMember struct{}
|
||||
|
||||
// GetSystemMember 获取会员配置数据
|
||||
func (b *SystemMember) GetSystemMember(c *gin.Context) {
|
||||
userId := c.GetInt64("UserId")
|
||||
|
||||
systemMemberDao := dao.SystemMemberDao{}
|
||||
|
||||
maps := make(map[string]interface{})
|
||||
systemMember, err := systemMemberDao.GetSystemMemberList(maps)
|
||||
systemMembers, err := systemMemberDao.GetSystemMemberList(maps)
|
||||
if err != nil {
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
// 检测用户是否购买过会员
|
||||
userService := service.UserService{}
|
||||
isBuy := userService.CheckUserBuyOrderMember(userId)
|
||||
if isBuy == true {
|
||||
for _, member := range systemMembers {
|
||||
fmt.Println(member)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理返回值
|
||||
g := dto.GetSystemMemberListDto(systemMember)
|
||||
g := dto.GetSystemMemberListDto(systemMembers)
|
||||
|
||||
responses.OkWithData(g, c)
|
||||
}
|
||||
|
||||
@ -6,8 +6,10 @@ import (
|
||||
"hepa-calc-api/api/dto"
|
||||
"hepa-calc-api/api/requests"
|
||||
"hepa-calc-api/api/responses"
|
||||
"hepa-calc-api/api/service"
|
||||
"hepa-calc-api/global"
|
||||
"hepa-calc-api/utils"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type UserCoupon struct{}
|
||||
@ -89,10 +91,10 @@ func (b *UserCoupon) GetUserCouponUnnotified(c *gin.Context) {
|
||||
responses.OkWithData(g, c)
|
||||
}
|
||||
|
||||
// GetUserUsableCoupon 获取用户当前可用优惠卷
|
||||
func (b *UserCoupon) GetUserUsableCoupon(c *gin.Context) {
|
||||
// GetUserUsableQuestionCoupon 获取患者可使用优惠卷-单项
|
||||
func (b *UserCoupon) GetUserUsableQuestionCoupon(c *gin.Context) {
|
||||
userCouponRequest := requests.UserCouponRequest{}
|
||||
req := userCouponRequest.GetUserCouponPage
|
||||
req := userCouponRequest.GetUserUsableQuestionCoupon
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
@ -104,32 +106,49 @@ func (b *UserCoupon) GetUserUsableCoupon(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if req.Page == 0 {
|
||||
req.Page = 1
|
||||
}
|
||||
|
||||
if req.PageSize == 0 {
|
||||
req.PageSize = 20
|
||||
}
|
||||
|
||||
userId := c.GetInt64("UserId")
|
||||
req.UserId = userId
|
||||
|
||||
// 获取数据
|
||||
userCouponDao := dao.UserCouponDao{}
|
||||
userCoupon, total, err := userCouponDao.GetUserCouponPageSearch(req, req.Page, req.PageSize)
|
||||
// 将 id 转换为 int64 类型
|
||||
questionId, err := strconv.ParseInt(req.QuestionId, 10, 64)
|
||||
if err != nil {
|
||||
responses.Fail(c)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取患者可使用优惠卷-单项
|
||||
userCouponService := service.UserCouponService{}
|
||||
userCoupon, _ := userCouponService.GetUserUsableQuestionCoupon(userId, questionId, req.AmountTotal)
|
||||
|
||||
responses.OkWithData(userCoupon, c)
|
||||
}
|
||||
|
||||
// GetUserUsableMemberCoupon 获取患者可使用优惠卷-会员
|
||||
func (b *UserCoupon) GetUserUsableMemberCoupon(c *gin.Context) {
|
||||
userCouponRequest := requests.UserCouponRequest{}
|
||||
req := userCouponRequest.GetUserUsableMemberCoupon
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
// 处理返回值
|
||||
g := dto.GetUserCouponListDto(userCoupon)
|
||||
// 参数验证
|
||||
if err := global.Validate.Struct(req); err != nil {
|
||||
responses.FailWithMessage(utils.Translate(err), c)
|
||||
return
|
||||
}
|
||||
|
||||
result := make(map[string]interface{})
|
||||
result["page"] = req.Page
|
||||
result["page_size"] = req.PageSize
|
||||
result["total"] = total
|
||||
result["data"] = g
|
||||
responses.OkWithData(result, c)
|
||||
userId := c.GetInt64("UserId")
|
||||
|
||||
// 将 id 转换为 int64 类型
|
||||
systemMemberId, err := strconv.ParseInt(req.SystemMemberId, 10, 64)
|
||||
if err != nil {
|
||||
responses.Fail(c)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取患者可使用优惠卷-会员
|
||||
userCouponService := service.UserCouponService{}
|
||||
userCoupon, _ := userCouponService.GetUserUsableMemberCoupon(userId, systemMemberId, req.AmountTotal)
|
||||
|
||||
responses.OkWithData(userCoupon, c)
|
||||
}
|
||||
|
||||
@ -173,3 +173,15 @@ func (r *OrderMemberDao) GetOrderMemberPageSearch(req requests.GetOrderMemberPag
|
||||
}
|
||||
return m, totalRecords, nil
|
||||
}
|
||||
|
||||
// GetUserFirstTimeBuyOrderMember 获取用户首次购买的订单
|
||||
func (r *OrderMemberDao) GetUserFirstTimeBuyOrderMember(userId int64) (m *model.OrderMember, err error) {
|
||||
err = global.Db.
|
||||
Where("user_id = ?", userId).
|
||||
Where("order_status != ?", 2).
|
||||
First(&m).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
@ -75,6 +75,15 @@ func (r *UserCouponDao) GetUserCouponList(maps interface{}) (m []*model.UserCoup
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// GetUserCouponPreloadList 获取列表-加载全部关联
|
||||
func (r *UserCouponDao) GetUserCouponPreloadList(maps interface{}) (m []*model.UserCoupon, err error) {
|
||||
err = global.Db.Preload(clause.Associations).Where(maps).Find(&m).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// GetUserCouponCount 获取数量
|
||||
func (r *UserCouponDao) GetUserCouponCount(maps interface{}) (total int64, err error) {
|
||||
err = global.Db.Model(&model.UserCoupon{}).Where(maps).Count(&total).Error
|
||||
|
||||
@ -2,10 +2,13 @@ package dto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/app"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
|
||||
"hepa-calc-api/api/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
// OrderMemberDto 订单-单项
|
||||
// OrderMemberDto 订单-会员
|
||||
type OrderMemberDto struct {
|
||||
OrderId string `json:"order_id"` // 主键id
|
||||
UserId string `json:"user_id"` // 用户id
|
||||
@ -14,7 +17,7 @@ type OrderMemberDto struct {
|
||||
IsDelete int `json:"is_delete"` // 用户删除状态(0:否 1:是)
|
||||
PayChannel int `json:"pay_channel"` // 支付渠道(1:h5支付 2:app支付 3:会员支付)
|
||||
PayStatus int `json:"pay_status"` // 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
|
||||
PayTime model.LocalTime `json:"pay_time"` // 支付时间
|
||||
PayTime *time.Time `json:"pay_time"` // 支付时间
|
||||
RefundStatus int `json:"refund_status"` // 订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常 7:部分退款)
|
||||
OrderNo string `json:"order_no"` // 系统订单编号
|
||||
EscrowTradeNo string `json:"escrow_trade_no"` // 第三方支付流水号
|
||||
@ -22,7 +25,7 @@ type OrderMemberDto struct {
|
||||
CouponAmountTotal float64 `json:"coupon_amount_total"` // 优惠卷总金额
|
||||
PaymentAmountTotal float64 `json:"payment_amount_total"` // 实际付款金额
|
||||
CancelStatus int `json:"cancel_status"` // 取消状态(0:否 1:是)
|
||||
CancelTime model.LocalTime `json:"cancel_time"` // 订单取消时间
|
||||
CancelTime *time.Time `json:"cancel_time"` // 订单取消时间
|
||||
CancelRemarks string `json:"cancel_remarks"` // 取消订单备注
|
||||
OrderRemarks string `json:"order_remarks"` // 订单备注
|
||||
CreatedAt model.LocalTime `json:"created_at"` // 创建时间
|
||||
@ -30,6 +33,19 @@ type OrderMemberDto struct {
|
||||
SystemMember *SystemMemberDto `json:"system_member"` // 会员
|
||||
}
|
||||
|
||||
// OrderMemberPayDto 会员订单支付数据
|
||||
type OrderMemberPayDto struct {
|
||||
OrderId string `json:"order_id"` // 主键id
|
||||
SystemMemberId string `json:"system_member_id"` // 会员id
|
||||
OrderNo string `json:"order_no"` // 系统订单编号
|
||||
AmountTotal float64 `json:"amount_total"` // 订单金额
|
||||
CouponAmountTotal float64 `json:"coupon_amount_total"` // 优惠卷总金额
|
||||
PaymentAmountTotal float64 `json:"payment_amount_total"` // 实际付款金额
|
||||
CreatedAt model.LocalTime `json:"created_at"` // 创建时间
|
||||
PrepayJsapi *jsapi.PrepayWithRequestPaymentResponse `json:"prepay_jsapi"` // 预支付交易数据-jsapi
|
||||
PrepayApp *app.PrepayWithRequestPaymentResponse `json:"prepay_app"` // 预支付交易数据-app
|
||||
}
|
||||
|
||||
// GetOrderMemberListDto 列表
|
||||
func GetOrderMemberListDto(m []*model.OrderMember) []*OrderMemberDto {
|
||||
// 处理返回值
|
||||
@ -73,6 +89,19 @@ func GetOrderMemberListDto(m []*model.OrderMember) []*OrderMemberDto {
|
||||
return responses
|
||||
}
|
||||
|
||||
// GetOrderMemberPayDto 获取单项订单支付数据
|
||||
func GetOrderMemberPayDto(m *model.OrderMember) *OrderMemberPayDto {
|
||||
return &OrderMemberPayDto{
|
||||
OrderId: fmt.Sprintf("%d", m.OrderId),
|
||||
SystemMemberId: fmt.Sprintf("%d", m.SystemMemberId),
|
||||
OrderNo: m.OrderNo,
|
||||
AmountTotal: m.AmountTotal,
|
||||
CouponAmountTotal: m.CouponAmountTotal,
|
||||
PaymentAmountTotal: m.PaymentAmountTotal,
|
||||
CreatedAt: m.CreatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
// LoadSystemMember 加载会员数据
|
||||
func (r *OrderMemberDto) LoadSystemMember(m *model.SystemMember) *OrderMemberDto {
|
||||
if m != nil {
|
||||
|
||||
@ -3,6 +3,7 @@ package dto
|
||||
import (
|
||||
"fmt"
|
||||
"hepa-calc-api/api/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
// QuestionDto 问题表
|
||||
@ -19,6 +20,7 @@ type QuestionDto struct {
|
||||
PayCount int `json:"pay_count"` // 支付次数(查看报告的人次)
|
||||
Price float64 `json:"price"` // 价格(原价)
|
||||
DiscountPrice *float64 `json:"discount_price"` // 优惠价格
|
||||
DiscountEndTime *time.Time `json:"discount_end_time"` // 优惠截止时间
|
||||
QuestionBrief string `json:"question_brief"` // 问题介绍
|
||||
QuestionExplain string `json:"question_explain"` // 问题解释/科普
|
||||
CreatedAt model.LocalTime `json:"created_at"` // 创建时间
|
||||
@ -43,6 +45,7 @@ func GetQuestionDto(m *model.Question) *QuestionDto {
|
||||
PayCount: m.PayCount,
|
||||
Price: m.Price,
|
||||
DiscountPrice: m.DiscountPrice,
|
||||
DiscountEndTime: m.DiscountEndTime,
|
||||
QuestionBrief: m.QuestionBrief,
|
||||
QuestionExplain: m.QuestionExplain,
|
||||
CreatedAt: m.CreatedAt,
|
||||
@ -70,6 +73,7 @@ func GetQuestionListDto(m []*model.Question) []*QuestionDto {
|
||||
PayCount: v.PayCount,
|
||||
Price: v.Price,
|
||||
DiscountPrice: v.DiscountPrice,
|
||||
DiscountEndTime: v.DiscountEndTime,
|
||||
QuestionBrief: v.QuestionBrief,
|
||||
QuestionExplain: v.QuestionExplain,
|
||||
CreatedAt: v.CreatedAt,
|
||||
|
||||
@ -3,17 +3,18 @@ package dto
|
||||
import (
|
||||
"fmt"
|
||||
"hepa-calc-api/api/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SystemMemberDto 配置-会员配置
|
||||
type SystemMemberDto struct {
|
||||
SystemMemberId string `json:"system_member_id"` // 主键id
|
||||
MemberDays uint `json:"member_days"` // 会员天数
|
||||
Price float64 `json:"price"` // 价格(原价)
|
||||
DiscountPrice float64 `json:"discount_price"` // 优惠价格
|
||||
FirstTimePrice float64 `json:"first_time_price"` // 首次购买价格
|
||||
CreatedAt model.LocalTime `json:"created_at"` // 创建时间
|
||||
UpdatedAt model.LocalTime `json:"updated_at"` // 更新时间
|
||||
SystemMemberId string `json:"system_member_id"` // 主键id
|
||||
MemberDays uint `json:"member_days"` // 会员天数
|
||||
Price float64 `json:"price"` // 价格(原价)
|
||||
DiscountPrice *float64 `json:"discount_price"` // 优惠价格
|
||||
DiscountEndTime *time.Time `json:"discount_end_time"` // 优惠截止时间
|
||||
CreatedAt model.LocalTime `json:"created_at"` // 创建时间
|
||||
UpdatedAt model.LocalTime `json:"updated_at"` // 更新时间
|
||||
}
|
||||
|
||||
// GetSystemMemberListDto 列表
|
||||
@ -24,13 +25,13 @@ func GetSystemMemberListDto(m []*model.SystemMember) []*SystemMemberDto {
|
||||
if len(m) > 0 {
|
||||
for i, v := range m {
|
||||
response := &SystemMemberDto{
|
||||
SystemMemberId: fmt.Sprintf("%d", v.SystemMemberId),
|
||||
MemberDays: v.MemberDays,
|
||||
Price: v.Price,
|
||||
DiscountPrice: v.DiscountPrice,
|
||||
FirstTimePrice: v.FirstTimePrice,
|
||||
CreatedAt: v.CreatedAt,
|
||||
UpdatedAt: v.UpdatedAt,
|
||||
SystemMemberId: fmt.Sprintf("%d", v.SystemMemberId),
|
||||
MemberDays: v.MemberDays,
|
||||
Price: v.Price,
|
||||
DiscountPrice: v.DiscountPrice,
|
||||
DiscountEndTime: v.DiscountEndTime,
|
||||
CreatedAt: v.CreatedAt,
|
||||
UpdatedAt: v.UpdatedAt,
|
||||
}
|
||||
|
||||
// 将转换后的结构体添加到新切片中
|
||||
@ -44,12 +45,12 @@ func GetSystemMemberListDto(m []*model.SystemMember) []*SystemMemberDto {
|
||||
// GetSystemMemberDto 详情
|
||||
func GetSystemMemberDto(m *model.SystemMember) *SystemMemberDto {
|
||||
return &SystemMemberDto{
|
||||
SystemMemberId: fmt.Sprintf("%d", m.SystemMemberId),
|
||||
MemberDays: m.MemberDays,
|
||||
Price: m.Price,
|
||||
DiscountPrice: m.DiscountPrice,
|
||||
FirstTimePrice: m.FirstTimePrice,
|
||||
CreatedAt: m.CreatedAt,
|
||||
UpdatedAt: m.UpdatedAt,
|
||||
SystemMemberId: fmt.Sprintf("%d", m.SystemMemberId),
|
||||
MemberDays: m.MemberDays,
|
||||
Price: m.Price,
|
||||
DiscountPrice: m.DiscountPrice,
|
||||
DiscountEndTime: m.DiscountEndTime,
|
||||
CreatedAt: m.CreatedAt,
|
||||
UpdatedAt: m.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,24 +8,24 @@ import (
|
||||
|
||||
// OrderMember 订单-单项
|
||||
type OrderMember struct {
|
||||
OrderId int64 `gorm:"column:order_id;type:bigint(19);primary_key;comment:主键id" json:"order_id"`
|
||||
UserId int64 `gorm:"column:user_id;type:bigint(19);comment:用户id;NOT NULL" json:"user_id"`
|
||||
SystemMemberId int64 `gorm:"column:system_member_id;type:bigint(19);comment:会员id;NOT NULL" json:"system_member_id"`
|
||||
OrderStatus int `gorm:"column:order_status;type:tinyint(1);default:1;comment:订单状态(1:待支付 2:已完成 3:已取消)" json:"order_status"`
|
||||
IsDelete int `gorm:"column:is_delete;type:tinyint(1);default:0;comment:用户删除状态(0:否 1:是)" json:"is_delete"`
|
||||
PayChannel int `gorm:"column:pay_channel;type:tinyint(1);comment:支付渠道(1:h5支付 2:app支付 3:会员支付);NOT NULL" json:"pay_channel"`
|
||||
PayStatus int `gorm:"column:pay_status;type:tinyint(1);default:1;comment:支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款);NOT NULL" json:"pay_status"`
|
||||
PayTime LocalTime `gorm:"column:pay_time;type:datetime;comment:支付时间" json:"pay_time"`
|
||||
RefundStatus int `gorm:"column:refund_status;type:tinyint(1);default:0;comment:订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常 7:部分退款);NOT NULL" json:"refund_status"`
|
||||
OrderNo string `gorm:"column:order_no;type:varchar(30);comment:系统订单编号;NOT NULL" json:"order_no"`
|
||||
EscrowTradeNo string `gorm:"column:escrow_trade_no;type:varchar(100);comment:第三方支付流水号;NOT NULL" json:"escrow_trade_no"`
|
||||
AmountTotal float64 `gorm:"column:amount_total;type:decimal(10,2) unsigned;default:0.00;comment:订单金额" json:"amount_total"`
|
||||
CouponAmountTotal float64 `gorm:"column:coupon_amount_total;type:decimal(10,2);default:0.00;comment:优惠卷总金额" json:"coupon_amount_total"`
|
||||
PaymentAmountTotal float64 `gorm:"column:payment_amount_total;type:decimal(10,2);default:0.00;comment:实际付款金额" json:"payment_amount_total"`
|
||||
CancelStatus int `gorm:"column:cancel_status;type:tinyint(1);default:0;comment:取消状态(0:否 1:是)" json:"cancel_status"`
|
||||
CancelTime LocalTime `gorm:"column:cancel_time;type:datetime;comment:订单取消时间" json:"cancel_time"`
|
||||
CancelRemarks string `gorm:"column:cancel_remarks;type:varchar(255);comment:取消订单备注" json:"cancel_remarks"`
|
||||
OrderRemarks string `gorm:"column:order_remarks;type:varchar(255);comment:订单备注" json:"order_remarks"`
|
||||
OrderId int64 `gorm:"column:order_id;type:bigint(19);primary_key;comment:主键id" json:"order_id"`
|
||||
UserId int64 `gorm:"column:user_id;type:bigint(19);comment:用户id;NOT NULL" json:"user_id"`
|
||||
SystemMemberId int64 `gorm:"column:system_member_id;type:bigint(19);comment:会员id;NOT NULL" json:"system_member_id"`
|
||||
OrderStatus int `gorm:"column:order_status;type:tinyint(1);default:1;comment:订单状态(1:待支付 2:已完成 3:已取消)" json:"order_status"`
|
||||
IsDelete int `gorm:"column:is_delete;type:tinyint(1);default:0;comment:用户删除状态(0:否 1:是)" json:"is_delete"`
|
||||
PayChannel int `gorm:"column:pay_channel;type:tinyint(1);comment:支付渠道(1:h5支付 2:app支付 3:会员支付);NOT NULL" json:"pay_channel"`
|
||||
PayStatus int `gorm:"column:pay_status;type:tinyint(1);default:1;comment:支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款);NOT NULL" json:"pay_status"`
|
||||
PayTime *time.Time `gorm:"column:pay_time;type:datetime;comment:支付时间" json:"pay_time"`
|
||||
RefundStatus int `gorm:"column:refund_status;type:tinyint(1);default:0;comment:订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常 7:部分退款);NOT NULL" json:"refund_status"`
|
||||
OrderNo string `gorm:"column:order_no;type:varchar(30);comment:系统订单编号;NOT NULL" json:"order_no"`
|
||||
EscrowTradeNo string `gorm:"column:escrow_trade_no;type:varchar(100);comment:第三方支付流水号;NOT NULL" json:"escrow_trade_no"`
|
||||
AmountTotal float64 `gorm:"column:amount_total;type:decimal(10,2) unsigned;default:0.00;comment:订单金额" json:"amount_total"`
|
||||
CouponAmountTotal float64 `gorm:"column:coupon_amount_total;type:decimal(10,2);default:0.00;comment:优惠卷总金额" json:"coupon_amount_total"`
|
||||
PaymentAmountTotal float64 `gorm:"column:payment_amount_total;type:decimal(10,2);default:0.00;comment:实际付款金额" json:"payment_amount_total"`
|
||||
CancelStatus int `gorm:"column:cancel_status;type:tinyint(1);default:0;comment:取消状态(0:否 1:是)" json:"cancel_status"`
|
||||
CancelTime *time.Time `gorm:"column:cancel_time;type:datetime;comment:订单取消时间" json:"cancel_time"`
|
||||
CancelRemarks string `gorm:"column:cancel_remarks;type:varchar(255);comment:取消订单备注" json:"cancel_remarks"`
|
||||
OrderRemarks string `gorm:"column:order_remarks;type:varchar(255);comment:订单备注" json:"order_remarks"`
|
||||
Model
|
||||
SystemMember *SystemMember `gorm:"foreignKey:SystemMemberId;references:system_member_id" json:"system_member"`
|
||||
}
|
||||
|
||||
@ -8,20 +8,21 @@ import (
|
||||
|
||||
// Question 问题表
|
||||
type Question struct {
|
||||
QuestionId int64 `gorm:"column:question_id;type:bigint(19);primary_key;comment:主键id" json:"question_id"`
|
||||
QuestionTitle string `gorm:"column:question_title;type:varchar(200);comment:标题" json:"question_title"`
|
||||
QuestionSubtitle string `gorm:"column:question_subtitle;type:varchar(200);comment:副标题" json:"question_subtitle"`
|
||||
QuestionIden string `gorm:"column:question_iden;type:varchar(255);comment:唯一标识(用于和前端对应)" json:"question_iden"`
|
||||
QuestionStatus int `gorm:"column:question_status;type:tinyint(1);default:2;comment:问题状态(1:正常 2:待发布)" json:"question_status"`
|
||||
IsHide int `gorm:"column:is_hide;type:tinyint(1);default:0;comment:是否隐藏(0:否 1:是)" json:"is_hide"`
|
||||
IsRecommend int `gorm:"column:is_recommend;type:tinyint(1);default:0;comment:是否推荐(0:否 1:是)" json:"is_recommend"`
|
||||
ClickCount int `gorm:"column:click_count;type:int(5);default:0;comment:点击次数(点击进入详情页的人次)" json:"click_count"`
|
||||
SubmitCount int `gorm:"column:submit_count;type:int(5);default:0;comment:提交次数(提交个人信息进行了算算的人次)" json:"submit_count"`
|
||||
PayCount int `gorm:"column:pay_count;type:int(5);default:0;comment:支付次数(查看报告的人次)" json:"pay_count"`
|
||||
Price float64 `gorm:"column:price;type:decimal(10,2) unsigned;default:0.00;comment:价格(原价)" json:"price"`
|
||||
DiscountPrice *float64 `gorm:"column:discount_price;type:decimal(10,2);comment:优惠价格" json:"discount_price"`
|
||||
QuestionBrief string `gorm:"column:question_brief;type:text;comment:问题介绍" json:"question_brief"`
|
||||
QuestionExplain string `gorm:"column:question_explain;type:text;comment:问题解释/科普" json:"question_explain"`
|
||||
QuestionId int64 `gorm:"column:question_id;type:bigint(19);primary_key;comment:主键id" json:"question_id"`
|
||||
QuestionTitle string `gorm:"column:question_title;type:varchar(200);comment:标题" json:"question_title"`
|
||||
QuestionSubtitle string `gorm:"column:question_subtitle;type:varchar(200);comment:副标题" json:"question_subtitle"`
|
||||
QuestionIden string `gorm:"column:question_iden;type:varchar(255);comment:唯一标识(用于和前端对应)" json:"question_iden"`
|
||||
QuestionStatus int `gorm:"column:question_status;type:tinyint(1);default:2;comment:问题状态(1:正常 2:待发布)" json:"question_status"`
|
||||
IsHide int `gorm:"column:is_hide;type:tinyint(1);default:0;comment:是否隐藏(0:否 1:是)" json:"is_hide"`
|
||||
IsRecommend int `gorm:"column:is_recommend;type:tinyint(1);default:0;comment:是否推荐(0:否 1:是)" json:"is_recommend"`
|
||||
ClickCount int `gorm:"column:click_count;type:int(5);default:0;comment:点击次数(点击进入详情页的人次)" json:"click_count"`
|
||||
SubmitCount int `gorm:"column:submit_count;type:int(5);default:0;comment:提交次数(提交个人信息进行了算算的人次)" json:"submit_count"`
|
||||
PayCount int `gorm:"column:pay_count;type:int(5);default:0;comment:支付次数(查看报告的人次)" json:"pay_count"`
|
||||
Price float64 `gorm:"column:price;type:decimal(10,2) unsigned;default:0.00;comment:价格(原价)" json:"price"`
|
||||
DiscountPrice *float64 `gorm:"column:discount_price;type:decimal(10,2);comment:优惠价格" json:"discount_price"`
|
||||
DiscountEndTime *time.Time `gorm:"column:discount_end_time;type:datetime;comment:优惠截止时间" json:"discount_end_time"`
|
||||
QuestionBrief string `gorm:"column:question_brief;type:text;comment:问题介绍" json:"question_brief"`
|
||||
QuestionExplain string `gorm:"column:question_explain;type:text;comment:问题解释/科普" json:"question_explain"`
|
||||
Model
|
||||
}
|
||||
|
||||
|
||||
@ -8,11 +8,11 @@ import (
|
||||
|
||||
// SystemMember 配置-会员配置
|
||||
type SystemMember struct {
|
||||
SystemMemberId int64 `gorm:"column:system_member_id;type:bigint(19);primary_key;comment:主键id" json:"system_member_id"`
|
||||
MemberDays uint `gorm:"column:member_days;type:int(10) unsigned;default:0;comment:会员天数" json:"member_days"`
|
||||
Price float64 `gorm:"column:price;type:decimal(10,2);default:0.00;comment:价格(原价)" json:"price"`
|
||||
DiscountPrice float64 `gorm:"column:discount_price;type:decimal(10,2);comment:优惠价格" json:"discount_price"`
|
||||
FirstTimePrice float64 `gorm:"column:first_time_price;type:decimal(10,2) unsigned;default:0.00;comment:首次购买价格" json:"first_time_price"`
|
||||
SystemMemberId int64 `gorm:"column:system_member_id;type:bigint(19);primary_key;comment:主键id" json:"system_member_id"`
|
||||
MemberDays uint `gorm:"column:member_days;type:int(10) unsigned;default:0;comment:会员天数" json:"member_days"`
|
||||
Price float64 `gorm:"column:price;type:decimal(10,2);default:0.00;comment:价格(原价)" json:"price"`
|
||||
DiscountPrice *float64 `gorm:"column:discount_price;type:decimal(10,2);comment:优惠价格" json:"discount_price"`
|
||||
DiscountEndTime *time.Time `gorm:"column:discount_end_time;type:datetime;comment:优惠截止时间" json:"discount_end_time"`
|
||||
Model
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,8 @@ package requests
|
||||
|
||||
type OrderMemberRequest struct {
|
||||
GetOrderMemberPage // 获取会员订单列表-分页
|
||||
AddOrderMember // 创建会员订单
|
||||
GetOrderMemberPay // 获取会员订单支付数据
|
||||
}
|
||||
|
||||
// GetOrderMemberPage 获取会员订单列表-分页
|
||||
@ -18,3 +20,16 @@ type GetOrderMemberPage struct {
|
||||
EscrowTradeNo string `json:"escrow_trade_no" form:"escrow_trade_no" label:"第三方支付流水号"`
|
||||
CancelStatus *int `json:"cancel_status" form:"cancel_status" label:"取消状态"`
|
||||
}
|
||||
|
||||
// AddOrderMember 创建会员订单
|
||||
type AddOrderMember struct {
|
||||
SystemMemberId string `json:"system_member_id" form:"system_member_id" label:"会员" validate:"required"`
|
||||
UserCouponId string `json:"user_coupon_id" form:"user_coupon_id" label:"优惠卷"`
|
||||
PayChannel int `json:"pay_channel" form:"pay_channel" label:"支付渠道" validate:"required,oneof=1 2"` // 支付渠道(1:h5支付 2:app支付)
|
||||
OrderPrice float64 `json:"order_price" form:"order_price" label:"订单金额" validate:"required"` // 订单金额
|
||||
}
|
||||
|
||||
// GetOrderMemberPay 获取会员订单支付数据
|
||||
type GetOrderMemberPay struct {
|
||||
ClientType int `json:"client_type" form:"client_type" label:"客户端类型" validate:"required,oneof=1 2"` // 客户端类型(1:h5 2:app)
|
||||
}
|
||||
|
||||
@ -23,9 +23,10 @@ type GetOrderSinglePage struct {
|
||||
|
||||
// AddOrderSingle 创建单项订单
|
||||
type AddOrderSingle struct {
|
||||
QuestionId string `json:"question_id" form:"question_id" label:"问题" validate:"required"`
|
||||
UserCouponId string `json:"user_coupon_id" form:"user_coupon_id" label:"优惠卷"`
|
||||
PayChannel int `json:"pay_channel" form:"pay_channel" label:"支付渠道" validate:"required,oneof=1 2 3"` // 支付渠道(1:h5支付 2:app支付 3:会员支付)
|
||||
QuestionId string `json:"question_id" form:"question_id" label:"问题" validate:"required"`
|
||||
UserCouponId string `json:"user_coupon_id" form:"user_coupon_id" label:"优惠卷"`
|
||||
PayChannel int `json:"pay_channel" form:"pay_channel" label:"支付渠道" validate:"required,oneof=1 2 3"` // 支付渠道(1:h5支付 2:app支付 3:会员支付)
|
||||
OrderPrice float64 `json:"order_price" form:"order_price" label:"订单金额" validate:"required"` // 订单金额
|
||||
}
|
||||
|
||||
// GetOrderSinglePay 获取单项订单支付数据
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
package requests
|
||||
|
||||
type UserCouponRequest struct {
|
||||
GetUserCouponPage // 获取优惠卷列表-分页
|
||||
GetUserCouponPage // 获取优惠卷列表-分页
|
||||
GetUserUsableQuestionCoupon // 获取患者可使用优惠卷-单项
|
||||
GetUserUsableMemberCoupon // 获取患者可使用优惠卷-会员
|
||||
}
|
||||
|
||||
// GetUserCouponPage 获取优惠卷列表-分页
|
||||
@ -17,8 +19,14 @@ type GetUserCouponPage struct {
|
||||
ValidEndTime string `json:"valid_end_time" form:"valid_end_time" label:"有效结束时间"` // 同上
|
||||
}
|
||||
|
||||
// GetUserUsableCoupon 获取用户当前可用优惠卷
|
||||
type GetUserUsableCoupon struct {
|
||||
UserId int64 `json:"user_id" form:"user_id" label:"用户id"`
|
||||
UserCouponStatus *int `json:"user_coupon_status" form:"user_coupon_status" label:"状态"` // 状态(0:未使用 1:已使用 3:已过期)
|
||||
// GetUserUsableQuestionCoupon 获取患者可使用优惠卷-单项
|
||||
type GetUserUsableQuestionCoupon struct {
|
||||
QuestionId string `json:"question_id" form:"question_id" label:"问题" validate:"required"`
|
||||
AmountTotal float64 `json:"amount_total" form:"amount_total" label:"价格1" validate:"required"`
|
||||
}
|
||||
|
||||
// GetUserUsableMemberCoupon 获取患者可使用优惠卷-会员
|
||||
type GetUserUsableMemberCoupon struct {
|
||||
SystemMemberId string `json:"system_member_id" form:"system_member_id" label:"会员" validate:"required"`
|
||||
AmountTotal float64 `json:"amount_total" form:"amount_total" label:"价格1" validate:"required"`
|
||||
}
|
||||
|
||||
@ -91,6 +91,16 @@ func publicRouter(r *gin.Engine, api controller.Api) {
|
||||
|
||||
// 首页
|
||||
r.GET("/index", api.Public.GetIndex)
|
||||
|
||||
// 回调
|
||||
callbackGroup := r.Group("/callback")
|
||||
{
|
||||
// 微信支付回调
|
||||
wxpayGroup := callbackGroup.Group("/wxpay")
|
||||
{
|
||||
wxpayGroup.GET("/jsapi", api.CallBack.WxJsapiPay)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// adminRouter 公共路由-验证权限
|
||||
@ -126,6 +136,9 @@ func privateRouter(r *gin.Engine, api controller.Api) {
|
||||
|
||||
// 获取问题详情
|
||||
questionGroup.GET("/:question_id", api.Question.GetQuestion)
|
||||
|
||||
// 获取问题购买状态
|
||||
questionGroup.GET("/buy/status/:question_id", api.Question.GetQuestionBuyStatus)
|
||||
}
|
||||
|
||||
// 用户
|
||||
@ -144,8 +157,11 @@ func privateRouter(r *gin.Engine, api controller.Api) {
|
||||
// 获取还未弹窗的优惠卷
|
||||
couponGroup.GET("/unnotified", api.UserCoupon.GetUserCouponUnnotified)
|
||||
|
||||
// 获取用户当前可用优惠卷
|
||||
couponGroup.GET("/usable", api.UserCoupon.GetUserUsableCoupon)
|
||||
// 获取患者可使用优惠卷-单项
|
||||
couponGroup.GET("/question", api.UserCoupon.GetUserUsableQuestionCoupon)
|
||||
|
||||
// 获取患者可使用优惠卷-会员
|
||||
couponGroup.GET("/member", api.UserCoupon.GetUserUsableMemberCoupon)
|
||||
}
|
||||
|
||||
// 收藏
|
||||
@ -182,7 +198,7 @@ func privateRouter(r *gin.Engine, api controller.Api) {
|
||||
// 获取单项订单支付数据
|
||||
singleGroup.GET("/pay/:order_id", api.OrderSingle.GetOrderSinglePay)
|
||||
|
||||
// 删除单项订单支付数据
|
||||
// 删除单项订单
|
||||
singleGroup.DELETE("/:order_id", api.OrderSingle.DeleteOrderSingle)
|
||||
}
|
||||
|
||||
@ -191,6 +207,12 @@ func privateRouter(r *gin.Engine, api controller.Api) {
|
||||
{
|
||||
// 获取会员订单列表-分页
|
||||
memberGroup.GET("/page", api.OrderMember.GetOrderMemberPage)
|
||||
|
||||
// 创建会员订单
|
||||
memberGroup.POST("", api.OrderMember.AddOrderMember)
|
||||
|
||||
// 获取会员订单支付数据
|
||||
memberGroup.GET("/pay/:order_id", api.OrderMember.GetOrderMemberPay)
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,4 +222,5 @@ func privateRouter(r *gin.Engine, api controller.Api) {
|
||||
// 获取会员配置数据
|
||||
memberGroup.GET("", api.SystemMember.GetSystemMember)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
350
api/service/OrderMember.go
Normal file
350
api/service/OrderMember.go
Normal file
@ -0,0 +1,350 @@
|
||||
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-api/api/dao"
|
||||
"hepa-calc-api/api/model"
|
||||
"hepa-calc-api/config"
|
||||
"hepa-calc-api/extend/weChat"
|
||||
"hepa-calc-api/global"
|
||||
"hepa-calc-api/utils"
|
||||
"time"
|
||||
)
|
||||
|
||||
type OrderMemberService struct {
|
||||
}
|
||||
|
||||
// AddOrderMember 创建会员订单
|
||||
func (r *OrderMemberService) AddOrderMember(tx *gorm.DB, UserId, SystemMemberId int64, UserCouponId *int64, payChannel int, orderPrice float64) (orderMember *model.OrderMember, err error) {
|
||||
// 检测多次请求
|
||||
redisKey := "AddOrderMember" + fmt.Sprintf("%d", UserId) + fmt.Sprintf("%d", SystemMemberId)
|
||||
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("生成订单失败")
|
||||
}
|
||||
|
||||
// 获取会员配置数据
|
||||
systemMemberDao := dao.SystemMemberDao{}
|
||||
systemMember, err := systemMemberDao.GetSystemMemberById(SystemMemberId)
|
||||
if err != nil {
|
||||
return nil, errors.New("会员配置异常")
|
||||
}
|
||||
|
||||
// 获取用户数据
|
||||
userDao := dao.UserDao{}
|
||||
user, err := userDao.GetUserById(UserId)
|
||||
if err != nil || user == nil {
|
||||
return nil, errors.New("用户错误")
|
||||
}
|
||||
|
||||
// 检测会员有效期
|
||||
if user.IsMember == 1 {
|
||||
now := time.Now()
|
||||
|
||||
diff := user.MemberExpireDate.Sub(now)
|
||||
// 将差值转换为天数
|
||||
diffDays := int(diff.Hours() / 24)
|
||||
totalDays := diffDays + int(systemMember.MemberDays)
|
||||
if totalDays > 180 {
|
||||
return nil, errors.New("超出会员有效期")
|
||||
}
|
||||
}
|
||||
|
||||
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 // 第三方支付流水号
|
||||
|
||||
// 获取会员购买价格
|
||||
systemMemberService := &SystemMemberService{}
|
||||
amountTotal = systemMemberService.GetSystemMemberBuyPrice(systemMember)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 检测用户优惠卷
|
||||
var userCoupon *model.UserCoupon
|
||||
if UserCouponId != nil {
|
||||
// 检测用户是否购买过会员
|
||||
userService := &UserService{}
|
||||
isBuy := userService.CheckUserBuyOrderMember(UserId)
|
||||
if isBuy == true {
|
||||
// 已购买过会员,无法使用优惠卷
|
||||
return nil, errors.New("优惠券异常")
|
||||
}
|
||||
|
||||
// 获取优惠卷数据
|
||||
UserCouponDao := dao.UserCouponDao{}
|
||||
userCoupon, err = UserCouponDao.GetUserCouponPreloadById(*UserCouponId)
|
||||
if err != nil {
|
||||
return nil, errors.New("优惠券异常")
|
||||
}
|
||||
|
||||
userCouponService := &UserCouponService{}
|
||||
isCanUse, err := userCouponService.CheckUserCoupon(userCoupon, SystemMemberId, 2, amountTotal)
|
||||
if err != nil || isCanUse == false {
|
||||
return nil, errors.New("价格异常")
|
||||
}
|
||||
|
||||
// 优惠卷总金额
|
||||
couponAmountTotal = userCoupon.Coupon.CouponPrice
|
||||
}
|
||||
|
||||
// 实际付款金额
|
||||
paymentAmountTotal = amountTotal - couponAmountTotal // 实际付款金额
|
||||
if paymentAmountTotal < 0 {
|
||||
return nil, errors.New("价格异常")
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
// 创建订单
|
||||
orderMember = &model.OrderMember{
|
||||
UserId: UserId,
|
||||
SystemMemberId: SystemMemberId,
|
||||
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: "",
|
||||
}
|
||||
|
||||
orderMemberDao := dao.OrderMemberDao{}
|
||||
orderMember, err = orderMemberDao.AddOrderMember(tx, orderMember)
|
||||
if err != nil {
|
||||
return nil, errors.New("订单创建失败")
|
||||
}
|
||||
|
||||
// 创建优惠卷表
|
||||
if userCoupon != nil {
|
||||
orderMemberCoupon := &model.OrderMemberCoupon{
|
||||
OrderId: orderMember.OrderId,
|
||||
UserCouponId: *UserCouponId,
|
||||
CouponName: userCoupon.Coupon.CouponName,
|
||||
CouponUsePrice: userCoupon.Coupon.CouponPrice,
|
||||
}
|
||||
|
||||
orderMemberCouponDao := dao.OrderMemberCouponDao{}
|
||||
orderMemberCoupon, err = orderMemberCouponDao.AddOrderMemberCoupon(tx, orderMemberCoupon)
|
||||
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("订单创建失败")
|
||||
}
|
||||
}
|
||||
|
||||
return orderMember, nil
|
||||
}
|
||||
|
||||
// PutCancelOrderMember 取消会员订单
|
||||
// cancelReason:订单取消原因(1:主动取消 2:后台取消 3:支付超时取消)
|
||||
func (r *OrderMemberService) PutCancelOrderMember(tx *gorm.DB, userId, orderId int64, cancelReason int) (bool, error) {
|
||||
// 检测多次请求
|
||||
redisKey := "PutCancelOrderSingle" + 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["user_id"] = userId
|
||||
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 *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.Pay1659662936.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.Pay1659662936.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
|
||||
}
|
||||
@ -20,7 +20,7 @@ type OrderSingleService struct {
|
||||
}
|
||||
|
||||
// AddOrderSingle 创建单项订单
|
||||
func (r *OrderSingleService) AddOrderSingle(tx *gorm.DB, UserId, QuestionId int64, UserCouponId *int64, payChannel int) (orderSingle *model.OrderSingle, err error) {
|
||||
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()
|
||||
@ -52,16 +52,24 @@ func (r *OrderSingleService) AddOrderSingle(tx *gorm.DB, UserId, QuestionId int6
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var amountTotal float64 // 总金额
|
||||
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 {
|
||||
@ -73,7 +81,7 @@ func (r *OrderSingleService) AddOrderSingle(tx *gorm.DB, UserId, QuestionId int6
|
||||
}
|
||||
|
||||
userCouponService := &UserCouponService{}
|
||||
isCanUse, err := userCouponService.CheckUserCoupon(userCoupon, QuestionId, 1, amountTotal)
|
||||
isCanUse, err := userCouponService.CheckUserCoupon(userCoupon, QuestionId, 1, *amountTotal)
|
||||
if err != nil || isCanUse == false {
|
||||
return nil, errors.New("价格异常")
|
||||
}
|
||||
@ -82,15 +90,26 @@ func (r *OrderSingleService) AddOrderSingle(tx *gorm.DB, UserId, QuestionId int6
|
||||
couponAmountTotal = userCoupon.Coupon.CouponPrice
|
||||
}
|
||||
|
||||
// 实际付款金额
|
||||
paymentAmountTotal = amountTotal - couponAmountTotal
|
||||
if paymentAmountTotal < 0 {
|
||||
return nil, errors.New("价格异常")
|
||||
}
|
||||
|
||||
// 会员支付
|
||||
if payChannel == 3 {
|
||||
paymentAmountTotal = 0
|
||||
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 // 支付时间
|
||||
}
|
||||
|
||||
// 生成订单号
|
||||
@ -100,15 +119,15 @@ func (r *OrderSingleService) AddOrderSingle(tx *gorm.DB, UserId, QuestionId int6
|
||||
orderSingle = &model.OrderSingle{
|
||||
UserId: UserId,
|
||||
QuestionId: QuestionId,
|
||||
OrderStatus: 1,
|
||||
OrderStatus: orderStatus,
|
||||
IsDelete: 0,
|
||||
PayChannel: payChannel,
|
||||
PayStatus: 1,
|
||||
PayTime: nil,
|
||||
PayStatus: payStatus,
|
||||
PayTime: payTime,
|
||||
RefundStatus: 0,
|
||||
OrderNo: orderNo,
|
||||
EscrowTradeNo: "",
|
||||
AmountTotal: amountTotal,
|
||||
EscrowTradeNo: escrowTradeNo,
|
||||
AmountTotal: *amountTotal,
|
||||
CouponAmountTotal: couponAmountTotal,
|
||||
PaymentAmountTotal: paymentAmountTotal,
|
||||
CancelStatus: 0,
|
||||
@ -152,6 +171,9 @@ func (r *OrderSingleService) AddOrderSingle(tx *gorm.DB, UserId, QuestionId int6
|
||||
}
|
||||
|
||||
// 增加至未支付取消订单延迟队列
|
||||
if payChannel == 1 || payChannel == 2 {
|
||||
|
||||
}
|
||||
|
||||
return orderSingle, nil
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"hepa-calc-api/api/dao"
|
||||
"hepa-calc-api/api/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
type QuestionService struct {
|
||||
@ -126,14 +127,14 @@ func (r *QuestionService) GetUserFirstTimeBuyPrice(userId, questionId int64) (f
|
||||
// GetQuestionBuyCount 获取问题被购买数量
|
||||
func (r *QuestionService) GetQuestionBuyCount(userId, questionId int64) (c int, err error) {
|
||||
// 未购买过
|
||||
systemSingleDao := dao.SystemSingleDao{}
|
||||
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 := systemSingleDao.GetSystemSingleCount(maps)
|
||||
buyCount, err := orderSingleDao.GetOrderSingleCount(maps)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -141,20 +142,13 @@ func (r *QuestionService) GetQuestionBuyCount(userId, questionId int64) (c int,
|
||||
return int(buyCount), nil
|
||||
}
|
||||
|
||||
// GetUserBuyPrice 获取问题价格
|
||||
func (r *QuestionService) GetUserBuyPrice(userId, questionId int64) (p float64, err error) {
|
||||
// GetUserBuyPrice 获取问题最终价格
|
||||
func (r *QuestionService) GetUserBuyPrice(userId, questionId int64) (p *float64, err error) {
|
||||
// 获取问题详情
|
||||
questionDao := dao.QuestionDao{}
|
||||
question, err := questionDao.GetQuestionById(questionId)
|
||||
if err != nil {
|
||||
return 0, errors.New("题目异常")
|
||||
}
|
||||
|
||||
// 问题价格
|
||||
p = question.Price
|
||||
|
||||
if question.DiscountPrice != nil {
|
||||
p = *question.DiscountPrice
|
||||
return nil, errors.New("题目异常")
|
||||
}
|
||||
|
||||
// 检测用户是否购买过该问题
|
||||
@ -166,10 +160,19 @@ func (r *QuestionService) GetUserBuyPrice(userId, questionId int64) (p float64,
|
||||
maps := make(map[string]interface{})
|
||||
systemSingle, err := systemSingleDao.GetSystemSingle(maps)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p = systemSingle.FirstTimePrice
|
||||
p = &systemSingle.FirstTimePrice
|
||||
}
|
||||
|
||||
// 处理问题优惠价格
|
||||
if p == nil {
|
||||
p = r.HandleQuestionDiscountPrice(question.DiscountPrice, question.DiscountEndTime)
|
||||
}
|
||||
|
||||
if p == nil {
|
||||
p = &question.Price
|
||||
}
|
||||
|
||||
return p, nil
|
||||
@ -187,3 +190,19 @@ func (r *QuestionService) CheckQuestion(m *model.Question) (bool, error) {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
17
api/service/SystemMember.go
Normal file
17
api/service/SystemMember.go
Normal file
@ -0,0 +1,17 @@
|
||||
package service
|
||||
|
||||
import "hepa-calc-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
|
||||
}
|
||||
@ -3,6 +3,8 @@ package service
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"hepa-calc-api/api/dao"
|
||||
"hepa-calc-api/api/model"
|
||||
"hepa-calc-api/extend/aliyun"
|
||||
"io"
|
||||
"math/rand"
|
||||
@ -55,3 +57,28 @@ func (r *UserService) HandleUserAvatar(wxAvatar string) (avatar string, err erro
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -10,8 +10,8 @@ import (
|
||||
type UserCollectionService struct {
|
||||
}
|
||||
|
||||
// CheckUserCollectionQuestion 检测问题是否被用户收藏
|
||||
func (r *UserCollectionService) CheckUserCollectionQuestion(userId, questionId int64) bool {
|
||||
// GetUserCollectionQuestionStatus 检测用户收藏状态
|
||||
func (r *UserCollectionService) GetUserCollectionQuestionStatus(userId, questionId int64) bool {
|
||||
userCollectionDao := dao.UserCollectionDao{}
|
||||
|
||||
maps := make(map[string]interface{})
|
||||
@ -27,8 +27,8 @@ func (r *UserCollectionService) CheckUserCollectionQuestion(userId, questionId i
|
||||
|
||||
// PutUserCollection 收藏题目
|
||||
func (r *UserCollectionService) PutUserCollection(userId, questionId int64) (bool, error) {
|
||||
// 检测问题是否被用户收藏
|
||||
IsCollection := r.CheckUserCollectionQuestion(userId, questionId)
|
||||
// 检测用户收藏状态
|
||||
IsCollection := r.GetUserCollectionQuestionStatus(userId, questionId)
|
||||
if IsCollection == true {
|
||||
// 已收藏
|
||||
return true, nil
|
||||
@ -60,8 +60,8 @@ func (r *UserCollectionService) PutUserCollection(userId, questionId int64) (boo
|
||||
|
||||
// PutUserCollectionCancel 取消收藏题目
|
||||
func (r *UserCollectionService) PutUserCollectionCancel(userId, questionId int64) (bool, error) {
|
||||
// 检测问题是否被用户收藏
|
||||
IsCollection := r.CheckUserCollectionQuestion(userId, questionId)
|
||||
// 检测用户收藏状态
|
||||
IsCollection := r.GetUserCollectionQuestionStatus(userId, questionId)
|
||||
if IsCollection == false {
|
||||
// 已收藏
|
||||
return true, nil
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"gorm.io/gorm"
|
||||
"hepa-calc-api/api/dao"
|
||||
"hepa-calc-api/api/dto"
|
||||
"hepa-calc-api/api/model"
|
||||
"time"
|
||||
)
|
||||
@ -12,6 +13,7 @@ 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("优惠卷异常")
|
||||
@ -114,3 +116,93 @@ func (r *UserCouponService) ReturnUserCoupon(tx *gorm.DB, userCouponId int64) bo
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ dysms:
|
||||
dysms-access-key: LTAI4GGygjsKhyBwvvC3CghV
|
||||
dysms-access-secret: rcx7lO9kQxG10m8NqNPEfEtT9IS8EI
|
||||
|
||||
# [微信]v
|
||||
# [微信]
|
||||
wechat:
|
||||
app-id: wxc8ac5051745bc795
|
||||
app-secret: 678b63a8a7541e528abc3040c3cea809
|
||||
|
||||
@ -7,25 +7,24 @@ import (
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core/option"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/utils"
|
||||
"hepa-calc-api/config"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var (
|
||||
mchId = config.C.Wechat.Pay1659662936.MchId // 商户号
|
||||
mchCertificateSerialNumber = config.C.Wechat.Pay1659662936.MchCertificateSerialNumber // 商户证书序列号
|
||||
v3ApiSecret = config.C.Wechat.Pay1659662936.V3ApiSecret // 商户APIv3密钥
|
||||
privateKeyPath = "extend/weChat/certs/" + mchId + "/apiclient_key.pem" // 商户私钥文件地址
|
||||
)
|
||||
|
||||
// 创建客户端
|
||||
func createClient() (*core.Client, error) {
|
||||
mchId := config.C.Wechat.Pay1659662936.MchId // 商户号
|
||||
mchCertificateSerialNumber := config.C.Wechat.Pay1659662936.MchCertificateSerialNumber // 商户证书序列号
|
||||
v3ApiSecret := config.C.Wechat.Pay1659662936.V3ApiSecret // 商户APIv3密钥
|
||||
|
||||
if mchId == "" {
|
||||
return nil, errors.New("商户号错误")
|
||||
}
|
||||
|
||||
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
|
||||
certsDir := filepath.Join("extend/weChat/certs", mchId, "/apiclient_key.pem")
|
||||
// certsDir := filepath.Join("extend/weChat/certs", "/1636644248/apiclient_key.pem")
|
||||
mchPrivateKey, err := utils.LoadPrivateKeyWithPath(certsDir)
|
||||
mchPrivateKey, err := utils.LoadPrivateKeyWithPath(privateKeyPath)
|
||||
if err != nil {
|
||||
return nil, errors.New("微信签名生成失败")
|
||||
return nil, errors.New("微信支付生成失败")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
43
extend/weChat/parseNotify.go
Normal file
43
extend/weChat/parseNotify.go
Normal file
@ -0,0 +1,43 @@
|
||||
package weChat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core/downloader"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core/notify"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/utils"
|
||||
)
|
||||
|
||||
// ParseNotify 回调通知的验签与解密
|
||||
func ParseNotify(c *gin.Context) (notifyReq *notify.Request, err error) {
|
||||
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
|
||||
mchPrivateKey, err := utils.LoadPrivateKeyWithPath(privateKeyPath)
|
||||
if err != nil {
|
||||
return nil, errors.New("微信支付生成失败")
|
||||
}
|
||||
|
||||
// 1. 使用 `RegisterDownloaderWithPrivateKey` 注册下载器
|
||||
err = downloader.MgrInstance().RegisterDownloaderWithPrivateKey(c, mchPrivateKey, mchCertificateSerialNumber, mchId, v3ApiSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 2. 获取商户号对应的微信支付平台证书访问器
|
||||
certificateVisitor := downloader.MgrInstance().GetCertificateVisitor(mchId)
|
||||
// 3. 使用证书访问器初始化 `notify.Handler`
|
||||
handler, err := notify.NewRSANotifyHandler(v3ApiSecret, verifiers.NewSHA256WithRSAVerifier(certificateVisitor))
|
||||
|
||||
transaction := new(payments.Transaction)
|
||||
notifyReq, err = handler.ParseNotifyRequest(context.Background(), c.Request, transaction)
|
||||
// 如果验签未通过,或者解密失败
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Println(transaction)
|
||||
return notifyReq, nil
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user