You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2246 lines
72 KiB

package service
import (
"context"
"encoding/json"
"errors"
"fmt"
"math"
"os"
"shop-api/initialize/api"
"shop-api/model/response"
"strconv"
"strings"
"sync/atomic"
"time"
"shop-api/dto"
"shop-api/global"
"shop-api/model"
"shop-api/model/request"
"shop-api/utils"
"github.com/plutov/paypal"
"github.com/spf13/cast"
"github.com/w3liu/go-common/constant/timeformat"
"gorm.io/gorm"
)
func GetUserOrderData(userId string) (response.OrderData, error) {
var (
err error
result response.OrderData
)
result.All, _ = getOrderCount(userId, &request.SearchOrderList{Status: 0})
result.Unpaid, _ = getOrderCount(userId, &request.SearchOrderList{Status: 1})
result.Unship, _ = getOrderCount(userId, &request.SearchOrderList{Status: 2})
result.Shipped, _ = getOrderCount(userId, &request.SearchOrderList{Status: 3})
result.Finished, _ = getOrderCount(userId, &request.SearchOrderList{Status: 4})
result.Cancel, _ = getOrderCount(userId, &request.SearchOrderList{Status: 5})
result.PostSale, _ = getOrderCount(userId, &request.SearchOrderList{Status: 10})
return result, err
}
func getOrderCount(userId string, info *request.SearchOrderList) (int64, error) {
var (
err error
result int64
)
db := global.MG_DB.Model(&model.Order{}).Where("`order`.user_id = ?", userId)
if info.Status == 10 { //退货
db = db.Joins("LEFT JOIN `order_post_sale` ON `order_post_sale`.order_id = `order`.order_id").Where("`order_post_sale`.id IS NOT NULL AND `order_post_sale`.`status` != 4")
} else {
if info.Status != 0 {
db = db.Where("`order`.`status` = ?", info.Status)
}
}
if info.Code != "" {
db = db.Where("`order`.`code` = ?", info.Code)
}
err = db.Count(&result).Error
return result, err
}
func GetUserOrderList(userID string, info *request.SearchOrderList) (error, interface{}, int64) {
var (
err error
data []model.OrderList
total int64
orderIds []string
)
limit := info.PageSize
offset := info.PageSize * (info.Page - 1)
db := global.MG_DB.Model(&model.Order{}).Where("`order`.user_id = ?", userID)
if info.Status == 10 { //退货
db = db.Joins("LEFT JOIN `order_post_sale` ON `order_post_sale`.order_id = `order`.order_id").Where("`order_post_sale`.id IS NOT NULL AND `order_post_sale`.`status` != 4")
} else {
if info.Status != 0 {
db = db.Where("`order`.`status` = ?", info.Status)
}
}
if info.Code != "" {
db = db.Where("`order`.`code` = ?", info.Code)
}
err = db.Select("`order`.*").Order("`order`.id DESC").Offset(offset).Limit(limit).Find(&data).Error
if err != nil {
return errors.New("获取订单失败"), data, total
}
if len(data) == 0 {
return nil, data, total
}
for i := 0; i < len(data); i++ {
orderIds = append(orderIds, data[i].OrderID)
now := time.Now()
if data[i].Status == 1 { // 待付款 计算付款倒计时
tmp := data[i].CreatedAt.Add(time.Duration(global.MG_CONFIG.Paypal.OrderBack) * time.Hour)
if tmp.Unix() >= now.Unix() {
data[i].NextCountdown = tmp.Unix() - now.Unix()
}
} else if data[i].Status == 3 && data[i].ExpressStatus == 1 {
tmp := data[i].ExpressTime.AddDate(0, 0, 15)
if tmp.Unix() >= now.Unix() {
data[i].NextCountdown = tmp.Unix() - now.Unix()
}
}
}
var (
orderGoodsList []model.OrderGoodsDetail
goodsMap = make(map[string]model.OrderGoodsDetail)
)
err = global.MG_DB.Model(&model.OrderGoods{}).Where("order_id IN (?)", orderIds).Find(&orderGoodsList).Error
if err != nil {
return errors.New("获取订单商品信息失败"), data, total
}
for _, goods := range orderGoodsList {
goodsMap[goods.OrderID] = goods
}
var (
postSales []model.PostSale
postSaleMap = make(map[string]model.PostSale)
)
_ = global.MG_DB.Model(&model.OrderPostSale{}).Select("id,order_id,status,refund_status").Where("order_id IN (?) AND status IN (1,2,3)", orderIds).Find(&postSales).Error
for _, sale := range postSales {
postSaleMap[sale.OrderID] = sale
}
for v := range data {
if val, ok := goodsMap[data[v].OrderID]; ok {
data[v].Goods = val
}
// todo 判断订单状态??
if val, ok := postSaleMap[data[v].OrderID]; ok {
data[v].PostSale = val
}
}
return nil, data, total
}
func GetUserOrderDetail(userID string, info *request.SearchOrderDetail) (error, interface{}) {
var (
err error
data model.OrderDetail
tCommod model.TbGoods
)
db := global.MG_DB.Model(&model.Order{})
if info.OrderID != "" {
db = db.Where("order_id = ?", info.OrderID)
}
err = db.Where("user_id = ?", userID).Find(&data).Error
if err != nil {
return errors.New("获取订单失败"), data
}
{
now := time.Now()
if data.Status == 1 { // 待付款 计算付款倒计时
tmp := data.CreatedAt.Add(time.Duration(global.MG_CONFIG.Paypal.OrderBack) * time.Hour)
if tmp.Unix() >= now.Unix() {
data.NextCountdown = tmp.Unix() - now.Unix()
}
} else if data.Status == 3 && data.ExpressStatus == 1 {
tmp := data.ExpressTime.AddDate(0, 0, 15)
if tmp.Unix() >= now.Unix() {
data.NextCountdown = tmp.Unix() - now.Unix()
}
}
}
err = global.MG_DB.Model(&model.OrderAddress{}).Where("order_id=?", info.OrderID).Find(&data.Address).Error
if err != nil {
return errors.New("获取订单地址失败"), data
}
err = global.MG_DB.Model(&model.OrderGoods{}).Where("order_id=?", info.OrderID).Find(&data.Goods).Error
if err != nil {
return errors.New("获取订单商品信息失败"), data
}
err = global.MG_DB.Model(&model.OrderDeliver{}).Where("order_id=?", info.OrderID).Find(&data.Deliver).Error
if err != nil {
return errors.New("获取发货信息失败"), data
}
global.MG_DB.Model(&model.TbGoods{}).Where("id=?", data.CommodID).Find(&tCommod)
global.MG_DB.Model(&model.SellerStore{}).Select("store_no,`type`,email").Where("store_no = ?", tCommod.StoreNo).Find(&data.Store)
_ = global.MG_DB.Model(&model.OrderPostSale{}).Select("id,order_id,status,remark,examine_time,refund_time,refund_status,created_at").Where("order_id = ? AND status IN (1,2,3)", data.OrderID).Order("id DESC").First(&data.PostSale).Error
if data.PayTime != nil {
data.Bill, _ = getBillView(data.OrderID)
}
data.Chain = model.Chain{Address: "b714e5508531a7b50d0696abdc83d2333bd896db24f68eb1470bb9529390ef3e"}
return nil, data
}
func AddUserOrder(userId string, req *request.CreateOrderParams) (error, interface{}) {
var (
err error
//user model.User
result bool
goods model.TbGoods
gSpecs model.TbGoodsSpecs
address model.Address
//mission model.MissionClaim
mission model.Mission
)
//// todo 判断用户状态
//user, err = getUser(userId)
//if err != nil {
// return errors.New("get user info error"), nil
//}
//if user.IDForbidden {
// return errors.New("user disabled"), nil
//}
// 开始交易
for {
err, result = utils.RedisSetNX("commod-"+cast.ToString(req.SkuID), "used", 10*time.Second)
if result && err == nil {
// 获取成功
break
}
}
defer func() {
// 释放锁
_, _ = utils.RedisDel("commod-" + cast.ToString(req.SkuID))
}()
// 校验code
if req.Code != "" {
tx := global.MG_DB.Begin()
err = tx.Model(&model.MissionClaim{}).Joins("INNER JOIN mission ON mission.id = mission_claim.mission_id").Where("mission_claim.claim_no = ?", req.Code).Select("mission.*").Find(&mission).Error
if err != nil || mission.ID == 0 {
return errors.New("任务码错误,请确认链接是否正确"), nil
}
}
err = global.MG_DB.Model(&model.TbGoodsSpecs{}).Where("id = ?", req.SkuID).Find(&gSpecs).Error
if err != nil {
return errors.New("获取规格信息失败"), nil
}
if gSpecs.Stock < int64(req.Number) {
return errors.New("商品库存不足"), nil
}
err = global.MG_DB.Model(&model.TbGoods{}).Where("id = ?", gSpecs.GoodsId).Find(&goods).Error
if err != nil {
return errors.New("获取商品信息失败"), nil
}
if goods.Online == "off" || goods.ID == 0 {
return errors.New("商品已下架,不可购买"), nil
}
// 校验任务码和商品关联
if mission.GoodsId != goods.ID { // 若任务领取码和下单商品不一致则将code置空
req.Code = ""
}
err = global.MG_DB.Model(&model.Address{}).Where("user_id = ? AND id = ?", userId, req.AddressID).Find(&address).Error
if err != nil {
return errors.New("获取地址信息失败"), nil
}
if address.ID == 0 {
return errors.New("请选择正确的收货地址"), nil
}
tx := global.MG_DB.Begin()
// 生成订单
var order model.Order
order.OrderID = Generate()
order.StoreNo = goods.StoreNo
order.CommodID = gSpecs.GoodsId
order.SkuNo = gSpecs.SkuNo
order.SkuID = req.SkuID
order.Code = req.Code
if req.Platform != "" {
order.Platform = getSysDictDataValue("release_channel", req.Platform)
}
order.Number = req.Number
order.Price = gSpecs.Price
order.PaidPrice = order.Price * float64(order.Number)
order.Type = 1
order.UserID = userId
order.Status = 1
// 调起支付方法 获取paysign
//err, payOrder := CreateOrderPayer(strconv.FormatFloat(order.Money, 'f', 2, 64), goods.SpuNo, req.Code)
err, payOrder := CreateOrderPayer(strconv.FormatFloat(0.01, 'f', 2, 64), &request.CreatePayOrderParams{OrderId: order.OrderID, SpuNo: goods.SpuNo, ClaimNo: req.Code})
if err != nil {
return errors.New("paypal下单失败"), nil
}
order.PaypalID = payOrder.ID
err = tx.Create(&order).Error
if err != nil {
tx.Rollback()
return errors.New("创建订单失败"), nil
}
var oGoods model.OrderGoods
oGoods.OrderID = order.OrderID
oGoods.SpuNo = goods.SpuNo
oGoods.SkuNo = gSpecs.SkuNo
oGoods.Specs = gSpecs.Specs
oGoods.TbGoodsBase = goods.TbGoodsBase
err = tx.Create(&oGoods).Error
if err != nil {
tx.Rollback()
return errors.New("save goods snapshot failed"), nil
}
// 快照记录商品所有规格
{
var (
gSpecsList []model.TbGoodsSpecs
oGoodsSpecs []model.OrderGoodsSpecs
)
err = global.MG_DB.Model(&model.TbGoodsSpecs{}).Where("goods_id = ?", goods.ID).Find(&gSpecsList).Error
if err != nil {
tx.Rollback()
return errors.New("get goods spec snapshot failed"), nil
}
for _, spec := range gSpecsList {
oGoodsSpecs = append(oGoodsSpecs, model.OrderGoodsSpecs{
TbGoodsSpecsBase: spec.TbGoodsSpecsBase,
OrderID: order.OrderID,
OrderGoodsId: oGoods.ID,
})
}
err = tx.Create(&oGoodsSpecs).Error
if err != nil {
tx.Rollback()
return errors.New("save goods spec snapshot failed"), nil
}
}
var oAddress model.OrderAddress
oAddress.Address = address
oAddress.OrderID = order.OrderID
oAddress.ID = 0
err = tx.Create(&oAddress).Error
if err != nil {
tx.Rollback()
return errors.New("创建订单相关地址失败"), nil
}
// 扣减商品库存
err = tx.Model(&model.TbGoodsSpecs{}).Where("id=?", req.SkuID).Update("stock", gorm.Expr("stock-?", req.Number)).Error
if err != nil {
tx.Rollback()
return errors.New("扣减商品库存失败"), nil
}
err = tx.Model(&model.TbGoods{}).Where("id=?", gSpecs.GoodsId).Update("stock", gorm.Expr("stock-?", req.Number)).Error
if err != nil {
tx.Rollback()
return errors.New("扣减商品库存失败"), nil
}
tx.Commit()
// 付款超时自动取消订单
utils.RedisSet("orderBack-"+order.OrderID, order.Number, time.Duration(global.MG_CONFIG.Paypal.OrderBack)*time.Hour)
// if result1 == "" {
// //err = errors.New("reids创建失败")
// //通知或记录
// }
return nil, payOrder
}
func AddUserOrderV1(userId string, device *request.Device, req *dto.CreateOrderRequest) (error, interface{}) {
var (
err error
//user model.User
goods model.TbGoods
gSpecs model.TbGoodsSpecs
address model.Address
//mission model.MissionClaim
mission model.Mission
result response.CreateOrder
)
// 开始交易
for {
err, ok := utils.RedisSetNX("commod-"+cast.ToString(req.SkuID), "used", 10*time.Second)
if ok && err == nil {
// 获取成功
break
}
}
defer func() {
// 释放锁
_, _ = utils.RedisDel("commod-" + cast.ToString(req.SkuID))
}()
// 校验code
if req.Code != "" {
tx := global.MG_DB.Begin()
err = tx.Model(&model.MissionClaim{}).Joins("INNER JOIN mission ON mission.id = mission_claim.mission_id").Where("mission_claim.claim_no = ?", req.Code).Select("mission.*").Find(&mission).Error
if err != nil || mission.ID == 0 {
return errors.New("任务码错误,请确认链接是否正确"), nil
}
}
err = global.MG_DB.Model(&model.TbGoodsSpecs{}).Where("id = ?", req.SkuID).Find(&gSpecs).Error
if err != nil {
return errors.New("获取规格信息失败"), nil
}
if gSpecs.Stock < int64(req.Number) {
return errors.New("商品库存不足"), nil
}
err = global.MG_DB.Model(&model.TbGoods{}).Where("id = ?", gSpecs.GoodsId).Find(&goods).Error
if err != nil {
return errors.New("获取商品信息失败"), nil
}
if goods.Online == "off" || goods.ID == 0 {
return errors.New("商品已下架,不可购买"), nil
}
// 校验任务码和商品关联
if mission.GoodsId != goods.ID { // 若任务领取码和下单商品不一致则将code置空
req.Code = ""
}
err = global.MG_DB.Model(&model.Address{}).Where("user_id = ? AND id = ?", userId, req.AddressID).Find(&address).Error
if err != nil {
return errors.New("获取地址信息失败"), nil
}
if address.ID == 0 {
return errors.New("请选择正确的收货地址"), nil
}
tx := global.MG_DB.Begin()
// 生成订单
var order model.Order
order.OrderID = Generate()
order.StoreNo = goods.StoreNo
order.CommodID = gSpecs.GoodsId
order.SkuNo = gSpecs.SkuNo
order.SkuID = int(req.SkuID)
order.Code = req.Code
order.PayMode = int(req.PayMode)
if req.Platform != "" {
order.Platform = getSysDictDataValue("release_channel", req.Platform)
}
order.Number = int(req.Number)
order.Price = gSpecs.Price
order.PaidPrice = order.Price * float64(order.Number)
order.Type = 1
order.UserID = userId
order.Status = 1
//order.PaypalID = payOrder.PayId
err = tx.Create(&order).Error
if err != nil {
tx.Rollback()
return errors.New("创建订单失败"), nil
}
var oGoods model.OrderGoods
oGoods.OrderID = order.OrderID
oGoods.SpuNo = goods.SpuNo
oGoods.SkuNo = gSpecs.SkuNo
oGoods.Specs = gSpecs.Specs
oGoods.TbGoodsBase = goods.TbGoodsBase
err = tx.Create(&oGoods).Error
if err != nil {
tx.Rollback()
return errors.New("save goods snapshot failed"), nil
}
var oGoodsSpec model.OrderGoodsSpecs
oGoodsSpec.TbGoodsSpecsBase = gSpecs.TbGoodsSpecsBase
oGoodsSpec.OrderID = order.OrderID
oGoodsSpec.OrderGoodsId = oGoods.ID
err = tx.Create(&oGoodsSpec).Error
if err != nil {
tx.Rollback()
return errors.New("save goods spec snapshot failed"), nil
}
var oAddress model.OrderAddress
oAddress.Address = address
oAddress.OrderID = order.OrderID
oAddress.AddressId = address.ID
oAddress.ID = 0
err = tx.Create(&oAddress).Error
if err != nil {
tx.Rollback()
return errors.New("创建订单相关地址失败"), nil
}
// 扣减商品库存
err = tx.Model(&model.TbGoodsSpecs{}).Where("id=?", req.SkuID).Update("stock", gorm.Expr("stock-?", req.Number)).Error
if err != nil {
tx.Rollback()
return errors.New("扣减商品库存失败"), nil
}
err = tx.Model(&model.TbGoods{}).Where("id=?", gSpecs.GoodsId).Update("stock", gorm.Expr("stock-?", req.Number)).Error
if err != nil {
tx.Rollback()
return errors.New("扣减商品库存失败"), nil
}
tx.Commit()
go calculateCreateOrderStatistics(request.OrderStatistic{
OrderId: order.OrderID,
SaleVolume: 0,
SkuNo: order.SkuNo,
SpuNo: goods.SpuNo,
UserId: order.UserID,
ClaimNo: order.Code,
StoreNo: order.StoreNo,
Money: order.Price,
})
// 调用支付方法
var payChannel string
switch order.PayMode {
case 1:
payChannel = "alipay-g"
case 2:
payChannel = "paypal"
default:
payChannel = "alipay-g"
}
attach, _ := json.Marshal(map[string]string{"orderId": order.OrderID})
payOrder, err := api.NewGreeterClient(global.PAY_CONN).PayTransactionWebUrl(context.Background(), &api.PayTransRequest{
Appid: "bkb5918273465092837",
Mchid: "11000001",
OutTradeNo: order.OrderID,
Attach: string(attach),
NotifyUrl: global.MG_CONFIG.Payment.NotifyUrl,
Amount: order.PaidPrice,
Currency: "USD",
PayChannel: payChannel,
ReturnUrl: global.MG_CONFIG.Payment.ReturnUrl + "?order_id=" + order.OrderID + "&spu_no=" + goods.SpuNo + "&claim_no=" + order.Code, // 回调链接,
CancelUrl: global.MG_CONFIG.Payment.CancelUrl + "?order_id=" + order.OrderID + "&spu_no=" + goods.SpuNo + "&claim_no=" + order.Code, // 取消链接,
Description: "BKB-" + goods.Title,
OsType: device.OsType,
TerminalType: device.TerminalType,
PaymentMethod: req.PaymentMethod,
})
if err != nil {
return errors.New("调起支付服务失败"), nil
}
_ = global.MG_DB.Model(&model.Order{}).Where("order_id = ?", order.OrderID).UpdateColumn("paypal_id", payOrder.PayId).Error
// 订单支付倒计时
utils.RedisSet("orderBack-"+order.OrderID, order.Number, time.Duration(global.MG_CONFIG.Paypal.OrderBack)*time.Hour)
result.PayChannel = payOrder.PayChannel
result.PayId = payOrder.PayId
result.PayReturn = payOrder.PayReturn
result.PayStatus = payOrder.PayStatus
result.OrderId = order.OrderID
return nil, result
}
func UpdateUserOrderStatus(userID string, info *request.UpdateUserOrderStatus) error {
var (
err error
order model.Order
)
err = global.MG_DB.Model(&model.Order{}).Where("user_id = ? and order_id = ?", userID, info.OrderID).First(&order).Error
if err != nil {
return errors.New("获取订单数据失败")
}
if order.CaptureID == "" && order.Status >= 2 {
return errors.New("正在付款途中,请稍后再试")
}
switch info.Status {
case 4: // 确认收货 完成订单
if order.Status != 3 {
return errors.New("order unship cannot receipt")
}
err = UserOrderConfirm(info.OrderID)
if err != nil {
return err
}
case 5: // 取消订单
// 删除定时取消任务
_, _ = utils.RedisDel("orderBack-" + info.OrderID)
// 释放库存
tx := global.MG_DB.Begin()
err = tx.Model(&model.TbGoodsSpecs{}).Where("id = ?", order.SkuID).Update("stock", gorm.Expr("stock + ?", order.Number)).Error
if err != nil {
tx.Rollback()
return errors.New("释放sku库存失败")
}
err = tx.Model(&model.TbGoods{}).Where("id = ?", order.CommodID).Update("stock", gorm.Expr("stock + ?", order.Number)).Error
if err != nil {
tx.Rollback()
return errors.New("释放spu库存失败")
}
// 退款
if order.Status == 2 && order.CaptureID != "" { // 账单中取消在途金额
attach, _ := json.Marshal(Attach{OrderId: order.OrderID})
err, _ = orderRefund(tx, order.OrderID, "订单取消", string(attach), order.PaidPrice)
if err != nil {
tx.Rollback()
return err
}
}
err = tx.Model(&model.Order{}).Where("id = ?", order.ID).Update("status", info.Status).Error
if err != nil {
tx.Rollback()
return errors.New("修改订单状态失败")
}
tx.Commit()
}
return nil
}
func UpdateOrderAddress(userId string, info *request.UpdateOrderAddress) error {
var (
err error
order model.Order
)
err = global.MG_DB.Model(&model.Order{}).Where("user_id = ? AND order_id = ?", userId, info.OrderID).First(&order).Error
if err != nil {
return errors.New("get order failed")
}
if order.Status != 1 && order.Status != 2 {
return errors.New("order not operable")
}
var orderAddress model.OrderAddress
err = global.MG_DB.Model(&model.OrderAddress{}).Where("order_id = ?", info.OrderID).Find(&orderAddress).Error
if err != nil {
return errors.New("get order address failed")
}
var oAddress model.OrderAddress
oAddress.Address = model.Address{
FirstName: info.FirstName,
LastName: info.LastName,
Street: info.Street,
Phone: info.Phone,
Bldg: info.Bldg,
City: info.City,
State: info.State,
ZipCode: info.ZipCode,
}
oAddress.OrderID = order.OrderID
err = global.MG_DB.Model(&model.OrderAddress{}).Where("order_id = ?", info.OrderID).Updates(&oAddress).Error
if err != nil {
return errors.New("operable failed")
}
// 更新用户收货地址管理
if orderAddress.AddressId != 0 {
_ = global.MG_DB.Model(&model.Address{}).Where("user_id = ? AND id = ?", userId, orderAddress.AddressId).Updates(&oAddress.Address).Error
}
return err
}
func DeleteUserOrderStatus(userID string, info *request.DeleteUserORder) error {
var (
err error
order model.Order
)
err = global.MG_DB.Model(&model.Order{}).Where("user_id=? and order_id=?", userID, info.OrderID).Find(&order).Error
if err != nil {
return errors.New("获取订单数据失败")
}
if order.Status != 5 {
return errors.New("订单状态不允许删除")
}
err = global.MG_DB.Model(&model.Order{}).Where("user_id=? and order_id=?", userID, info.OrderID).Delete(&model.Order{}).Error
if err != nil {
return errors.New("订单删除失败")
}
return nil
}
func GetPayOrderSign(userID string, info *request.SearchOrderDetail) (error, interface{}) {
var (
err error
order model.Order
goods model.TbGoods
)
err = global.MG_DB.Model(&model.Order{}).Where("user_id=? and order_id=?", userID, info.OrderID).Find(&order).Error
if err != nil {
return errors.New("获取订单数据失败"), nil
}
if order.Status != 1 {
return errors.New("订单状态不允许支付"), nil
}
err = global.MG_DB.Model(&model.TbGoods{}).Where("id=?", order.CommodID).Find(&goods).Error
if err != nil {
return errors.New("获取商品失败"), nil
}
//err, payOrder := CreateOrderPayer(strconv.FormatFloat(order.PaidPrice, 'f', 2, 64), &request.CreatePayOrderParams{OrderId: order.OrderID, SpuNo: goods.SpuNo, ClaimNo: order.Code})
err, payOrder := CreateOrderPayer(strconv.FormatFloat(0.01, 'f', 2, 64), &request.CreatePayOrderParams{OrderId: order.OrderID, SpuNo: goods.SpuNo, ClaimNo: order.Code})
// 调用支付方法
if err != nil {
fmt.Println(err)
return errors.New("调取支付失败"), nil
}
//global.MG_DB.Model(&model.Order{}).Where("user_id=? and order_id=?", userID, info.OrderID).Update("paypal_id", payOrder.ID)
tx := global.MG_DB.Begin()
err = tx.Model(&model.Order{}).Where("user_id=? and order_id=?", userID, info.OrderID).Update("paypal_id", payOrder.ID).Error
if err != nil {
tx.Rollback()
return err, nil
}
tx.Commit()
return nil, payOrder
}
func GetPayOrderSign1(userID string, device *request.Device, info *request.OrderPay) (error, interface{}) {
var (
err error
order model.Order
goods model.TbGoods
result response.CreateOrder
)
err = global.MG_DB.Model(&model.Order{}).Where("user_id = ? and order_id = ?", userID, info.OrderID).First(&order).Error
if err != nil {
return errors.New("获取订单数据失败"), nil
}
if order.Status != 1 {
return errors.New("订单状态不允许支付"), nil
}
err = global.MG_DB.Model(&model.TbGoods{}).Where("id = ?", order.CommodID).First(&goods).Error
if err != nil {
return errors.New("获取商品失败"), nil
}
// 调用支付方法
var payChannel string
switch info.PayMode {
case 1:
payChannel = "alipay-g"
case 2:
payChannel = "paypal"
default:
payChannel = "alipay-g"
}
attach, _ := json.Marshal(map[string]string{"orderId": order.OrderID})
payOrder, err := api.NewGreeterClient(global.PAY_CONN).PayTransactionWebUrl(context.Background(), &api.PayTransRequest{
Appid: "bkb5918273465092837",
Mchid: "11000001",
OutTradeNo: order.OrderID,
Attach: string(attach),
NotifyUrl: global.MG_CONFIG.Payment.NotifyUrl,
Amount: order.PaidPrice,
Currency: "USD",
PayChannel: payChannel,
ReturnUrl: global.MG_CONFIG.Payment.ReturnUrl + "?order_id=" + info.OrderID + "&spu_no=" + goods.SpuNo + "&claim_no=" + order.Code, // 回调链接,
CancelUrl: global.MG_CONFIG.Payment.CancelUrl + "?order_id=" + info.OrderID + "&spu_no=" + goods.SpuNo + "&claim_no=" + order.Code, // 取消链接,
Description: "BKB-" + goods.Title,
OsType: device.OsType,
TerminalType: device.TerminalType,
PaymentMethod: info.PayMethod,
})
if err != nil {
return errors.New("open " + payChannel + " failed"), nil
}
tx := global.MG_DB.Begin()
err = tx.Model(&model.Order{}).Where("user_id = ? and order_id = ?", userID, info.OrderID).Update("paypal_id", payOrder.PayId).Error
if err != nil {
tx.Rollback()
return err, nil
}
tx.Commit()
result.PayChannel = payOrder.PayChannel
result.PayId = payOrder.PayId
result.PayReturn = payOrder.PayReturn
result.PayStatus = payOrder.PayStatus
result.OrderId = order.OrderID
return nil, result
}
func PaypalCallback(paypalID, status string) error {
var (
err error
c *paypal.Client
)
if global.MG_CONFIG.Paypal.Env == "SandBox" {
c, err = paypal.NewClient(global.MG_CONFIG.Paypal.ClientID, global.MG_CONFIG.Paypal.Secret, paypal.APIBaseSandBox)
if err != nil {
return err
}
} else {
c, err = paypal.NewClient(global.MG_CONFIG.Paypal.ClientID, global.MG_CONFIG.Paypal.Secret, paypal.APIBaseLive)
if err != nil {
return err
}
}
_, err = c.GetAccessToken()
if err != nil {
return err
}
ctor := paypal.CaptureOrderRequest{}
order, err := c.CaptureOrder(paypalID, ctor)
if err != nil {
return err
}
// 查看回调完成后订单状态是否支付完成。
if (*order).Status == "FAILED" || (*order).Status == "DENIED" || status == "FAILED" || status == "DENIED" {
// 失败
global.MG_DB.Model(&model.Order{}).Where("paypal_id=?", paypalID).Update("status", 1)
return nil
}
if (*order).Status != "COMPLETED" {
return errors.New("pay fail")
}
orderstr, _ := json.Marshal(order)
println("-----", string(orderstr))
captureID := ""
if len((*order).PurchaseUnits) > 0 && len((*order).PurchaseUnits[0].Payments.Captures) > 0 {
captureID = (*order).PurchaseUnits[0].Payments.Captures[0].ID
}
_ = OrderCapture2("", paypalID, captureID)
return nil
}
type Attach struct {
OrderId string `json:"order_id"`
PostSaleId int `json:"post_sale_id"`
}
func PaypalCallback1(params *dto.PaybackBody) error {
switch params.ResourceType {
case "pay":
if params.Status != "SUCCESS" {
global.MG_DB.Model(&model.Order{}).Where("paypal_id = ?", params.PayId).Update("status", 1)
return nil
} else {
_ = OrderCapture2(params.OutTradeNo, params.PayId, params.CaptureId)
}
case "refund":
var (
err error
attach Attach
)
_ = json.Unmarshal([]byte(params.Attach), &attach)
tx := global.MG_DB.Begin()
if params.Status != "SUCCESS" {
if attach.PostSaleId != 0 {
var postSale model.OrderPostSale
err = global.MG_DB.Model(&model.OrderPostSale{}).Where("id = ?", attach.PostSaleId).First(&postSale).Error
if err != nil {
tx.Rollback()
return err
}
err = tx.Model(&model.OrderPostSale{}).Where("id = ?", postSale.ID).Updates(map[string]interface{}{"refund_status": "3"}).Error
if err != nil {
tx.Rollback()
return err
}
}
} else {
err = orderRefundSuccess(tx, params.OutTradeNo)
if err != nil {
tx.Rollback()
return err
}
if attach.PostSaleId != 0 {
var postSale model.OrderPostSale
err = global.MG_DB.Model(&model.OrderPostSale{}).Where("id = ?", attach.PostSaleId).First(&postSale).Error
if err != nil {
tx.Rollback()
return err
}
err = tx.Model(&model.OrderPostSale{}).Where("id = ?", postSale.ID).Updates(map[string]interface{}{"refund_status": "2"}).Error
if err != nil {
tx.Rollback()
return err
}
}
}
tx.Commit()
}
return nil
}
func CreateOrderPayer(amount string, params *request.CreatePayOrderParams) (error, *paypal.Order) {
var (
err error
c *paypal.Client
)
if global.MG_CONFIG.Paypal.Env == "SandBox" {
c, err = paypal.NewClient(global.MG_CONFIG.Paypal.ClientID, global.MG_CONFIG.Paypal.Secret, paypal.APIBaseSandBox)
if err != nil {
return err, nil
}
} else {
c, err = paypal.NewClient(global.MG_CONFIG.Paypal.ClientID, global.MG_CONFIG.Paypal.Secret, paypal.APIBaseLive)
if err != nil {
return err, nil
}
}
_, err = c.GetAccessToken()
if err != nil {
return err, nil
}
purchaseUnits := make([]paypal.PurchaseUnitRequest, 1)
purchaseUnits[0] = paypal.PurchaseUnitRequest{
Amount: &paypal.PurchaseUnitAmount{
Currency: "USD", // 收款类型
Value: amount, // 收款数量
},
}
payer := &paypal.CreateOrderPayer{}
appContext := &paypal.ApplicationContext{
ReturnURL: global.MG_CONFIG.Paypal.ReturnUrl + "?order_id=" + params.OrderId + "&spu_no=" + params.SpuNo + "&claim_no=" + params.ClaimNo, // 回调链接
CancelURL: global.MG_CONFIG.Paypal.CancelUrl + "?order_id=" + params.OrderId + "spu_no=" + params.SpuNo + "&claim_no=" + params.ClaimNo, // 取消链接,
}
order, err := c.CreateOrder("CAPTURE", purchaseUnits, payer, appContext)
if err != nil {
fmt.Println(err)
return err, nil
}
return nil, order
//(*order).Links[1].Href就是支付的链接
}
// 用户提现
func CreatePayOutPayer(paypalName, amount, withdID string) (error, *paypal.PayoutResponse) {
var (
err error
c *paypal.Client
)
if global.MG_CONFIG.Paypal.Env == "SandBox" {
c, err = paypal.NewClient(global.MG_CONFIG.Paypal.ClientID, global.MG_CONFIG.Paypal.Secret, paypal.APIBaseSandBox)
if err != nil {
return err, nil
}
} else {
c, err = paypal.NewClient(global.MG_CONFIG.Paypal.ClientID, global.MG_CONFIG.Paypal.Secret, paypal.APIBaseLive)
if err != nil {
return err, nil
}
}
_, err = c.GetAccessToken()
if err != nil {
return err, nil
}
payout := paypal.Payout{}
send := &paypal.SenderBatchHeader{
SenderBatchID: withdID,
}
item := make([]paypal.PayoutItem, 1)
fmt.Println(amount)
item[0] = paypal.PayoutItem{
RecipientType: "EMAIL",
Receiver: paypalName,
Amount: &paypal.AmountPayout{
Currency: "USD", // 收款类型
Value: amount, // 收款数量
},
Note: "打款",
}
payout.SenderBatchHeader = send
payout.Items = item
fmt.Println(payout.Items[0].Amount)
resp, err := c.CreateSinglePayout(payout)
if err != nil {
fmt.Println(err.Error())
fmt.Println(resp)
return err, nil
}
return err, resp
}
func UserOrderMessage(info *model.PaypalWebhookDetail) error {
switch info.ResourceType {
case "checkout-order":
// 订单付款
// 确认收款
PaypalCallback(info.Resource.ID, info.Resource.Status)
case "capture":
// 付款确认
case "payouts":
// 提现
UserWithdrawalHandle(info)
case "refund":
// 退款(待处理)
}
return nil
}
func UserWithdrawalHandle(info *model.PaypalWebhookDetail) {
var (
err error
bills []model.Bill
)
switch info.Resource.BatchHeader.BatchStatus {
case "SUCCESS":
uMap := make(map[string]interface{})
uMap["receipt"] = 1
uMap["withdrawal_status"] = 1
uMap["remark"] = "提现完成"
global.MG_DB.Model(&model.Bill{}).Where("withd_id=?", info.Resource.BatchHeader.SenderBatchHeader.SenderBatchID).Updates(uMap)
case "PROCESSING":
default:
// 失败
err = global.MG_DB.Model(&model.Bill{}).Where("withd_id=?", info.Resource.BatchHeader.SenderBatchHeader.SenderBatchID).Find(&bills).Error
if err != nil {
return
}
tx := global.MG_DB.Begin()
for v := range bills {
err = tx.Model(&model.Wallet{}).Where("user_id=?", bills[v].UserID).Update("balance", gorm.Expr("balance+?", bills[v].Price)).Error
if err != nil {
break
}
}
if err != nil {
tx.Rollback()
return
}
uMap := make(map[string]interface{})
uMap["receipt"] = 1
uMap["withdrawal_status"] = 2
uMap["remark"] = "提现失败,金额已返还到余额中"
err = global.MG_DB.Model(&model.Bill{}).Where("withd_id=?", info.Resource.BatchHeader.SenderBatchHeader.SenderBatchID).Updates(uMap).Error
if err != nil {
tx.Rollback()
return
}
tx.Commit()
}
}
func OrderCapture2(orderId, paypalId, captureId string) error {
// 开始交易
for {
err, result := utils.RedisSetNX("commod-settle-"+paypalId, "used", 10*time.Second)
if result && err == nil {
// 获取成功
break
}
}
defer func() {
// 释放锁
_, _ = utils.RedisDel("commod-settle-" + paypalId)
}()
var (
err error
order model.Order
orderGoods model.OrderGoods
)
if orderId != "" {
err = global.MG_DB.Model(&model.Order{}).Where("order_id = ?", orderId).First(&order).Error
if err != nil {
return errors.New("获取订单数据失败")
}
} else {
err = global.MG_DB.Model(&model.Order{}).Where("paypal_id = ?", paypalId).First(&order).Error
if err != nil {
return errors.New("获取订单数据失败")
}
}
if order.PayTime != nil {
fmt.Println("重复通知:", paypalId)
return errors.New("订单已支付")
}
err = global.MG_DB.Model(&model.OrderGoods{}).Where("order_id = ?", order.OrderID).First(&orderGoods).Error
if err != nil {
return errors.New("获取订单商品失败")
}
tx := global.MG_DB.Begin()
// 用户账单
var (
uBill model.Bill
iBill model.Bill
sBill model.Bill
)
uBill.UserID = order.UserID
uBill.Type = "2"
uBill.Title = ""
uBill.OrderID = order.OrderID
uBill.Price = order.PaidPrice
uBill.Balance = 0
uBill.Status = 1
uBill.Receipt = 1
uBill.Platform = "customer"
uBill.TransactionId = "B" + Generate()
err = tx.Create(&uBill).Error
if err != nil {
tx.Rollback()
return err
}
// 网红账单
if order.Code != "" {
var (
claim model.MissionClaim
mission model.Mission
wallet model.Wallet
)
err = global.MG_DB.Model(&model.MissionClaim{}).Where("claim_no = ?", order.Code).First(&claim).Error
if err != nil {
return errors.New("获取任务失败")
}
// 只会有比例抽成的任务存在订单
err = global.MG_DB.Model(&model.Mission{}).Where("id = ? AND hire_type = 2", claim.MissionId).Find(&mission).Error
if err != nil {
tx.Rollback()
return errors.New("获取任务失败")
}
// 网红账户
err, wallet = getWallet("influencer", claim.CreateBy)
if err != nil {
tx.Rollback()
return errors.New("获取网红钱包失败")
}
iBill.UserID = claim.CreateBy
iBill.Type = "1"
iBill.OrderID = order.OrderID
iBill.Price = math.Round(order.PaidPrice*(mission.HireRatio/100)*100) / 100
iBill.Balance = wallet.Balance
iBill.Status = 2
iBill.Receipt = 2
iBill.Platform = "influencer"
iBill.Title = "订单" + order.OrderID
iBill.TransactionId = "B" + Generate()
err = tx.Create(&iBill).Error
if err != nil {
tx.Rollback()
return errors.New("添加网红账单失败")
}
// 领取任务订单统计数据
err = tx.Model(&model.MissionClaim{}).Where("id = ?", claim.ID).UpdateColumns(map[string]interface{}{"achieve_num": gorm.Expr("achieve_num + ?", order.Number), "order_num": gorm.Expr("order_num + 1"), "order_money": gorm.Expr("order_money + ?", order.Price), "reward_unfinished": gorm.Expr("reward_unfinished + ?", iBill.Price)}).Error
if err != nil {
tx.Rollback()
return errors.New("更新任务领取在途佣金统计失败")
}
err = tx.Model(&model.Wallet{}).Where("user_id = ?", claim.CreateBy).Update("transit_balance", gorm.Expr("transit_balance + ?", iBill.Price)).Error
if err != nil {
tx.Rollback()
return errors.New("网红钱包添加在途金额失败")
}
}
var wallet model.Wallet
// 商家账户
err, wallet = getWallet("seller", order.StoreNo)
if err != nil {
tx.Rollback()
return errors.New("获取商家钱包失败")
}
sBill.UserID = order.StoreNo
sBill.Type = "2"
sBill.Title = ""
sBill.OrderID = order.OrderID
sBill.Price = uBill.Price - iBill.Price // 商家收入=用户支付-网红佣金
sBill.Balance = wallet.Balance
sBill.Status = 2
sBill.Receipt = 2
sBill.Platform = "seller"
sBill.TransactionId = "B" + Generate()
err = tx.Create(&sBill).Error
if err != nil {
tx.Rollback()
return errors.New("添加卖家账单失败")
}
err = tx.Model(&model.Wallet{}).Where("user_id = ?", order.StoreNo).Update("transit_balance", gorm.Expr("transit_balance + ?", sBill.Price)).Error
if err != nil {
tx.Rollback()
return errors.New("卖家钱包添加在途金额失败")
}
err = tx.Model(&model.Order{}).Where("order_id = ?", order.OrderID).Updates(map[string]interface{}{"status": 2, "capture_id": captureId, "pay_time": time.Now()}).Error
if err != nil {
tx.Rollback()
return errors.New("订单状态变更失败")
}
tx.Commit()
go updateTbGoodsSalesByGoodsId(order.CommodID, order.Number) // 统计商品总销售量
// 删除定时取消任务
_, _ = utils.RedisDel("orderBack-" + order.OrderID)
// 添加定时确认收货
utils.RedisSet("orderConfirm-"+order.OrderID, order.Number, time.Duration(global.MG_CONFIG.Paypal.OrderConfirm)*24*time.Hour)
go calculatePayOrderStatistics(request.OrderStatistic{
OrderId: order.OrderID,
SaleVolume: int64(order.Number),
SkuNo: order.SkuNo,
SpuNo: orderGoods.SpuNo,
UserId: order.UserID,
ClaimNo: order.Code,
StoreNo: order.StoreNo,
Money: order.PaidPrice,
Reward: iBill.Price,
})
return nil
}
func UserOrderBack(orderID string) error {
var (
err error
order model.Order
)
// 获取订单数据
err = global.MG_DB.Model(&model.Order{}).Where("order_id=?", orderID).Find(&order).Error
if err != nil {
return errors.New("获取订单数据失败")
}
if order.Status != 1 {
return errors.New("订单状态不可取消")
}
// 释放库存?
tx := global.MG_DB.Begin()
err = tx.Model(&model.TbGoodsSpecs{}).Where("id=?", order.SkuID).Update("stock", gorm.Expr("stock+?", order.Number)).Error
if err != nil {
tx.Rollback()
return errors.New("释放库存失败")
}
err = tx.Model(&model.TbGoods{}).Where("id=?", order.CommodID).Update("stock", gorm.Expr("stock+?", order.Number)).Error
if err != nil {
tx.Rollback()
return errors.New("释放库存失败")
}
err = tx.Model(&model.Order{}).Where("order_id=?", orderID).Update("status", 5).Error
if err != nil {
tx.Rollback()
return errors.New("修改订单状态失败")
}
tx.Commit()
return nil
}
func UserOrderConfirm(orderID string) error {
var (
err error
order model.Order
billList []model.Bill
storeNo string
influencer string
sellerM float64
influencerM float64
)
err = global.MG_DB.Model(&model.Order{}).Where("order_id = ?", orderID).First(&order).Error
if err != nil {
return errors.New("获取订单失败")
}
err = global.MG_DB.Model(&model.Bill{}).Where("order_id = ?", orderID).Find(&billList).Error
if err != nil {
return errors.New("获取在途账单失败")
}
for v := range billList {
switch billList[v].Status {
case 1: // 支出
if billList[v].Platform == "seller" {
storeNo = billList[v].UserID
sellerM -= billList[v].Price
} else if billList[v].Platform == "influencer" {
influencer = billList[v].UserID
influencerM -= billList[v].Price
}
case 2: // 收入
if billList[v].Platform == "seller" {
storeNo = billList[v].UserID
sellerM += billList[v].Price
} else if billList[v].Platform == "influencer" {
influencer = billList[v].UserID
influencerM += billList[v].Price
}
}
}
tx := global.MG_DB.Begin()
if storeNo != "" {
err = tx.Model(&model.Wallet{}).Where("user_id = ?", storeNo).
Updates(map[string]interface{}{"balance": gorm.Expr("balance + ?", sellerM), "transit_balance": gorm.Expr("transit_balance - ?", sellerM)}).Error
if err != nil {
tx.Rollback()
return errors.New("卖家钱包更新失败")
}
}
if influencer != "" {
// 更新任务订单统计数据
if order.Code != "" {
err = tx.Model(&model.MissionClaim{}).Where("claim_no = ?", order.Code).UpdateColumns(map[string]interface{}{"reward_finished": gorm.Expr("reward_finished + ?", influencerM), "reward_unfinished": gorm.Expr("reward_unfinished - ?", influencerM)}).Error
if err != nil {
tx.Rollback()
return errors.New("订单完成更新任务领取在途佣金统计失败")
}
}
err = tx.Model(&model.Wallet{}).Where("user_id = ?", influencer).Updates(map[string]interface{}{"balance": gorm.Expr("balance + ?", influencerM), "transit_balance": gorm.Expr("transit_balance - ?", influencerM)}).Error
if err != nil {
tx.Rollback()
return errors.New("订单完成网红钱包结算失败")
}
}
err = tx.Model(&model.Bill{}).Where("order_id = ?", orderID).Update("receipt", 1).Error
if err != nil {
tx.Rollback()
return errors.New("账单状态更新失败")
}
// 订单状态变更
err = tx.Model(&model.Order{}).Where("order_id = ?", orderID).Updates(map[string]interface{}{"status": 4, "confirm_time": time.Now()}).Error
if err != nil {
tx.Rollback()
return errors.New("订单状态更新失败")
}
tx.Commit()
// 删除定时收款任务
_, _ = utils.RedisDel("orderConfirm-" + orderID)
go calculateFinishOrderStatistics(request.OrderStatistic{
OrderId: order.OrderID,
UserId: order.UserID,
ClaimNo: order.Code,
StoreNo: order.StoreNo,
Money: order.PaidPrice,
Reward: influencerM,
})
return nil
}
// 生成24位订单号
// 前面17位代表时间精确到毫秒,中间3位代表进程id,最后4位代表序号
var num int64
func Generate() string {
t := time.Now()
s := t.Format(timeformat.Continuity)
m := t.UnixNano()/1e6 - t.UnixNano()/1e9*1e3
ms := sup(m, 3)
p := os.Getpid() % 1000
ps := sup(int64(p), 3)
i := atomic.AddInt64(&num, 1)
r := i % 10000
rs := sup(r, 4)
n := fmt.Sprintf("%s%s%s%s", s, ms, ps, rs)
return n
}
// 对长度不足n的数字前面补0
func sup(i int64, n int) string {
m := fmt.Sprintf("%d", i)
for len(m) < n {
m = fmt.Sprintf("0%s", m)
}
return m
}
func CreateWebhookRecord(body []byte) (error, interface{}) {
var (
err error
info model.PaypalWebhook
)
info.Value = string(body)
err = global.MG_DB.Create(&info).Error
if err != nil {
fmt.Println(err)
return err, nil
}
return nil, info
}
// 用户取消订单退款
func RefundPayOrderPayer(CaptureID string) (error, *paypal.PayoutResponse) {
var (
err error
data []byte
c *paypal.Client
)
if global.MG_CONFIG.Paypal.Env == "SandBox" {
c, err = paypal.NewClient(global.MG_CONFIG.Paypal.ClientID, global.MG_CONFIG.Paypal.Secret, paypal.APIBaseSandBox)
if err != nil {
return err, nil
}
} else {
c, err = paypal.NewClient(global.MG_CONFIG.Paypal.ClientID, global.MG_CONFIG.Paypal.Secret, paypal.APIBaseLive)
if err != nil {
return err, nil
}
}
_, err = c.GetAccessToken()
if err != nil {
return err, nil
}
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/captures/"+CaptureID+"/refund"), nil)
resp := &paypal.PayoutResponse{}
if err != nil {
return err, resp
}
if err = c.SendWithAuth(req, resp); err != nil {
return err, resp
}
json.Unmarshal(data, resp)
fmt.Println(string(data))
return err, resp
}
func CheckOrderStatus(userID string, info *request.CheckOrderParams) error {
var err error
// 确认订单
uMap := make(map[string]interface{})
uMap["status"] = 2
err = global.MG_DB.Model(&model.Order{}).Where("user_id=? and paypal_id=?", userID, info.Token).Updates(uMap).Error
if err != nil {
return errors.New("确认订单失败")
}
return nil
}
//func GetUserOrderGoods(userId string, info *request.OrderIDParams) (error, model.OrderGoodsDetail) {
// var (
// err error
// order model.Order
// result model.OrderGoodsDetail
// )
// err = global.MG_DB.Model(&model.Order{}).Joins("INNER JOIN mission_claim ON mission_claim.claim_no = `order`.`code`").
// Where("mission_claim.create_by = ? AND order_id = ?", userId, info.OrderID).Find(&order).Error
// if err != nil {
// return errors.New("获取订单失败"), result
// }
// err = global.MG_DB.Model(&model.OrderGoods{}).Where("order_id = ?", info.OrderID).Preload("OrderGoodsSpecs").Find(&result).Error
// if err != nil {
// return errors.New("获取订单商品信息失败"), result
// }
// var goodsSpecs []model.OrderGoodsSpecsView
// for _, spec := range result.OrderGoodsSpecs {
// goodsSpecs = append(goodsSpecs, model.OrderGoodsSpecsView{ID: spec.ID, Specs: spec.Specs, Image: spec.Image})
// }
// return err, result
//}
func GetOrderGoods(userId string, info *request.SearchOrderDetail) (error, model.OrderGoodsDetail) {
var (
err error
order model.Order
result model.OrderGoodsDetail
)
err = global.MG_DB.Model(&model.Order{}).Joins("INNER JOIN mission_claim ON mission_claim.claim_no = `order`.`code`").
Where("mission_claim.create_by = ? AND order_id = ?", userId, info.OrderID).Find(&order).Error
if err != nil {
return errors.New("获取订单失败"), result
}
err = global.MG_DB.Model(&model.OrderGoods{}).Where("order_id = ?", info.OrderID).Find(&result).Error
if err != nil {
return errors.New("获取订单商品信息失败"), result
}
err = global.MG_DB.Model(&model.OrderGoodsSpecs{}).Where("order_goods_id = ?", result.ID).Find(&result.GoodsSpecs).Error
if err != nil {
return errors.New("获取订单商品规格信息失败"), result
}
attributeValues := make(map[uint]*model.TbAttributeValueJson)
for i := 0; i < len(result.GoodsSpecs); i++ {
var attributeList []model.TbAttributeDetail
err = json.Unmarshal([]byte(result.GoodsSpecs[i].Specs), &attributeList)
if err != nil {
return err, result
}
if i == 0 {
var attributes []uint
for j := 0; j < len(attributeList); j++ {
attributes = append(attributes, attributeList[j].AttributeId)
}
orderSql := "FIELD(id"
for _, attribute := range attributes {
orderSql += fmt.Sprintf(",'%v'", attribute)
}
orderSql += ")"
err = global.MG_DB.Model(&model.TbAttribute{}).Select("id,`name`").Where("id IN (?)", attributes).Order(orderSql).Find(&result.Attributes).Error
if err != nil {
return err, result
}
}
for _, attribute := range attributeList {
if _, ok := attributeValues[attribute.AttributeId]; ok {
if !strings.Contains(attributeValues[attribute.AttributeId].Str, attribute.Value) {
attributeValues[attribute.AttributeId].Str += attribute.Value + ","
attributeValues[attribute.AttributeId].Items = append(attributeValues[attribute.AttributeId].Items, model.TbAttributeValueItem{Id: attribute.ValueId, Name: attribute.Value, Image: result.GoodsSpecs[i].Image})
}
} else {
attributeValues[attribute.AttributeId] = &model.TbAttributeValueJson{Items: []model.TbAttributeValueItem{{Id: attribute.ValueId, Name: attribute.Value, Image: result.GoodsSpecs[i].Image}}, Str: attribute.Value + ","}
}
}
}
for i := 0; i < len(result.Attributes); i++ {
if val, ok := attributeValues[result.Attributes[i].ID]; ok {
result.Attributes[i].Values = val.Items
}
}
return err, result
}
func GetOrderPostSale(userId string, params *request.IdReq) (model.OrderPostSale, error) {
var (
err error
result model.OrderPostSale
)
err = global.MG_DB.Model(&model.OrderPostSale{}).Where("user_id = ? AND id = ? ", userId, params.ID).First(&result).Error
return result, err
}
func OrderPostSale(userId string, params *request.PostSaleParams) (string, error) {
var (
err error
order model.Order
oldPS, postSale model.OrderPostSale
result string
)
ok, err := global.MG_REDIS.SetNX("postSale-"+params.OrderId, "used", 0).Result()
if !ok || err != nil {
return "", errors.New("request error")
}
defer func() {
// 释放锁
_, _ = utils.RedisDel("postSale-" + params.OrderId)
}()
// 校验申请原因数据字典取值
if !checkSysDictData("return_goods_reason", params.Reason) {
return "", errors.New("post-sale reason value error")
}
err = global.MG_DB.Model(&model.Order{}).Where("user_id = ? AND order_id = ?", userId, params.OrderId).First(&order).Error
if err != nil {
return "", errors.New("get order error")
}
// todo 1、订单状态未发货,已发货,已收货等下都可以申请退款 2、订单时长过长可以是否可以退款,待支付公司确认后再定。
if order.Status != 2 && order.Status != 3 && order.Status != 4 {
return "", errors.New("order status not operable")
}
if order.CaptureID == "" {
return "", errors.New("order in the process of payment")
}
// 校验退款
if params.Amount <= 0 || params.Amount > order.PaidPrice {
return "", errors.New("post-sale fund amount invalid")
}
err = global.MG_DB.Model(&model.OrderPostSale{}).Where("user_id = ? AND order_id = ? AND status IN (1,2)", userId, params.OrderId).Find(&oldPS).Error
if err != nil {
return "", err
}
if oldPS.ID != 0 {
return "", errors.New("repeated submission post-sale")
}
tx := global.MG_DB.Begin()
postSale.Type = 1
postSale.OrderID = params.OrderId
postSale.StoreNo = order.StoreNo
postSale.UserID = userId
postSale.Amount = params.Amount
postSale.Reason = params.Reason
postSale.Images = params.Images
postSale.Videos = params.Videos
if order.Status == 2 { // 未发货 全额退款
attach, _ := json.Marshal(Attach{OrderId: order.OrderID, PostSaleId: int(postSale.ID)})
err, _ = orderRefund(tx, order.OrderID, "订单退款", string(attach), postSale.Amount)
if err != nil {
tx.Rollback()
return "", err
}
postSale.Status = 2
postSale.RefundStatus = 1
} else {
postSale.Status = 1
}
err = tx.Model(&model.OrderPostSale{}).Create(&postSale).Error
if err != nil {
tx.Rollback()
return result, err
}
tx.Commit()
return result, err
}
func CancelOrderPostSale(userId string, params *request.IdReq) (string, error) {
var (
err error
postSale model.OrderPostSale
result string
)
err = global.MG_DB.Model(&model.OrderPostSale{}).Where("user_id = ? AND id = ?", userId, params.ID).First(&postSale).Error
if err != nil {
return "", err
}
if postSale.Status != 1 {
return "", errors.New("post-sale non cancellable")
}
tx := global.MG_DB.Begin()
err = tx.Model(&model.OrderPostSale{}).Where("user_id = ? AND id = ?", userId, params.ID).Update("status", "4").Error
if err != nil {
tx.Rollback()
return result, err
}
// todo 订单状态
tx.Commit()
return result, err
}
// 计算创建订单统计
func calculateCreateOrderStatistics(info request.OrderStatistic) {
var err error
defer func() {
if err != nil {
fmt.Println("calculateCreateOrderStatistics:", err.Error())
}
}()
now := time.Now().Format("060102") + "0000"
tx := global.MG_DB.Begin()
// 用户维度统计
var userOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ? AND `type` = 1", now, info.UserId).First(&userOrder).Error
if userOrder.ID == 0 {
userOrder.Value = now
userOrder.Unit = ""
userOrder.Type = 1
userOrder.RelationId = info.UserId
userOrder.NewOrderNum = 1
userOrder.NewOrderMoney = info.Money
err = tx.Model(&model.DtStatisticOrder{}).Create(&userOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["new_order_num"] = gorm.Expr("new_order_num + 1")
updateMap["new_order_money"] = gorm.Expr("new_order_money + ?", info.Money)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", userOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
if info.ClaimNo != "" {
// 网红领取任务维度统计
var influenceOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ? AND `type` = 2", now, info.ClaimNo).First(&influenceOrder).Error
if influenceOrder.ID == 0 {
influenceOrder.Value = now
influenceOrder.Unit = ""
influenceOrder.Type = 2
influenceOrder.RelationId = info.ClaimNo
influenceOrder.NewOrderNum = 1
influenceOrder.NewOrderMoney = info.Money
err = tx.Model(&model.DtStatisticOrder{}).Create(&influenceOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["new_order_num"] = gorm.Expr("new_order_num + 1")
updateMap["new_order_money"] = gorm.Expr("new_order_money + ?", info.Money)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", influenceOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
}
if info.StoreNo != "" {
// 店铺维度统计
var storeOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ? AND `type` = 3", now, info.StoreNo).First(&storeOrder).Error
if storeOrder.ID == 0 {
storeOrder.Value = now
storeOrder.Unit = ""
storeOrder.Type = 3
storeOrder.RelationId = info.StoreNo
storeOrder.NewOrderNum = 1
storeOrder.NewOrderMoney = info.Money
err = tx.Model(&model.DtStatisticOrder{}).Create(&storeOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["new_order_num"] = gorm.Expr("new_order_num + 1")
updateMap["new_order_money"] = gorm.Expr("new_order_money + ?", info.Money)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", storeOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
}
// 商品spu维度统计
// 平台维度统计
var bkbOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ?", now, "bkb").First(&bkbOrder).Error
if bkbOrder.ID == 0 {
bkbOrder.Value = now
bkbOrder.Unit = ""
bkbOrder.RelationId = "bkb"
bkbOrder.NewOrderNum = 1
bkbOrder.NewOrderMoney = info.Money
err = tx.Model(&model.DtStatisticOrder{}).Create(&bkbOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["new_order_num"] = gorm.Expr("new_order_num + 1")
updateMap["new_order_money"] = gorm.Expr("new_order_money + ?", info.Money)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", bkbOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
tx.Commit()
}
// 计算支付订单统计
func calculatePayOrderStatistics(info request.OrderStatistic) {
var err error
defer func() {
if err != nil {
fmt.Println("calculatePayOrderStatistics:", err.Error())
}
}()
now := time.Now().Format("060102") + "0000"
tx := global.MG_DB.Begin()
// 用户维度统计
var userOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ? AND `type` = 1", now, info.UserId).First(&userOrder).Error
if userOrder.ID == 0 {
userOrder.Value = now
userOrder.Unit = ""
userOrder.Type = 1
userOrder.RelationId = info.UserId
userOrder.OrderNum = 1
userOrder.OrderMoney = info.Money
userOrder.SaleVolume = info.SaleVolume
err = tx.Model(&model.DtStatisticOrder{}).Create(&userOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["order_num"] = gorm.Expr("order_num + 1")
updateMap["order_money"] = gorm.Expr("order_money + ?", info.Money)
updateMap["sale_volume"] = gorm.Expr("sale_volume + ?", info.SaleVolume)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", userOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
if info.ClaimNo != "" {
// 网红领取任务维度统计
var influenceOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ? AND `type` = 2", now, info.ClaimNo).First(&influenceOrder).Error
if influenceOrder.ID == 0 {
influenceOrder.Value = now
influenceOrder.Unit = ""
influenceOrder.Type = 2
influenceOrder.RelationId = info.ClaimNo
influenceOrder.OrderNum = 1
influenceOrder.OrderMoney = info.Money
influenceOrder.SaleVolume = info.SaleVolume
influenceOrder.TransitReward = info.Reward
err = tx.Model(&model.DtStatisticOrder{}).Create(&influenceOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["order_num"] = gorm.Expr("order_num + 1")
updateMap["order_money"] = gorm.Expr("order_money + ?", info.Money)
updateMap["sale_volume"] = gorm.Expr("sale_volume + ?", info.SaleVolume)
updateMap["transit_reward"] = gorm.Expr("transit_reward + ?", info.Reward)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", influenceOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
}
if info.StoreNo != "" {
// 店铺维度统计
var storeOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ? AND `type` = 3", now, info.StoreNo).First(&storeOrder).Error
if storeOrder.ID == 0 {
storeOrder.Value = now
storeOrder.Unit = ""
storeOrder.Type = 3
storeOrder.RelationId = info.StoreNo
storeOrder.OrderNum = 1
storeOrder.OrderMoney = info.Money
storeOrder.SaleVolume = info.SaleVolume
storeOrder.TransitReward = info.Money - info.Reward
err = tx.Model(&model.DtStatisticOrder{}).Create(&storeOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["order_num"] = gorm.Expr("order_num + 1")
updateMap["order_money"] = gorm.Expr("order_money + ?", info.Money)
updateMap["sale_volume"] = gorm.Expr("sale_volume + ?", info.SaleVolume)
updateMap["transit_reward"] = gorm.Expr("transit_reward + ?", info.Money-info.Reward)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", storeOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
}
{
// 商品sku维度统计
var skuOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ? AND `type` = 4", now, info.SkuNo).First(&skuOrder).Error
if skuOrder.ID == 0 {
skuOrder.Value = now
skuOrder.Unit = ""
skuOrder.Type = 4
skuOrder.RelationId = info.SkuNo
skuOrder.OrderNum = 1
skuOrder.OrderMoney = info.Money
skuOrder.SaleVolume = info.SaleVolume
err = tx.Model(&model.DtStatisticOrder{}).Create(&skuOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["order_num"] = gorm.Expr("order_num + 1")
updateMap["order_money"] = gorm.Expr("order_money + ?", info.Money)
updateMap["sale_volume"] = gorm.Expr("sale_volume + ?", info.SaleVolume)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", skuOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
}
{
// 商品spu维度统计
var spuOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ? AND `type` = 5", now, info.SpuNo).First(&spuOrder).Error
if spuOrder.ID == 0 {
spuOrder.Value = now
spuOrder.Unit = ""
spuOrder.Type = 5
spuOrder.RelationId = info.SpuNo
spuOrder.OrderNum = 1
spuOrder.OrderMoney = info.Money
spuOrder.SaleVolume = info.SaleVolume
err = tx.Model(&model.DtStatisticOrder{}).Create(&spuOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["order_num"] = gorm.Expr("order_num + 1")
updateMap["order_money"] = gorm.Expr("order_money + ?", info.Money)
updateMap["sale_volume"] = gorm.Expr("sale_volume + ?", info.SaleVolume)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", spuOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
}
// 平台维度统计
var bkbOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ?", now, "bkb").First(&bkbOrder).Error
if bkbOrder.ID == 0 {
bkbOrder.Value = now
bkbOrder.Unit = ""
bkbOrder.RelationId = "bkb"
bkbOrder.OrderNum = 1
bkbOrder.OrderMoney = info.Money
bkbOrder.SaleVolume = info.SaleVolume
err = tx.Model(&model.DtStatisticOrder{}).Create(&bkbOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["order_num"] = gorm.Expr("order_num + 1")
updateMap["order_money"] = gorm.Expr("order_money + ?", info.Money)
updateMap["sale_volume"] = gorm.Expr("sale_volume + ?", info.SaleVolume)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", bkbOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
tx.Commit()
}
// 计算完成订单统计
func calculateFinishOrderStatistics(info request.OrderStatistic) {
var err error
defer func() {
if err != nil {
fmt.Println("calculatePayOrderStatistics:", err.Error())
}
}()
now := time.Now().Format("060102") + "0000"
tx := global.MG_DB.Begin()
var userOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ? AND `type` = 1", now, info.UserId).First(&userOrder).Error
if userOrder.ID == 0 {
userOrder.Value = now
userOrder.Unit = ""
userOrder.Type = 1
userOrder.RelationId = info.UserId
userOrder.OrderDoneNum = 1
userOrder.SettleReward = info.Reward
err = tx.Model(&model.DtStatisticOrder{}).Create(&userOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["order_done_num"] = gorm.Expr("order_done_num + 1")
updateMap["settle_reward"] = gorm.Expr("settle_reward + ?", info.Reward)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", userOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
if info.ClaimNo != "" {
// 网红维度统计
var influenceOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ? AND `type` = 2", now, info.ClaimNo).First(&influenceOrder).Error
if influenceOrder.ID == 0 {
influenceOrder.Value = now
influenceOrder.Unit = ""
influenceOrder.Type = 2
influenceOrder.RelationId = info.ClaimNo
influenceOrder.OrderDoneNum = 1
influenceOrder.SettleReward = info.Reward
err = tx.Model(&model.DtStatisticOrder{}).Create(&influenceOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["order_done_num"] = gorm.Expr("order_done_num + 1")
updateMap["settle_reward"] = gorm.Expr("settle_reward + ?", info.Reward)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", influenceOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
}
if info.StoreNo != "" {
// 店铺维度统计
var storeOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ? AND `type` = 3", now, info.StoreNo).First(&storeOrder).Error
if storeOrder.ID == 0 {
storeOrder.Value = now
storeOrder.Unit = ""
storeOrder.Type = 3
storeOrder.RelationId = info.StoreNo
storeOrder.OrderDoneNum = 1
storeOrder.SettleReward = info.Reward
err = tx.Model(&model.DtStatisticOrder{}).Create(&storeOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["order_done_num"] = gorm.Expr("order_done_num + 1")
updateMap["settle_reward"] = gorm.Expr("settle_reward + ?", info.Reward)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", storeOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
}
{
// 商品sku维度统计
var goodsOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ? AND `type` = 4", now, info.SkuNo).First(&goodsOrder).Error
if goodsOrder.ID == 0 {
goodsOrder.Value = now
goodsOrder.Unit = ""
goodsOrder.Type = 4
goodsOrder.RelationId = info.SkuNo
goodsOrder.OrderNum = 1
goodsOrder.OrderMoney = info.Money
err = tx.Model(&model.DtStatisticOrder{}).Create(&goodsOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["order_done_num"] = gorm.Expr("order_done_num + 1")
updateMap["settle_reward"] = gorm.Expr("settle_reward + ?", info.Reward)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", goodsOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
}
{
// 商品spu维度统计
var goodsOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ? AND `type` = 5", now, info.SpuNo).First(&goodsOrder).Error
if goodsOrder.ID == 0 {
goodsOrder.Value = now
goodsOrder.Unit = ""
goodsOrder.Type = 5
goodsOrder.RelationId = info.SpuNo
goodsOrder.OrderNum = 1
goodsOrder.OrderMoney = info.Money
err = tx.Model(&model.DtStatisticOrder{}).Create(&goodsOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["order_done_num"] = gorm.Expr("order_done_num + 1")
updateMap["settle_reward"] = gorm.Expr("settle_reward + ?", info.Reward)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", goodsOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
}
// 平台维度统计
var bkbOrder model.DtStatisticOrder
_ = global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND relation_id = ?", now, "bkb").First(&bkbOrder).Error
if bkbOrder.ID == 0 {
bkbOrder.Value = now
bkbOrder.Unit = ""
bkbOrder.RelationId = "bkb"
bkbOrder.OrderDoneNum = 1
bkbOrder.SettleReward = info.Reward
err = tx.Model(&model.DtStatisticOrder{}).Create(&bkbOrder).Error
if err != nil {
tx.Rollback()
return
}
} else {
var updateMap = make(map[string]interface{})
updateMap["order_done_num"] = gorm.Expr("order_done_num + 1")
updateMap["settle_reward"] = gorm.Expr("settle_reward + ?", info.Reward)
err = tx.Model(&model.DtStatisticOrder{}).Where("id = ?", bkbOrder.ID).Updates(&updateMap).Error
if err != nil {
tx.Rollback()
return
}
}
tx.Commit()
}
func specsToAttributes(specs *[]model.TbOrderGoodsSpecsDetail) (error, []model.TbAttributeWithValues) {
var (
err error
attributeIds []uint
attributeMap = make(map[uint]string)
result []model.TbAttributeWithValues
)
attributeValues := make(map[uint]*model.TbAttributeValueJson)
for i := 0; i < len(*specs); i++ {
var attributes []model.TbAttributeDetail
err = json.Unmarshal([]byte((*specs)[i].Specs), &attributes)
if err != nil {
return err, nil
}
if i == 0 {
for _, attribute := range attributes {
attributeIds = append(attributeIds, attribute.AttributeId)
result = append(result, model.TbAttributeWithValues{
TbAttributeView: model.TbAttributeView{ID: attribute.AttributeId, Name: ""},
Values: []model.TbAttributeValueItem{},
})
}
}
for _, attribute := range attributes {
if _, ok := attributeValues[attribute.AttributeId]; ok {
if !strings.Contains(attributeValues[attribute.AttributeId].Str, attribute.Value) {
attributeValues[attribute.AttributeId].Str += attribute.Value + ","
attributeValues[attribute.AttributeId].Items = append(attributeValues[attribute.AttributeId].Items, model.TbAttributeValueItem{Name: attribute.Value, Image: (*specs)[i].Image})
}
(*specs)[i].Code += fmt.Sprintf("#%v-%v", attribute.AttributeId, len(attributeValues[attribute.AttributeId].Items)-1)
} else {
attributeValues[attribute.AttributeId] = &model.TbAttributeValueJson{Items: []model.TbAttributeValueItem{{Name: attribute.Value, Image: (*specs)[i].Image}}, Str: attribute.Value + ","}
(*specs)[i].Code += fmt.Sprintf("#%v-0", attribute.AttributeId)
}
}
}
{
var attributeList []model.TbAttributeWithValues
err = global.MG_DB.Model(&model.TbAttribute{}).Select("id,`name`").Where("id IN (?)", attributeIds).Find(&attributeList).Error
if err != nil {
return err, nil
}
for _, attribute := range attributeList {
attributeMap[attribute.ID] = attribute.Name
}
}
for i := 0; i < len(result); i++ {
if val, ok := attributeMap[result[i].ID]; ok {
result[i].Name = val
}
if val, ok := attributeValues[result[i].ID]; ok {
result[i].Values = val.Items
}
}
return nil, result
}
func orderRefund(tx *gorm.DB, orderId, title, attach string, amount float64) (error, string) {
var (
err error
order model.Order
)
ok, err := global.MG_REDIS.SetNX("orderRefund-"+orderId, "used", 0).Result()
if !ok || err != nil {
return errors.New("request error"), ""
}
err = tx.Model(&model.Order{}).Where("order_id = ?", orderId).First(&order).Error
if order.Status != 2 {
err = errors.New("订单状态错误")
return err, ""
}
if amount > order.PaidPrice {
err = errors.New("退款金额错误")
return err, ""
}
{
// 用户付款账单处理
var bill model.Bill
err = tx.Model(&model.Bill{}).Where("platform = 'customer' AND order_id = ? AND type = '2' AND `status` = 1", order.OrderID).UpdateColumn("receipt", 3).Error
if err != nil {
return err, ""
}
bill.UserID = order.UserID
bill.Type = "2"
bill.Title = title + "-订单" + order.OrderID
bill.OrderID = order.OrderID
bill.Price = amount
bill.Status = 2
bill.Receipt = 2
bill.Platform = "customer"
bill.TransactionId = "R" + Generate()
err = tx.Create(&bill).Error
if err != nil {
return err, ""
}
}
{
if order.Code != "" {
var (
oldBill model.Bill
bill model.Bill
wallet model.Wallet
)
err = tx.Model(&model.Bill{}).Where("platform = 'influencer' AND order_id = ? AND type = '1' AND `status` = 2", order.OrderID).Find(&oldBill).Error
if err != nil {
return err, ""
}
// 扣除领取任务订单统计数据
err = tx.Model(&model.MissionClaim{}).Where("claim_no = ?", order.Code).UpdateColumns(map[string]interface{}{"order_num": gorm.Expr("order_num - 1"), "order_money": gorm.Expr("order_money - ?", order.Price), "reward_unfinished": gorm.Expr("reward_unfinished - ?", oldBill.Price)}).Error
if err != nil {
return err, ""
}
err = tx.Model(&model.Wallet{}).Where("user_id = ? AND platform = 'seller'", oldBill.UserID).Update("transit_balance", gorm.Expr("transit_balance - ?", oldBill.Price)).Error
if err != nil {
return err, ""
}
err, wallet = getWallet("influencer", oldBill.UserID)
if err != nil {
return err, ""
}
bill.UserID = oldBill.UserID
bill.Type = "1"
bill.Title = title + "-订单" + oldBill.OrderID
bill.OrderID = oldBill.OrderID
bill.Price = oldBill.Price
bill.Balance = wallet.Balance
bill.Status = 1
bill.Receipt = 2
bill.Platform = oldBill.Platform
bill.TransactionId = "R" + Generate()
bill.Remark = "订单取消"
err = tx.Create(&bill).Error
if err != nil {
return err, ""
}
}
}
{
var (
oldBill model.Bill
bill model.Bill
wallet model.Wallet
)
err = tx.Model(&model.Bill{}).Where("platform = 'seller' AND order_id = ? AND type = '2' AND `status` = 2", order.OrderID).Find(&oldBill).Error
if err != nil {
return err, ""
}
err = tx.Model(&model.Wallet{}).Where("user_id = ?", oldBill.UserID).Update("transit_balance", gorm.Expr("transit_balance - ?", oldBill.Price)).Error
if err != nil {
return err, ""
}
err, wallet = getWallet("seller", oldBill.UserID)
if err != nil {
return err, ""
}
bill.UserID = oldBill.UserID
bill.Type = "2"
bill.Title = "交易退款-订单" + oldBill.OrderID
bill.OrderID = oldBill.OrderID
bill.Price = oldBill.Price
bill.Balance = wallet.Balance
bill.Status = 1
bill.Receipt = 2
bill.Platform = oldBill.Platform
bill.TransactionId = "R" + Generate()
bill.Remark = "订单取消"
err = tx.Create(&bill).Error
if err != nil {
return err, ""
}
}
params1 := api.RefundRequest{
Appid: "bkb5918273465092837",
Mchid: "11000001",
OutTradeNo: order.OrderID,
PayId: order.PaypalID,
Attach: attach,
NotifyUrl: global.MG_CONFIG.Payment.NotifyUrl,
Amount: amount,
Description: "订单退款-" + order.OrderID,
}
refundResp, err := api.NewGreeterClient(global.PAY_CONN).RefundBill(context.Background(), &params1)
if err != nil {
return err, ""
}
if refundResp.RefundStatus != "SUCCESS" {
err = errors.New("refund failed")
return err, ""
}
return err, refundResp.RefundId
}
func orderRefundSuccess(tx *gorm.DB, orderId string) error {
var (
err error
order model.Order
)
err = tx.Model(&model.Order{}).Where("order_id = ?", orderId).First(&order).Error
if err != nil {
return err
}
{
err = tx.Model(&model.Bill{}).Where("platform = 'customer' AND order_id = ? AND type = '2' AND `status` = 2 AND receipt = 2", orderId).Update("receipt", 1).Error
if err != nil {
return err
}
}
{
if order.Code != "" {
err = tx.Model(&model.Bill{}).Where("platform = 'influencer' AND order_id = ? AND type = '1' AND `status` = 1 AND receipt = 2", orderId).Update("receipt", 1).Error
if err != nil {
return err
}
}
}
{
err = tx.Model(&model.Bill{}).Where("platform = 'seller' AND order_id = ? AND type = '2' AND `status` = 1 AND receipt = 2", orderId).Update("receipt", 1).Error
if err != nil {
return err
}
}
return err
}