465 lines
15 KiB
Go
465 lines
15 KiB
Go
package dao
|
||
|
||
import (
|
||
"encoding/json"
|
||
"gorm.io/gorm"
|
||
"micro-bundle/internal/model"
|
||
"micro-bundle/pb/bundle"
|
||
"micro-bundle/pkg/app"
|
||
commonErr "micro-bundle/pkg/err"
|
||
"micro-bundle/pkg/msg"
|
||
"micro-bundle/pkg/utils"
|
||
"time"
|
||
)
|
||
|
||
func CreateOrderRecord(orderRecord *model.BundleOrderRecords, req *bundle.OrderRecord) (res *bundle.CommonResponse, err error) {
|
||
res = new(bundle.CommonResponse)
|
||
bundleInfo := new(model.BundleProfile)
|
||
// 生成UUID和订单号
|
||
orderRecord.UUID = app.ModuleClients.SfNode.Generate().Base64()
|
||
orderRecord.OrderNo = utils.GetOrderNo()
|
||
|
||
// 开启事务
|
||
tx := app.ModuleClients.BundleDB.Begin()
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
tx.Rollback()
|
||
}
|
||
}()
|
||
|
||
// 查询套餐主表并预加载
|
||
err = tx.Model(&model.BundleProfile{}).
|
||
Where("uuid = ?", orderRecord.BundleUUID).
|
||
Preload("BundleToValueAddService").
|
||
Preload("BundleProfileLang", "language = ?", req.Language).
|
||
First(&bundleInfo).Error
|
||
if err != nil {
|
||
tx.Rollback()
|
||
res.Msg = msg.ErrorBundleNotFound
|
||
return res, commonErr.ReturnError(err, msg.ErrorBundleNotFound, "查询Bundle信息失败: ")
|
||
}
|
||
|
||
// 填充BundleCommonJson字段
|
||
if bundleJson, e := json.Marshal(bundleInfo); e == nil {
|
||
orderRecord.BundleCommonJson = bundleJson
|
||
} else {
|
||
tx.Rollback()
|
||
res.Msg = msg.ErrorDataConvert
|
||
return res, commonErr.ReturnError(e, msg.ErrorDataConvert, "Bundle信息转换失败: ")
|
||
}
|
||
|
||
// 创建主订单
|
||
if err = tx.Model(&model.BundleOrderRecords{}).Create(orderRecord).Error; err != nil {
|
||
tx.Rollback()
|
||
res.Msg = msg.ErrorCreateOrderInfo
|
||
return res, commonErr.ReturnError(err, msg.ErrorCreateOrderInfo, "创建订单信息失败: ")
|
||
}
|
||
var (
|
||
childOrders []*model.BundleOrderValueAdd
|
||
valueAddAmount float64
|
||
expirationTime = "9999-12-31"
|
||
)
|
||
for _, service := range bundleInfo.BundleToValueAddService {
|
||
amount, info, num, day, e := calculateAmount(service.ValueUid, req)
|
||
if e != nil {
|
||
tx.Rollback()
|
||
res.Msg = msg.ErrorDataConvert
|
||
return res, commonErr.ReturnError(e, msg.ErrorDataConvert, "子订单金额计算失败: ")
|
||
}
|
||
if day != "" {
|
||
expirationTime = day
|
||
}
|
||
valueAddAmount = valueAddAmount + amount
|
||
childOrder := &model.BundleOrderValueAdd{
|
||
UUID: app.ModuleClients.SfNode.Generate().Base64(),
|
||
OrderUUID: orderRecord.UUID, // 修正: 这里应使用主订单UUID
|
||
CustomerID: orderRecord.CustomerID,
|
||
CustomerNum: orderRecord.CustomerNum,
|
||
CustomerName: orderRecord.CustomerName,
|
||
ServiceType: info.ServiceType,
|
||
CurrencyType: info.PriceType,
|
||
Amount: amount,
|
||
OrderNo: orderRecord.OrderNo,
|
||
Num: num,
|
||
Unit: info.Unit,
|
||
ValueAddUUID: service.ValueUid,
|
||
Source: 1,
|
||
PaymentStatus: 1,
|
||
SignContract: orderRecord.SignContract,
|
||
Signature: orderRecord.Signature,
|
||
SignedTime: orderRecord.SignedTime,
|
||
}
|
||
childOrders = append(childOrders, childOrder)
|
||
}
|
||
// 批量创建子订单(提高性能)
|
||
if err = tx.Model(&model.BundleOrderValueAdd{}).Create(childOrders).Error; err != nil {
|
||
tx.Rollback()
|
||
return res, commonErr.ReturnError(err, msg.ErrorCreateOrderInfo, "批量创建子订单失败")
|
||
}
|
||
// 更新总金额
|
||
updateData := map[string]interface{}{
|
||
"total_amount": gorm.Expr("total_amount + ?", valueAddAmount),
|
||
"updated_at": time.Now(),
|
||
"expiration_time": expirationTime,
|
||
}
|
||
if err = tx.Model(&model.BundleOrderRecords{}).
|
||
Where("uuid = ?", orderRecord.UUID).
|
||
Updates(updateData).Error; err != nil {
|
||
tx.Rollback()
|
||
return res, commonErr.ReturnError(err, msg.ErrorUpdateOrderInfo, "更新订单总金额失败")
|
||
}
|
||
// 提交事务
|
||
if err = tx.Commit().Error; err != nil {
|
||
res.Msg = msg.ErrorCommitTransaction
|
||
return res, commonErr.ReturnError(err, msg.ErrorCommitTransaction, "提交事务失败: ")
|
||
}
|
||
|
||
res.Uuid = orderRecord.UUID
|
||
res.OrderNo = orderRecord.OrderNo
|
||
res.Msg = msg.SuccessCreateOrderInfo
|
||
return
|
||
}
|
||
|
||
// calculateAmount 计算子订单金额
|
||
func calculateAmount(valueUid string, req *bundle.OrderRecord) (amount float64, valueAddServiceLang *model.ValueAddServiceLang, num int32, expirationDay string, err error) {
|
||
err = app.ModuleClients.BundleDB.
|
||
Where("uuid = ? AND language = ?", valueUid, req.Language).
|
||
First(&valueAddServiceLang).Error
|
||
if err != nil {
|
||
return
|
||
}
|
||
for _, opt := range valueAddServiceLang.Options {
|
||
for _, p := range req.PriceOptionsInfo {
|
||
if p.ValueUid == valueUid && opt.Id == p.Id {
|
||
num = opt.Num
|
||
if valueAddServiceLang.PriceMode == 1 {
|
||
amount = float64(float32(opt.Num) * opt.Price)
|
||
} else if valueAddServiceLang.PriceMode == 2 {
|
||
amount = float64(opt.Price)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 计算过期时间
|
||
if valueAddServiceLang.ServiceType == 5 {
|
||
expirationDay = calculateExpirationDay(opt.Num, valueAddServiceLang.Unit)
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// calculateExpirationDay 计算到期日
|
||
func calculateExpirationDay(num int32, unit string) string {
|
||
now := time.Now()
|
||
switch unit {
|
||
case "天":
|
||
return now.AddDate(0, 0, int(num)).Format("2006-01-02")
|
||
case "月":
|
||
return now.AddDate(0, int(num), 0).Format("2006-01-02")
|
||
case "年":
|
||
return now.AddDate(int(num), 0, 0).Format("2006-01-02")
|
||
default:
|
||
return ""
|
||
}
|
||
}
|
||
func UpdateOrderRecord(orderRecord *model.BundleOrderRecords) (res *bundle.CommonResponse, err error) {
|
||
res = new(bundle.CommonResponse)
|
||
err = app.ModuleClients.BundleDB.Model(&model.BundleOrderRecords{}).Where("uuid = ?", orderRecord.UUID).Updates(orderRecord).Error
|
||
if err != nil {
|
||
res.Msg = msg.ErrorUpdateOrderInfo
|
||
return res, commonErr.ReturnError(err, msg.ErrorUpdateOrderInfo, "更新订单信息失败: ")
|
||
}
|
||
res.Uuid = orderRecord.UUID
|
||
res.Msg = msg.SuccessUpdateOrderInfo
|
||
return
|
||
}
|
||
|
||
func UpdateOrderRecordByOrderNO(orderRecord *model.BundleOrderRecords) (res *bundle.CommonResponse, err error) {
|
||
res = new(bundle.CommonResponse)
|
||
// Step 1: 先更新子订单(增值服务)的支付状态
|
||
valueAdd := &model.BundleOrderValueAdd{
|
||
PaymentStatus: int(orderRecord.Status),
|
||
PaymentTime: orderRecord.PayTime,
|
||
}
|
||
err = app.ModuleClients.BundleDB.Model(&model.BundleOrderValueAdd{}).
|
||
Where("order_no = ?", orderRecord.OrderNo).
|
||
Updates(valueAdd).Error
|
||
if err != nil {
|
||
res.Msg = msg.ErrorUpdateOrderInfo
|
||
return res, commonErr.ReturnError(err, msg.ErrorUpdateOrderInfo, "更新增值服务支付状态失败: ")
|
||
}
|
||
// Step 2: 再更新主订单信息(如果存在)
|
||
err = app.ModuleClients.BundleDB.Model(&model.BundleOrderRecords{}).
|
||
Where("order_no = ?", orderRecord.OrderNo).
|
||
Updates(orderRecord).Error
|
||
// Step 3: 返回结果(即使主订单更新失败,也视为成功)
|
||
res.Uuid = orderRecord.UUID
|
||
res.Msg = msg.SuccessUpdateOrderInfo
|
||
return res, nil
|
||
}
|
||
|
||
func OrderRecordsList(req *bundle.OrderRecordsRequest) (res *bundle.OrderRecordsResponse, err error) {
|
||
res = new(bundle.OrderRecordsResponse)
|
||
res.OrderRecords = make([]*bundle.OrderRecord, 0)
|
||
records := make([]*model.BundleOrderRecords, 0)
|
||
|
||
query := app.ModuleClients.BundleDB.Model(&model.BundleOrderRecords{})
|
||
|
||
query.Joins("left join `micro-account`.`user` on `micro-account`.`user`.`id` = `bundle_order_records`.`customer_id`")
|
||
|
||
if req.CustomerID != "" {
|
||
query = query.Where("customer_id = ?", req.CustomerID)
|
||
}
|
||
|
||
if req.CustomerNum != "" {
|
||
query = query.Where("customer_num like ?", "%"+req.CustomerNum+"%")
|
||
}
|
||
|
||
if req.CustomerName != "" {
|
||
query = query.Where("customer_name like ?", "%"+req.CustomerName+"%")
|
||
}
|
||
|
||
if req.BundleName != "" {
|
||
query = query.Where("bundle_name like ?", "%"+req.BundleName+"%")
|
||
}
|
||
|
||
if req.BundleUUID != "" {
|
||
query = query.Where("bundle_uuid = ?", req.BundleUUID)
|
||
}
|
||
|
||
if req.OrderNo != "" {
|
||
query = query.Where("order_no like ?", "%"+req.OrderNo+"%")
|
||
}
|
||
|
||
if req.Status != 0 {
|
||
query = query.Where("`bundle_order_records`.status = ?", req.Status)
|
||
}
|
||
|
||
if req.StartSignedTime != "" {
|
||
query = query.Where("signed_time >= ?", req.StartSignedTime)
|
||
}
|
||
|
||
if req.EndSignedTime != "" {
|
||
query = query.Where("signed_time <= ?", req.EndSignedTime)
|
||
}
|
||
|
||
if req.StartPayTime != "" {
|
||
query = query.Where("pay_time >= ?", req.StartPayTime)
|
||
}
|
||
|
||
if req.EndPayTime != "" {
|
||
query = query.Where("pay_time <= ?", req.EndPayTime)
|
||
}
|
||
|
||
if req.IsHaveValueAdd == 1 { // 有
|
||
query = query.Where("value_add_bundle_uuid != ?", "")
|
||
} else if req.IsHaveValueAdd == 2 { // 无
|
||
query = query.Where("IFNULL(value_add_bundle_uuid,'') = ''")
|
||
}
|
||
|
||
if req.FinancialConfirmation != 0 {
|
||
query = query.Where("financial_confirmation = ?", req.FinancialConfirmation)
|
||
}
|
||
|
||
if req.TelNum != "" {
|
||
query = query.Where("`micro-account`.`user`.`tel_num` like ?", "%"+req.TelNum+"%")
|
||
}
|
||
|
||
count := *query
|
||
|
||
if req.PageSize != 0 && req.Page != 0 {
|
||
query = query.Limit(int(req.PageSize)).Offset(int(req.Page-1) * int(req.PageSize))
|
||
}
|
||
|
||
err = query.Find(&records).Error
|
||
|
||
if err != nil {
|
||
return res, commonErr.ReturnError(err, msg.ErrorGetOrderList, "获取订单信息失败: ")
|
||
}
|
||
|
||
//_ = copier.CopyWithOption(&res.OrderRecords, records, copier.Option{DeepCopy: true})
|
||
|
||
for _, record := range records {
|
||
res.OrderRecords = append(res.OrderRecords, &bundle.OrderRecord{
|
||
Uuid: record.UUID,
|
||
OrderNo: record.OrderNo,
|
||
BundleUuid: record.BundleUUID,
|
||
BundleName: record.BundleName,
|
||
CustomerID: record.CustomerID,
|
||
CustomerNum: record.CustomerNum,
|
||
CustomerName: record.CustomerName,
|
||
Amount: record.Amount,
|
||
AmountType: record.AmountType,
|
||
SignContract: record.SignContract,
|
||
Signature: record.Signature,
|
||
SignedTime: record.SignedTime,
|
||
PayType: record.PayType,
|
||
PayTime: record.PayTime,
|
||
CheckoutSessionId: record.CheckoutSessionId,
|
||
CheckoutSessionUrl: record.CheckoutSessionUrl,
|
||
Status: record.Status,
|
||
ContractNo: record.ContractNo,
|
||
ValueAddBundleUuid: record.ValueAddBundleUUID,
|
||
ValueAddBundleAmount: record.ValueAddBundleAmount,
|
||
ValueAddOriginalPrice: record.ValueAddOriginalPrice,
|
||
ValueAddDiscountPrice: record.ValueAddDiscountPrice,
|
||
ValueAddSavedAmount: record.ValueAddSavedAmount,
|
||
TotalAmount: record.TotalAmount,
|
||
Num: record.Num,
|
||
BundleCommonUid: record.BundleCommonUid,
|
||
AddBundleCommonUid: record.AddBundleCommonUid,
|
||
FinancialConfirmation: record.FinancialConfirmation,
|
||
ExpirationTime: record.ExpirationTime,
|
||
})
|
||
}
|
||
|
||
var total int64
|
||
|
||
count.Count(&total)
|
||
|
||
res.Total = int32(total)
|
||
|
||
return
|
||
}
|
||
|
||
func OrderRecordDetail(req *bundle.OrderRecordsDetailRequest) (res *bundle.OrderRecord, err error) {
|
||
res = new(bundle.OrderRecord)
|
||
orderRecord := new(model.BundleOrderRecords)
|
||
|
||
query := app.ModuleClients.BundleDB.Model(&model.BundleOrderRecords{})
|
||
|
||
if req.Uuid != "" {
|
||
query = query.Where("uuid = ?", req.Uuid)
|
||
}
|
||
|
||
if req.OrderNo != "" {
|
||
query = query.Where("order_no = ?", req.OrderNo)
|
||
}
|
||
|
||
if req.CustomerID != "" {
|
||
query = query.Where("customer_id = ?", req.CustomerID)
|
||
}
|
||
|
||
err = query.First(&orderRecord).Error
|
||
if err != nil {
|
||
return res, commonErr.ReturnError(err, msg.ErrorGetOrderInfo, "获取订单信息失败: ")
|
||
}
|
||
//_ = copier.CopyWithOption(&res, orderRecord, copier.Option{DeepCopy: true})
|
||
|
||
res = &bundle.OrderRecord{
|
||
Uuid: orderRecord.UUID,
|
||
OrderNo: orderRecord.OrderNo,
|
||
BundleUuid: orderRecord.BundleUUID,
|
||
BundleName: orderRecord.BundleName,
|
||
CustomerID: orderRecord.CustomerID,
|
||
CustomerNum: orderRecord.CustomerNum,
|
||
CustomerName: orderRecord.CustomerName,
|
||
Amount: orderRecord.Amount,
|
||
AmountType: orderRecord.AmountType,
|
||
SignContract: orderRecord.SignContract,
|
||
Signature: orderRecord.Signature,
|
||
SignedTime: orderRecord.SignedTime,
|
||
PayType: orderRecord.PayType,
|
||
PayTime: orderRecord.PayTime,
|
||
CheckoutSessionId: orderRecord.CheckoutSessionId,
|
||
CheckoutSessionUrl: orderRecord.CheckoutSessionUrl,
|
||
Status: orderRecord.Status,
|
||
ContractNo: orderRecord.ContractNo,
|
||
ValueAddBundleUuid: orderRecord.ValueAddBundleUUID,
|
||
ValueAddBundleAmount: orderRecord.ValueAddBundleAmount,
|
||
TotalAmount: orderRecord.TotalAmount,
|
||
}
|
||
return
|
||
}
|
||
func PackagePriceAndTime(orderRecord *bundle.OrderRecord) (res *bundle.PackagePriceAndTimeResponse, err error) {
|
||
res = new(bundle.PackagePriceAndTimeResponse)
|
||
bundleInfo := new(model.BundleProfile)
|
||
// 查询套餐主表并预加载
|
||
err = app.ModuleClients.BundleDB.Model(&model.BundleProfile{}).
|
||
Where("uuid = ?", orderRecord.BundleUuid).
|
||
Preload("BundleToValueAddService").
|
||
Preload("BundleProfileLang", "language = ?", orderRecord.Language).
|
||
First(&bundleInfo).Error
|
||
if err != nil {
|
||
return res, commonErr.ReturnError(err, msg.ErrorBundleNotFound, "查询Bundle信息失败: ")
|
||
}
|
||
var (
|
||
valueAddAmount float64
|
||
expirationTime = "9999-12-31"
|
||
)
|
||
for _, service := range bundleInfo.BundleToValueAddService {
|
||
amount, _, _, day, e := calculateAmount(service.ValueUid, orderRecord)
|
||
if e != nil {
|
||
return res, commonErr.ReturnError(e, msg.ErrorDataConvert, "子订单金额计算失败: ")
|
||
}
|
||
if day != "" {
|
||
expirationTime = day
|
||
}
|
||
valueAddAmount = valueAddAmount + amount
|
||
}
|
||
res = &bundle.PackagePriceAndTimeResponse{
|
||
Price: float32(valueAddAmount),
|
||
Time: expirationTime,
|
||
}
|
||
return
|
||
}
|
||
func CreateOrderAddRecord(req *bundle.OrderAddRecord) (res *bundle.CommonResponse, err error) {
|
||
tx := app.ModuleClients.BundleDB.Begin()
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
tx.Rollback()
|
||
}
|
||
}()
|
||
orderNo := utils.GetOrderNo()
|
||
var childOrders []*model.BundleOrderValueAdd
|
||
for _, i := range req.AddPriceOptionsList {
|
||
childOrder := &model.BundleOrderValueAdd{
|
||
UUID: app.ModuleClients.SfNode.Generate().Base64(),
|
||
OrderUUID: req.BundleUuid, // 修正: 这里应使用主订单UUID
|
||
CustomerID: req.CustomerID,
|
||
CustomerNum: req.CustomerNum,
|
||
CustomerName: req.CustomerName,
|
||
ServiceType: i.ServiceType,
|
||
CurrencyType: i.CurrencyType,
|
||
Amount: float64(i.Amount),
|
||
OrderNo: orderNo,
|
||
Num: i.Num,
|
||
Unit: i.Unit,
|
||
ValueAddUUID: i.ValueUid,
|
||
Source: 1,
|
||
PaymentStatus: 1,
|
||
SignContract: req.SignContract,
|
||
Signature: req.Signature,
|
||
SignedTime: req.SignedTime,
|
||
}
|
||
childOrders = append(childOrders, childOrder)
|
||
|
||
// 如果是类型5服务,更新主订单的过期时间
|
||
if i.ServiceType == 5 && req.ExpirationDate != "" {
|
||
if err := tx.Model(&model.BundleOrderRecords{}).
|
||
Where("uuid = ?", req.BundleUuid).
|
||
Update("expiration_time", req.ExpirationDate).Error; err != nil {
|
||
tx.Rollback()
|
||
return nil, commonErr.ReturnError(err, msg.ErrorCreateOrderInfo, "更新主订单过期时间失败: ")
|
||
}
|
||
}
|
||
}
|
||
// 批量创建子订单(提高性能)
|
||
if err = tx.Model(&model.BundleOrderValueAdd{}).Create(childOrders).Error; err != nil {
|
||
tx.Rollback()
|
||
return res, commonErr.ReturnError(err, msg.ErrorCreateOrderInfo, "批量创建子订单失败")
|
||
}
|
||
|
||
// 提交事务
|
||
if err := tx.Commit().Error; err != nil {
|
||
tx.Rollback()
|
||
return nil, commonErr.ReturnError(err, msg.ErrorCreateOrderInfo, "提交事务失败: ")
|
||
}
|
||
|
||
return &bundle.CommonResponse{
|
||
Uuid: req.BundleUuid,
|
||
OrderNo: orderNo,
|
||
Msg: msg.SuccessCreateOrderInfo,
|
||
}, nil
|
||
}
|