package after import ( "errors" mysql2 "git.oa00.com/go/mysql" gorm2 "gorm.io/gorm" "recook/internal/dbc" "recook/internal/libs/bean" "recook/internal/service/comFunc" "recook/internal/v2/hook" "recook/internal/v2/logic/pay" "recook/internal/v2/logic/pay/alipay" "recook/internal/v2/logic/pay/recook" "recook/internal/v2/logic/pay/union" "recook/internal/v2/logic/pay/wechat" "recook/internal/v2/logic/pay/wechatH5innter" "recook/internal/v2/logic/pay/wechatmini" "recook/internal/v2/logic/pay/wechatweb" after2 "recook/internal/v2/model/gys/after" "recook/internal/v2/model/recook/after" "recook/internal/v2/model/recook/coin" "recook/internal/v2/model/recook/goods" manage2 "recook/internal/v2/model/recook/manage" manage "recook/internal/v2/model/recook/order" user2 "recook/internal/v2/model/recook/user" "github.com/golangkit/formatime" "github.com/jinzhu/gorm" "github.com/shopspring/decimal" ) var Logic = &afterLogic{} type afterLogic struct { } type AFTQueryListResp struct { AsID uint `json:"asID"` OrderGoodsID uint `json:"orderGoodsID"` SkuCode string `json:"skuCode"` GoodsName string `json:"goodName"` UnitPrice decimal.Decimal `json:"UnitPrice"` RefundCoin decimal.Decimal `json:"refundCoin"` RefundAmount decimal.Decimal `json:"refundAmount"` ExpressFee decimal.Decimal `json:"expressFee"` Address manage.RecookOrderAddrModel `json:"address"` Status uint `json:"status"` CreatedAt int64 `json:"created_at"` FinishTime int64 `json:"finishTime"` OrderID uint `json:"orderID"` PayMethod uint `json:"pay_method"` PurchasePrice decimal.Decimal `json:"purchasePrice"` Quantity uint `json:"quantity"` SupplierPrice decimal.Decimal `json:"supplierPrice"` } type AFTQueryListReq struct { bean.Page AsID uint `json:"asID"` // 售后单号 SkuCode string `json:"skuCode"` // 商品条码 OrderSn uint `json:"orderSn"` // 主订单编号 GoodsName string `json:"goodsName"` // 商品标题 Status uint `json:"status"` // 售后状态 Receiver string `json:"receiver"` // 收货人 Phone string `json:"phone"` // 手机号 StartDate string `json:"startDate"` // 申请开始时间 EndDate string `json:"endDate"` // 申请结束时间 CStartDate string `json:"cStartDate"` // 完成开始时间 CEndDate string `json:"cEndDate"` // 完成结束时间 AssType uint `json:"assType"` // 分类 IsClosed uint `json:"isClosed"` // 是否关闭 LabelStatus uint `json:"labelStatus"` // 标签状态 } func (o afterLogic) List(q *AFTQueryListReq) ([]AFTQueryListResp, int) { return o.ListByVendor(q, -1) } func (o afterLogic) ListByVendor(q *AFTQueryListReq, vendor int) (list []AFTQueryListResp, total int) { aft := after.RecookAfterSalesGoodsModel{} addr := manage.RecookOrderAddrModel{} rog := manage.RecookOrderGoodsDetailModel{} var orderIDs []uint if len(q.Phone) != 0 { orderIDs = addr.FindOrderIDByMobile(q.Phone) } if len(q.Receiver) != 0 { orderIDs = addr.FindOrderIDByName(q.Receiver) } query := aft.GetDb().Model(&aft) if q.AssType != 0 { query = query.Where(AssType(q.AssType).getWhere().query) } else { query = query.Where(AssType(ATUnshippedAfterSale).getWhere().query) } if vendor >= 0 { query = query.Where("vendor_id = ?", vendor) } { if q.Status != 0 { query = query.Where("is_closed = ?", q.IsClosed) query = query.Where("return_status=? ", q.Status) } if q.LabelStatus != 0 { query = query.Where("is_closed = ?", q.IsClosed) query = query.Where("return_status=? ", q.LabelStatus) } if len(orderIDs) != 0 { query = query.Where("order_id IN (?)", orderIDs) } if len(q.CStartDate) != 0 { query = query.Where("finish_time > ?", q.CStartDate) } if len(q.CEndDate) != 0 { query = query.Where("finish_time < ?", q.CEndDate) } if len(q.StartDate) != 0 { query = query.Where("created_at > ?", q.StartDate) } if len(q.EndDate) != 0 { query = query.Where("created_at < ?", q.EndDate) } if len(q.GoodsName) != 0 { query = query.Where("goods_name like ?", q.GoodsName+"%") } if q.OrderSn != 0 { query = query.Where("order_id = ?", q.OrderSn) } if len(q.SkuCode) != 0 { query = query.Where("sku_code = ?", q.SkuCode) } if q.AsID != 0 { query = query.Where("id = ?", q.AsID) } } query.Count(&total) start := q.GetStart() if total > start { var temp []after.RecookAfterSalesGoodsModel if db := query.Offset(start).Limit(q.GetLimit()).Order("id DESC").Find(&temp); db.Error != nil { return } for _, v := range temp { rog = rog.FindById(v.OrderGoodsId) list = append(list, AFTQueryListResp{ AsID: v.Id, OrderGoodsID: v.OrderGoodsId, SkuCode: v.SkuCode, GoodsName: v.GoodsName, UnitPrice: rog.UnitPrice, RefundAmount: v.RefundAmount, RefundCoin: v.RefundCoin, ExpressFee: v.ExpressFree, Address: addr.FindByOrderId(v.OrderId), Status: v.ReturnStatus, CreatedAt: v.CreatedAt.Time.Unix(), FinishTime: v.FinishTime.Time.Unix(), OrderID: v.OrderId, PayMethod: v.PayMethod, PurchasePrice: rog.PurchasePrice, Quantity: rog.Quantity, SupplierPrice: v.SupplierPrice, }) } } return } type AFTDetailReq struct { AsID uint `json:"asID" binding:"required"` } type afterSaleResp struct { AsID uint `json:"asID"` OrderID uint `json:"orderID"` OrderGoodsID uint `json:"orderGoodsID"` GoodsName string `json:"goodsName"` PayMethod uint `json:"payMethod"` ApplyTime formatime.Second `json:"applyTime"` CreatedAt formatime.Second `json:"createdAt"` FinishTime formatime.Second `json:"finishTime"` VendorName string `json:"vendorName"` SkuCode string `json:"skuCode"` Reason string `json:"reason"` ReasonContent string `json:"reasonContent"` ReasonType uint `json:"reasonType"` AssType uint `json:"assType"` ExpressName string `json:"expressName"` RejectReason string `json:"rejectReason"` ExpressCompName string `json:"expressCompName"` ExpressCompCode string `json:"expressCompCode"` ExpressNo string `json:"expressNo"` ExpressFee decimal.Decimal `json:"expressFee"` RefundAmount decimal.Decimal `json:"refundAmount"` RefundCoin decimal.Decimal `json:"refundCoin"` ReturnStatus uint `json:"returnStatus"` OrderGoodsAmount decimal.Decimal `json:"orderGoodsAmount"` IsClosed int `json:"isClosed"` ReasonImg string `json:"reasonImg"` CheckTime formatime.Second `json:"checkTime"` SupplierPrice decimal.Decimal `json:"supplierPrice"` } type orderAddrResp struct { ReceiverName string `json:"receiverName"` Mobile string `json:"mobile"` Province string `json:"province"` City string `json:"city"` District string `json:"district"` Address string `json:"address"` } type orderGoodsDetailResp struct { MainPhotoURL string `json:"mainPhotoUrl"` GoodsName string `json:"goodsName"` SkuName string `json:"skuName"` PurchasePrice decimal.Decimal `json:"purchasePrice"` UnitPrice decimal.Decimal `json:"unitPrice"` Quantity uint `json:"quantity"` GoodsAmount decimal.Decimal `json:"goodsAmount"` ExpressFee decimal.Decimal `json:"expressFee"` CoinAmount decimal.Decimal `json:"coinAmount"` ActualAmount decimal.Decimal `json:"actualAmount"` BuyerMessage string `json:"buyerMessage"` NickName string `json:"nickName"` Phone string `json:"phone"` } type AFTDetailResp struct { Aft afterSaleResp `json:"aft"` Addr orderAddrResp `json:"addr"` OrderGoodsDetail orderGoodsDetailResp `json:"orderGoodsDetail"` OrderExpress []manage.RecookOrderGoodsExpressModel `json:"orderExpress"` Logs []after.RecookAfterSalesLogsModel `json:"logs"` Proof []after.RecookAfterSalesProofModel `json:"proof"` RtAddress after2.GysReturnAddressModel `json:"rtAddress"` } func (o afterLogic) Close(q *AFTDetailReq) error { aft := after.RecookAfterSalesGoodsModel{} aft = aft.GetAFTByID(q.AsID) if aft.ReturnStatus > 3 { return errors.New("该售后不符合关闭要求") } if err := hook.AfterHook.Close(&aft); err != nil { return err } aftNew := after.RecookAfterSalesGoodsModel{ ReturnStatus: 2, IsClosed: 1, RefundStatus: 2, } order := manage.RecookOrderGoodsDetailModel{ RefundStatus: 2, } err := mysql2.Db.Transaction(func(tx *gorm2.DB) error { err := tx.Table(aft.TableName()).Where("id = ?", aft.Id).Updates(&aftNew).Error if err != nil { return err } err = tx.Table(order.TableName()).Where("id=?", aft.OrderGoodsId).Updates(&order).Error if err != nil { return err } return nil }) if err != nil { return err } return nil } func (o afterLogic) Detail(q *AFTDetailReq) (result AFTDetailResp) { aft := after.RecookAfterSalesGoodsModel{} aft = aft.GetAFTByID(q.AsID) if aft.Id <= 0 { return } result.Aft = afterSaleResp{ AsID: aft.Id, OrderID: aft.OrderId, OrderGoodsID: aft.OrderGoodsId, GoodsName: aft.GoodsName, PayMethod: aft.PayMethod, ApplyTime: aft.ApplyTime, CreatedAt: aft.CreatedAt, FinishTime: aft.FinishTime, VendorName: aft.VendorName, SkuCode: aft.SkuCode, Reason: aft.Reason, ReasonContent: aft.ReasonContent, ReasonType: aft.ReasonType, AssType: aft.AssType, ExpressName: aft.ExpressCompName, RejectReason: aft.RejectReason, ExpressCompName: aft.ExpressCompName, ExpressCompCode: aft.ExpressCompCode, ExpressNo: aft.ExpressNo, ExpressFee: aft.ExpressFree, RefundAmount: aft.RefundAmount, RefundCoin: aft.RefundCoin, ReturnStatus: aft.ReturnStatus, OrderGoodsAmount: aft.RefundAmount.Add(aft.ExpressFree), IsClosed: aft.IsClosed, ReasonImg: aft.ReasonImg, CheckTime: aft.CheckTime, SupplierPrice: aft.SupplierPrice, } addr := manage.RecookOrderAddrModel{} addr = addr.FindByOrderId(aft.OrderId) result.Addr = orderAddrResp{ ReceiverName: addr.ReceiverName, Mobile: addr.Mobile, Province: addr.Province, City: addr.City, District: addr.District, Address: addr.Address, } ogd := manage.RecookOrderGoodsDetailModel{} ogd.GetDb().Table(ogd.TableName()).Where("id = ?", aft.OrderGoodsId).First(&ogd) u := user2.RecookUserInfoModel{} u = u.FindById(aft.UserId) result.OrderGoodsDetail = orderGoodsDetailResp{ MainPhotoURL: ogd.MainPhotoURL, GoodsName: ogd.GoodsName, SkuName: ogd.SkuName, PurchasePrice: ogd.PurchasePrice, UnitPrice: ogd.UnitPrice, Quantity: ogd.Quantity, GoodsAmount: ogd.GoodsAmount, ExpressFee: ogd.ExpressFee, CoinAmount: ogd.CoinAmount, ActualAmount: ogd.ActualAmount, BuyerMessage: ogd.BuyerMessage, NickName: u.Nickname, Phone: u.Phone, } express := manage.RecookOrderGoodsExpressModel{} express.GetDb().Table(express.TableName()).Where("order_id = ?", aft.OrderId).Find(&result.OrderExpress) sub := aft.GetDb().Table(aft.TableName()+" as aft"). Select("aft.id"). Where("order_goods_id = ?", aft.OrderGoodsId). SubQuery() log := after.RecookAfterSalesLogsModel{} log.GetDb().Table(log.TableName()). Where("as_id in (?)", sub).Order("id DESC").Find(&result.Logs) proof := after.RecookAfterSalesProofModel{} proof.GetDb().Table(proof.TableName()).Where("as_id = ?", q.AsID).Order("id DESC").Find(&result.Proof) g := goods.RecookGoodsInfoModel{} gSub := g.GetDb().Table(g.TableName()).Select("return_address_id"). Where("id = ?", aft.GoodsId).SubQuery() if aft.AssType > 1 { rt := after2.GysReturnAddressModel{} rt.GetDb().Table(rt.TableName()).Where("id in (?)", gSub).First(&result.RtAddress) } return } type AFTFeeUpdateReq struct { AsID uint `json:"asID" binding:"required"` Fee decimal.Decimal `json:"fee" binding:"required"` URLs []string `json:"urls" binding:"required"` } func (o afterLogic) UpdateCompensateFee(q *AFTFeeUpdateReq) error { aft := after.RecookAfterSalesGoodsModel{} if err := aft.GetDb().Transaction(func(tx *gorm.DB) error { tx.Table(aft.TableName()).Where("id = ?", q.AsID).First(&aft) if aft.Id <= 0 { return errors.New("未找到售后") } if aft.AssType != 3 { return errors.New("该订单并不是补偿售后") } og := manage.RecookOrderGoodsDetailModel{} tx.Table(og.TableName()).Where("id = ?", aft.OrderGoodsId).First(&og) if og.Id <= 0 { return errors.New("未查到该订单") } if q.Fee.GreaterThan(og.ActualAmount.Add(og.CoinAmount)) { return errors.New("补偿超过总和") } if q.Fee.LessThanOrEqual(og.ActualAmount) { aft.RefundAmount = q.Fee.Truncate(2) aft.RefundCoin = decimal.NewFromInt(0) } if q.Fee.GreaterThan(og.ActualAmount) { aft.RefundAmount = og.ActualAmount aft.RefundCoin = q.Fee.Sub(og.ActualAmount).Truncate(2) } if err := tx.Save(&aft).Error; err != nil { return err } if err := saveProof(tx, q.URLs, aft.Id); err != nil { return err } return nil }); err != nil { return err } return nil } func (o afterLogic) UpdateSupplierFee(q *AFTFeeUpdateReq) error { aft := after.RecookAfterSalesGoodsModel{} if err := aft.GetDb().Transaction(func(tx *gorm.DB) error { aft.GetDb().Table(aft.TableName()).Where("id = ?", q.AsID).First(&aft) if aft.Id <= 0 { return errors.New("未找到售后") } aft.SupplierPrice = q.Fee if err := tx.Save(&aft).Error; err != nil { return err } if err := saveProof(tx, q.URLs, aft.Id); err != nil { return err } return nil }); err != nil { return err } return nil } type UpdateOrderCheckStatusReq struct { AsID uint `json:"asID" binding:"required"` Opinion uint `json:"opinion" binding:"required"` // 审核意见 1:可以退货 2 拒绝退货 RejectReason string `json:"rejectReason"` // 拒绝理由 Need uint `json:"need"` // 1:需要 2:不需要 URLs []string `json:"urls"` // 凭证 SupplierPrice decimal.Decimal `json:"supplierPrice"` // 供应商承担价格 补偿订单必须填写 } func refundWithType(tx *gorm.DB, asGoods after.RecookAfterSalesGoodsModel) error { switch asGoods.PayMethod { case manage.RecookOrderInfoPayMethodRecookPay: if err := recook.Refund(tx, &asGoods); err != nil { return err } case manage.RecookOrderInfoPayMethodWechatPay: if err := wechat.Refund(&asGoods); err != nil { return err } case manage.RecookOrderInfoPayMethodAlipay: if err := alipay.Refund(tx, &asGoods); err != nil { return err } case manage.RecookOrderInfoPayMethodWechatMiniPay: if err := wechatmini.Refund(&asGoods); err != nil { return err } case manage.RecookOrderInfoPayMethodAlipayH5: if err := alipay.Refund(tx, &asGoods); err != nil { return err } case manage.RecookOrderInfoPayMethodWechatH5Pay: if err := wechatweb.Refund(&asGoods); err != nil { return err } case manage.RecookOrderInfoPayMethodWechatH5Inner: if err := wechatH5innter.Refund(&asGoods); err != nil { return err } case manage.RecookOrderInfoPayMethodUnionPay: if err := union.Refund(&asGoods); err != nil { return err } } return nil } func Refund(tx *gorm.DB, asGoods after.RecookAfterSalesGoodsModel, orderInfo manage.RecookOrderInfoModel, q *UpdateOrderCheckStatusReq, user manage2.RecookManageUserInfoModel) error { condition := asGoods.IsShip == 1 && asGoods.RefundAmount.IsZero() if err := tx.Model(&asGoods).Updates(after.RecookAfterSalesGoodsModel{ ReturnStatus: 5, RefundStatus: 1, CheckTime: formatime.NewSecondNow(), SupplierPrice: q.SupplierPrice, }).Error; err != nil { return err } //这里插入日志 Log1 := after.RecookAfterSalesLogsModel{ AsID: asGoods.Id, Title: "平台同意退款", Content: "同意买家退款,平台将在24小时内处理退款。", CTime: formatime.NewSecondNow(), User: user.Name, UserId: user.Id, } tx.Create(&Log1) Log2 := after.RecookAfterSalesLogsModel{ AsID: asGoods.Id, Title: "退款成功", Content: "退款金额¥" + asGoods.RefundAmount.String() + "将原路退回至您的付款账户,请及时关注到账情况。|退回瑞币" + asGoods.RefundCoin.Add(asGoods.ExpressFree).String() + "已返回至您的瑞币账户,请及时合适。|若3天内未收到退款/瑞币,请联系客服咨询。", CTime: formatime.NewSecondNow(), User: user.Name, UserId: user.Id, } tx.Create(&Log2) if condition { if err := pay.SyncRefundSuccessCallback(tx, &asGoods); err != nil { return errors.New("退款失败") } } else { if err := refundWithType(tx, asGoods); err != nil { return err } } if err := saveProof(tx, q.URLs, asGoods.Id); err != nil { return err } return nil } func (o afterLogic) Review(q *UpdateOrderCheckStatusReq, user manage2.RecookManageUserInfoModel) error { if q.Opinion == 2 && len(q.RejectReason) == 0 { return errors.New("必须填写拒绝理由") } var asGoods after.RecookAfterSalesGoodsModel if err := dbc.DB.First(&asGoods, q.AsID).Error; err != nil { return err } var orderInfo manage.RecookOrderInfoModel if err := dbc.DB.First(&orderInfo, asGoods.OrderId).Error; err != nil { return err } // 0正常,1等待商家审核 2审核被拒绝 3审核成功 4买家已填写退货物流信息 5收到退货,确认退款完成 6退货被拒绝 if asGoods.AssType == 2 { // 退货 退款 if q.Opinion == 1 { if q.Need == 0 { return errors.New("请确认是否需要退货") } if q.Need == 1 { tx := dbc.DB.Begin() if err := tx.Model(&asGoods).Updates(after.RecookAfterSalesGoodsModel{ ReturnStatus: 3, CheckTime: formatime.NewSecondNow(), }).Error; err != nil { tx.Rollback() return err } //这边增加一个让买家填写单号的通知 var userNotice = &user2.RecookUserNoticeModel{ Type: 4, UserID: asGoods.UserId, Content: "您的售后已通过,尽快填写退回的快递单号", CreatTime: formatime.NewSecondNow(), } tx.Create(userNotice) var gs goods.RecookGoodsInfoModel tx.First(&gs, "id = ?", asGoods.GoodsId) //这里插入日志 var addr after2.GysReturnAddressModel dbc.DB.First(&addr, "id = ?", gs.ReturnAddressID) Log1 := after.RecookAfterSalesLogsModel{ AsID: asGoods.Id, Title: "平台同意退货", Content: "平台同意买家退货,买家须在48小时内上传物流信息,否则系统将自动关闭退货请求。|
寄回地址:" + addr.Address + " " + " " + addr.Name + addr.Mobile + "
", CTime: formatime.NewSecondNow(), User: user.Name, UserId: user.Id, } tx.Create(&Log1) if err := saveProof(tx, q.URLs, asGoods.Id); err != nil { tx.Rollback() return err } tx.Commit() } if q.Need == 2 { tx := dbc.DB.Begin() if err := Refund(tx, asGoods, orderInfo, q, user); err != nil { tx.Rollback() return err } tx.Commit() } } else { // 拒绝的话,将原来的订单商品ass_type标记下 tx := dbc.DB.Begin() { if err := tx.Model(&asGoods).Updates(after.RecookAfterSalesGoodsModel{ ReturnStatus: 2, RejectReason: q.RejectReason, FinishTime: formatime.NewSecondNow(), }).Error; err != nil { tx.Rollback() return err } if err := tx.Model(&manage.RecookOrderGoodsDetailModel{Id: asGoods.OrderGoodsId}).Updates(map[string]interface{}{ "ass_type": 0, }).Error; err != nil { tx.Rollback() return err } } Log1 := after.RecookAfterSalesLogsModel{ AsID: asGoods.Id, Title: "平台拒绝退货", Content: "拒绝买家退货申请,如有疑问,请联系客服", CTime: formatime.NewSecondNow(), User: user.Name, UserId: user.Id, } tx.Create(&Log1) if err := saveProof(tx, q.URLs, asGoods.Id); err != nil { tx.Rollback() return err } tx.Commit() } } else { // 只是退款 tx := dbc.DB.Begin() { if q.Opinion == 1 { if err := Refund(tx, asGoods, orderInfo, q, user); err != nil { tx.Rollback() return err } tx.Commit() } else { // 拒绝的话,将原来的订单商品ass_type标记下 if err := tx.Model(&asGoods).Updates(after.RecookAfterSalesGoodsModel{ ReturnStatus: 2, RejectReason: q.RejectReason, FinishTime: formatime.NewSecondNow(), }).Error; err != nil { tx.Rollback() return err } if err := tx.Model(&manage.RecookOrderGoodsDetailModel{Id: asGoods.OrderGoodsId}).Updates(map[string]interface{}{ "ass_type": 0, }).Error; err != nil { tx.Rollback() return err } //这里插入日志 Log1 := after.RecookAfterSalesLogsModel{ AsID: asGoods.Id, Title: "平台拒绝退款", Content: "拒绝买家退款申请,如有疑问,请联系客服", CTime: formatime.NewSecondNow(), User: user.Name, UserId: user.Id, } tx.Create(&Log1) Log2 := after.RecookAfterSalesLogsModel{ AsID: asGoods.Id, Title: "退款关闭", Content: "系统自动关闭", CTime: formatime.NewSecondNow(), User: user.Name, UserId: user.Id, } tx.Create(&Log2) if err := saveProof(tx, q.URLs, asGoods.Id); err != nil { tx.Rollback() return err } tx.Commit() } } } return nil } func (o afterLogic) ReviewReturnAfter(q *UpdateOrderCheckStatusReq, user manage2.RecookManageUserInfoModel) error { var asGoods after.RecookAfterSalesGoodsModel if err := dbc.DB.First(&asGoods, q.AsID).Error; err != nil { return err } if asGoods.AssType == 1 { return errors.New("该订单仅退款") } if asGoods.ReturnStatus != 4 { return errors.New("订单状态不可更新") } var orderInfo manage.RecookOrderInfoModel if err := dbc.DB.First(&orderInfo, asGoods.OrderId).Error; err != nil { return err } if q.Opinion == 2 { if len(q.RejectReason) == 0 { return errors.New("没有填写拒绝原因") } tx := dbc.DB.Begin() { if err := tx.Model(&asGoods).Updates(after.RecookAfterSalesGoodsModel{ ReturnStatus: 3, //让买家继续填写单号 RejectReason: q.RejectReason, FinishTime: formatime.NewSecondNow(), }).Error; err != nil { tx.Rollback() return err } //这边增加一个让买家填写单号的通知 var userNotice = user2.RecookUserNoticeModel{ Type: 4, UserID: asGoods.UserId, Content: "您的售后已通过,尽快填写退回的快递单号", CreatTime: formatime.NewSecondNow(), } tx.Create(userNotice) //这里插入日志 var addr after2.GysReturnAddressModel dbc.DB.Last(&addr) Log1 := after.RecookAfterSalesLogsModel{ AsID: asGoods.Id, Title: "平台拒绝收货", Content: "已收到买家退回商品,不符合退货条件,拒绝退款。理由:" + q.RejectReason + "|买家须在48小时内上传物流信息,否则系统将自动关闭退货请求。|
寄回地址:" + addr.Address + " " + addr.Name + " " + addr.Mobile + "
", CTime: formatime.NewSecondNow(), User: user.Name, UserId: user.Id, } tx.Create(&Log1) Log2 := after.RecookAfterSalesLogsModel{ AsID: asGoods.Id, Title: "等待买家重新上传物流信息", Content: "", CTime: formatime.NewSecondNow(), User: user.Name, UserId: user.Id, } tx.Create(&Log2) if err := saveProof(tx, q.URLs, asGoods.Id); err != nil { tx.Rollback() return err } } tx.Commit() } else { tx := dbc.DB.Begin() { if err := tx.Model(&asGoods).Updates(after.RecookAfterSalesGoodsModel{ ReturnStatus: 5, RefundStatus: 1, }).Error; err != nil { tx.Rollback() return err } if err := refundWithType(tx, asGoods); err != nil { return err } } Log1 := after.RecookAfterSalesLogsModel{ AsID: asGoods.Id, Title: "平台确认收货", Content: "已收到买家退回商品,符合退货条件,同意退款。|平台将在24小时内处理退款。", CTime: formatime.NewSecondNow(), User: user.Name, UserId: user.Id, } tx.Create(&Log1) Log2 := after.RecookAfterSalesLogsModel{ AsID: asGoods.Id, Title: "退款成功", Content: "退款金额¥" + asGoods.RefundAmount.String() + "将原路退回至您的付款账户,请及时关注到账情况。|退回瑞币" + asGoods.RefundCoin.Add(asGoods.ExpressFree).String() + "已返回至您的瑞币账户,请及时合适。|若3天内未收到退款/瑞币,请联系客服咨询。", CTime: formatime.NewSecondNow(), User: user.Name, UserId: user.Id, } tx.Create(&Log2) if err := saveProof(tx, q.URLs, asGoods.Id); err != nil { tx.Rollback() return err } tx.Commit() } return nil } func refundRecord(tx *gorm.DB, o manage.RecookOrderInfoModel, after after.RecookAfterSalesGoodsModel) bool { // pay success 里面已经调用 这边不需要更新 if o.PayMethod != 0 { if o.CoinTotalAmount.GreaterThan(decimal.NewFromInt(0)) { var orderGoods manage.RecookOrderGoodsDetailModel if err := dbc.DB.First(&orderGoods, after.OrderGoodsId).Error; err != nil { return false } var coinHistory coin.RecookCoinHistoryModel coinHistory.UserId = o.UserId coinHistory.CoinType = coin.RefundTypeForCoinHistory1 // coinHistory.CoinNum = orderInfo.CoinTotalAmount coinHistory.CoinNum = orderGoods.CoinAmount coinHistory.OrderAmount = o.GoodsTotalAmount coinHistory.OrderId = o.Id coinHistory.Remark = "商品退款-退回" // beego.Info(coinHistory.CoinNum, orderInfo.CoinTotalAmount) if err := tx.Save(&coinHistory).Error; err != nil { comFunc.PrintErr("refundRecord save coinHistory error:", err) return false } if err := coinHistory.UpdateWalletAfterCreate(tx, o.UserId); err != nil { comFunc.PrintErr("refundRecord UpdateWalletAfterCreate error:", err) return false } } } return true } func saveProof(tx *gorm.DB, urls []string, asID uint) error { for _, v := range urls { t := after.RecookAfterSalesProofModel{ AsID: asID, URL: v, CreatedAt: formatime.NewTimestampNow(), } if err := tx.Table(t.TableName()).FirstOrCreate(&t, "as_id = ? and url = ?", asID, v).Error; err != nil { return err } } return nil }