package order
import (
"encoding/json"
logger "eta/eta_mini_ht_api/common/component/log"
"eta/eta_mini_ht_api/models"
"eta/eta_mini_ht_api/models/message"
"eta/eta_mini_ht_api/models/order"
"fmt"
"math/rand"
"strconv"
"time"
)
const (
RMB = "CNY"
AliPayWay PaymentWay = "alipay"
WechatPay PaymentWay = "wechat"
RefundSuccess = "success"
RefundFail = "fail"
PaySuccess = "success"
PayFail = "fail"
SuccessIcon = ``
FailIcon = ``
)
type PaymentWay string
type TradeOrderDTO struct {
ID int `gorm:"column:id;primaryKey"`
TransactionID string `gorm:"column:transaction_id;type:varchar(255);comment:第三方平台ID"`
ProductOrderID string `gorm:"column:product_order_id;type:varchar(255);comment:商品订单号"`
PaymentAccount string `gorm:"column:payment_account;type:varchar(255);comment:支付账号"`
PaymentWay string `gorm:"column:payment_way;type:enum('wechat');comment:支付渠道"`
Amount string `gorm:"column:amount;type:varchar(20);comment:支付金额"`
Currency string `gorm:"column:currency;type:varchar(255);comment:货币"`
MerchantID string `gorm:"column:merchant_id;type:int(11);comment:商户id"`
UserID int `gorm:"column:user_id;type:int(11);comment:用户id"`
TemplateUserID int `gorm:"column:template_user_id;type:int(11);comment:临时用户id"`
PaymentType string `gorm:"column:payment_type;type:enum('pay','refund');comment:订单类型"`
PaymentStatus string `gorm:"column:payment_status;type:enum('pending','processing','done','failed');comment:支付状态"`
DealTime time.Time `gorm:"column:deal_time;type:datetime;comment:完成时间"`
}
func GenerateTradeOrderNo() string {
timestamp := time.Now().UnixNano() / 1000000 // 毫秒级时间戳
// 生成随机数
rand.New(rand.NewSource(time.Now().UnixNano()))
randomPart := rand.Intn(999999)
// 格式化订单号
orderNumber := fmt.Sprintf("T%d%06d", timestamp, randomPart)
return orderNumber
}
func CreateTradeOrder(userId, templateUserId int, productOrderNo, tradeOrderNo, merchantNo string) (err error) {
db := models.Main()
productOrder, err := order.GetOrderByUser(templateUserId, productOrderNo)
if err != nil {
logger.Error("获取商品订单信息失败%v", err)
return
}
tx := db.Begin()
defer func() {
if err != nil {
tx.Rollback()
return
}
tx.Commit()
}()
tradeOrder := order.TradeOrder{
ProductOrderID: productOrderNo,
ProductName: productOrder.ProductName,
TransactionID: tradeOrderNo,
Amount: productOrder.TotalAmount,
Mobile: productOrder.Mobile,
AreaCode: productOrder.AreaCode,
RealName: productOrder.RealName,
PaymentWay: order.WechatPayWay,
Currency: RMB,
MerchantID: merchantNo,
UserID: userId,
TemplateUserID: templateUserId,
PaymentType: order.PaymentTypePay,
}
err = tx.Create(&tradeOrder).Error
if err != nil {
logger.Error("创建支付订单失败%v", err)
return
}
err = tx.Model(&order.ProductOrder{}).Where("id = ?", productOrder.ID).Updates(map[string]interface{}{
"trade_id": tradeOrder.ID,
"trade_no": tradeOrder.TransactionID,
"payment_time": time.Now(),
"payment_amount": tradeOrder.Amount,
"payment_way": tradeOrder.PaymentWay,
}).Error
return
}
func convertToDTO(tradeOrder order.TradeOrder) TradeOrderDTO {
return TradeOrderDTO{
ID: tradeOrder.ID,
TransactionID: tradeOrder.TransactionID,
ProductOrderID: tradeOrder.ProductOrderID,
PaymentAccount: tradeOrder.PaymentAccount,
PaymentWay: string(tradeOrder.PaymentWay),
Amount: tradeOrder.Amount,
Currency: tradeOrder.Currency,
MerchantID: tradeOrder.MerchantID,
UserID: tradeOrder.UserID,
TemplateUserID: tradeOrder.UserID,
PaymentType: string(tradeOrder.PaymentType),
PaymentStatus: string(tradeOrder.PaymentStatus),
DealTime: tradeOrder.DealTime,
}
}
func GetUnFailedTradeFlowByProductOrder(productOrderNo string) (dtoList []TradeOrderDTO, err error) {
var tradeOrderList []order.TradeOrder
tradeOrderList, err = order.GetUnFailedTradeFlowByProductOrder(productOrderNo)
for _, tradeOrder := range tradeOrderList {
dtoList = append(dtoList, convertToDTO(tradeOrder))
}
return
}
func GetTradeOrderByNo(tradeOrderNo string) (dto TradeOrderDTO, err error) {
var tradeOrder order.TradeOrder
tradeOrder, err = order.GetTradeOrderByNo(tradeOrderNo, order.PaymentTypePay)
dto = convertToDTO(tradeOrder)
return
}
type RefundDealFlowDTO struct {
OperatorUserID int `gorm:"column:operator_user_id"`
ProductOrderNo string `gorm:"column:product_order_no"`
RefundOrderNo string `gorm:"column:refund_order_no"`
}
func convertRefundDTO(flow order.RefundDealFlow) RefundDealFlowDTO {
return RefundDealFlowDTO{
OperatorUserID: flow.OperatorUserID,
ProductOrderNo: flow.ProductOrderNo,
RefundOrderNo: flow.RefundOrderNo,
}
}
func createRefundMetaInfo(sysUserId int, productOrderNo string, flag string) (err error) {
productOrder, err := order.GetOrderByOrderNo(productOrderNo)
if err != nil {
logger.Error("生成退款消息通知失败,获取订单信息失败:v,订单编号:%s", err, productOrderNo)
return
}
var result string
var icon string
switch flag {
case RefundSuccess:
result = "成功"
icon = SuccessIcon
case RefundFail:
result = "失败"
icon = FailIcon
default:
logger.Error("生成退款消息通知失败,未知的退款状态%s,订单编号:%s", flag, productOrderNo)
return
}
refundInfo := message.RefundMetaData{
Icon: icon,
RealName: productOrder.RealName,
ProductOrderNo: productOrderNo,
Result: result,
}
bytes, err := json.Marshal(refundInfo)
if err != nil {
logger.Error("生成退款消息通知失败,序列化退款信息失败:%v,订单编号:%s", err, productOrderNo)
return
}
metaInfo := message.MetaInfo{
Meta: string(bytes),
MetaType: message.SysUserNoticeType,
SourceType: message.RefundSourceType,
Status: message.InitStatusType,
From: "HTTradePlate",
To: strconv.Itoa(sysUserId),
}
return message.CreateMetaInfo(metaInfo)
}
func DealRefund(refundOrderNo string, flag string) (dto RefundDealFlowDTO, err error) {
flow, err := order.GetRefundFlow(refundOrderNo)
if err != nil {
logger.Error("获取退款流水失败%v,退款订单:%s", err, refundOrderNo)
return
}
dto = convertRefundDTO(flow)
//处理退款订单
TradeOrder, err := order.GetTradeOrderByNo(flow.RefundOrderNo, order.PaymentTypeRefund)
if err != nil {
logger.Error("获取退款订单失败%v,退款订单:%s", err, refundOrderNo)
return
}
isSuccess := false
if flag == RefundSuccess {
isSuccess = true
}
err = order.DealRefundOrder(TradeOrder, isSuccess)
if err != nil {
logger.Error("处理退款结果失败%v,退款订单:%s", err, refundOrderNo)
return
}
_ = createRefundMetaInfo(flow.OperatorUserID, flow.ProductOrderNo, flag)
return
}
func DealPayment(tradeOrderNo string, flag string) (productOrderNo string, err error) {
//处理退款订单
tradeOrder, err := order.GetTradeOrderByNo(tradeOrderNo, order.PaymentTypePay)
if err != nil {
logger.Error("获取支付订单失败%v,支付订单:%s", err, tradeOrderNo)
return
}
isSuccess := false
if flag == PaySuccess {
isSuccess = true
}
err = order.DealPaymentOrder(tradeOrder, isSuccess)
if err != nil {
logger.Error("处理支付结果失败%v,支付订单:%s", err, tradeOrderNo)
return
}
productOrderNo = tradeOrder.ProductOrderID
return
}