micro-bundle/internal/logic/bundleLogic.go

365 lines
11 KiB
Go
Raw Normal View History

2025-02-20 12:40:39 +00:00
package logic
import (
2025-05-28 01:34:43 +00:00
"errors"
"fmt"
"micro-bundle/internal/dao"
"micro-bundle/pkg/app"
"micro-bundle/pkg/msg"
2025-02-20 12:40:39 +00:00
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
"github.com/jinzhu/copier"
2025-05-28 01:34:43 +00:00
"gorm.io/gorm"
2025-02-20 12:40:39 +00:00
"micro-bundle/internal/model"
"micro-bundle/pb/bundle"
)
func CreateBundle(req *bundle.BundleProfile) (res *bundle.CommonResponse, err error) {
res = new(bundle.CommonResponse)
bundleProfile := new(model.BundleProfile)
_ = copier.CopyWithOption(&bundleProfile, req, copier.Option{DeepCopy: true})
bundleProfile.UUID = utils.GetUUID()
res, err = dao.CreateBundle(bundleProfile)
return
}
func UpdateBundle(req *bundle.BundleProfile) (res *bundle.CommonResponse, err error) {
res = new(bundle.CommonResponse)
bundleProfile := new(model.BundleProfile)
_ = copier.CopyWithOption(&bundleProfile, req, copier.Option{DeepCopy: true})
res, err = dao.UpdateBundle(bundleProfile)
return
}
func DeleteBundle(req *bundle.DelBundleRequest) (res *bundle.CommonResponse, err error) {
res = new(bundle.CommonResponse)
res, err = dao.DeleteBundle(req.Uuid)
return
}
func BundleList(req *bundle.BundleListRequest) (res *bundle.BundleListResponse, err error) {
res = new(bundle.BundleListResponse)
res, err = dao.BundleList(req)
return
}
func BundleDetail(req *bundle.BundleDetailRequest) (res *bundle.BundleDetailResponse, err error) {
res = new(bundle.BundleDetailResponse)
res.Bundle = new(bundle.BundleProfile)
res.Bundle, err = dao.BundleDetail(req.Uuid)
if err != nil {
res.Msg = err.Error()
}
return
}
2025-05-28 01:34:43 +00:00
func SaveBundle(req *bundle.BundleProfile) (res *bundle.SaveResponse, err error) {
res = &bundle.SaveResponse{}
if req.Language == "" {
return res, errors.New("语言参数不能为空")
}
if req.Sort <= 0 {
return res, errors.New("排序参数需为正整数")
}
bundleProfile := &model.BundleProfile{
Name: req.Name,
Sort: req.Sort,
Content: req.Content,
Price: req.Price,
PriceType: req.PriceType,
BgImg1: req.BgImg1,
BgImg2: req.BgImg2,
ShelfStatus: 2, //默认初始状态为2-下架
}
bundleLang := &model.BundleProfileLang{
Name: req.Name,
Content: req.Content,
Price: req.Price,
PriceType: req.PriceType,
Language: req.Language,
}
if req.Uuid == "" && req.Language != msg.ZH_CN {
return res, errors.New("请先创建中文版本套餐")
}
var existValueService = make(map[string]string)
if req.Uuid != "" {
valueService, existErr := dao.GetValueAddServiceUuidsByBundleUuid(req.Uuid)
if existErr != nil {
return res, existErr
}
if valueService != nil && len(valueService) > 0 {
for _, v := range valueService {
existValueService[v] = v
}
}
}
var cancelValueAddService = make(map[string]string)
selectService := make([]*model.BundleToValueAddService, 0)
if req.Language == msg.ZH_CN && req.SelectValueAddService != nil && len(req.SelectValueAddService) > 0 {
for _, v := range req.SelectValueAddService {
detail, checkErr := dao.ValueAddServiceDetailByUuidAndLanguage(v.ValueAddUuid, req.Language)
if checkErr != nil {
if checkErr == gorm.ErrRecordNotFound {
return res, errors.New(fmt.Sprintf("所选增值服务[%s]%s版不存在,请先创建对应增值套餐", v.ServiceName, req.Language))
} else {
return res, checkErr
}
}
if detail.PriceType != req.PriceType {
if req.Uuid == "" {
2025-06-06 07:27:06 +00:00
//中文套餐创建时,币种不一致直接返回错误
2025-05-28 01:34:43 +00:00
return res, errors.New(fmt.Sprintf("所选增值服务[%s]%s币种与套餐币种不一致", detail.ServiceName, req.Language))
} else {
2025-06-06 07:27:06 +00:00
//更新时,判断是否已存在,存在则取消关联
2025-05-28 01:34:43 +00:00
_, ok := existValueService[v.ValueAddUuid]
if ok {
cancelValueAddService[v.ValueAddUuid] = detail.ServiceName
continue
} else {
2025-06-06 07:27:06 +00:00
//币种不一致,新加币种时返回错误
2025-05-28 01:34:43 +00:00
return res, errors.New(fmt.Sprintf("所选增值服务[%s]%s币种与套餐币种不一致", detail.ServiceName, req.Language))
}
}
}
selectService = append(selectService, &model.BundleToValueAddService{
ValueUid: v.ValueAddUuid,
IsDisplay: v.IsDisplay,
})
}
}
tx := app.ModuleClients.BundleDB.Begin()
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
_, err = dao.BundleDetailByUuidAndLanguage(req.Uuid, req.Language)
if err != nil {
if err == gorm.ErrRecordNotFound {
if req.Language != msg.ZH_CN {
_, err = dao.BundleDetailByUuidAndLanguage(req.Uuid, msg.ZH_CN)
if err != nil {
if err == gorm.ErrRecordNotFound {
res.Msg = "请先创建中文版本套餐"
return res, errors.New("请先创建中文版本套餐")
} else {
return res, err
}
}
}
if req.Language == msg.ZH_CN {
bundleProfile.UUID = utils.GetUUID()
if err = dao.TxCreateBundle(tx, bundleProfile); err != nil {
return res, errors.New("保存中文语言套餐失败: " + err.Error())
}
bundleLang.UUID = bundleProfile.UUID
res.Uuid = bundleProfile.UUID
// 新建套餐时插入中间表
for _, s := range selectService {
s.BundleUuid = bundleProfile.UUID
}
if len(selectService) > 0 {
if err = dao.CreateBundleToValueAddService(tx, selectService); err != nil {
return res, errors.New("保存套餐与增值服务关联失败: " + err.Error())
}
}
} else {
bundleLang.UUID = req.Uuid
res.Uuid = req.Uuid
valueUuid, err1 := dao.GetValueAddServiceUuidsByBundleUuid(bundleLang.UUID)
if err1 != nil {
return res, err1
}
count := 0
if valueUuid != nil && len(valueUuid) > 0 {
for _, v := range valueUuid {
2025-06-06 07:27:06 +00:00
//可以改成批量获取
2025-05-28 01:34:43 +00:00
valueDetail, err2 := dao.ValueAddServiceDetailByUuidAndLanguage(v, req.Language)
if err2 != nil {
return res, err2
}
if valueDetail.PriceType != req.PriceType {
if err = tx.Where("bundle_uuid =? AND value_uid =?", bundleLang.UUID, v).Delete(&model.BundleToValueAddService{}).Error; err != nil {
return res, errors.New("删除套餐与增值服务关联失败: " + err.Error())
}
count++
}
}
}
res.CancelNum = int64(count)
}
if err = dao.TxCreateBundleLang(tx, bundleLang); err != nil {
return res, errors.New("保存语言套餐失败: " + err.Error())
}
res.Msg = "保存成功"
return res, nil
} else {
return
}
2025-06-06 07:27:06 +00:00
} else { // 已存在,进行更新
// 更新前保存历史记录
// if err = dao.CreateBundleProfileHistory(tx,req.Uuid); err != nil {
// return res, errors.New("保存套餐历史记录失败: " + err.Error())
// }
2025-05-28 01:34:43 +00:00
if req.Language == msg.ZH_CN {
if len(cancelValueAddService) > 0 {
cancel := "以下增值服务:"
for _, v := range cancelValueAddService {
cancel += fmt.Sprintf("[%s]%s", v, req.Language)
if err = tx.Where("bundle_uuid = ? AND value_uid = ?", req.Uuid, v).Delete(&model.BundleToValueAddService{}).Error; err != nil {
return res, errors.New("删除套餐与增值服务关联失败: " + err.Error())
}
}
cancel += "版币种与套餐币种不一致"
res.Msg = "保存cn成功 " + cancel
}
res.CancelNum = int64(len(cancelValueAddService))
updateBundle := map[string]interface{}{
"name": req.Name,
"sort": req.Sort,
"content": req.Content,
"price": req.Price,
"price_type": req.PriceType,
"bg_img1": req.BgImg1,
"bg_img2": req.BgImg2,
}
if err = dao.TxUpdateBundle(tx, req.Uuid, updateBundle); err != nil {
return res, err
}
// 更新中间表函数
if err = diffUpdateBundleToValueAddService(tx, req.Uuid, selectService); err != nil {
tx.Rollback()
return res, err
}
2025-06-06 07:27:06 +00:00
} else {
//更新其他语言时 先获取所有关联增值服务,判断币种是否一致,不一致则取消关联
valueAddService, err := dao.GetBundleToValueAddServiceByBundleUuid(req.Uuid)
if err != nil {
return res, err
}
cancelValueService := make(map[string]string)
for _, v := range valueAddService {
detail, checkErr := dao.ValueAddServiceDetailByUuidAndLanguage(v.ValueUid, req.Language)
if checkErr != nil {
if checkErr == gorm.ErrRecordNotFound {
continue
} else {
return res, checkErr
}
}
if detail.PriceType != req.PriceType {
cancelValueService[v.ValueUid] = detail.ServiceName
continue
}
}
if int64(len(cancelValueService)) > 0 {
cancel := "以下增值服务:"
for k, v := range cancelValueService {
cancel += fmt.Sprintf("[%s]%s", v, req.Language)
if err = tx.Where("bundle_uuid = ? AND value_uid = ?", req.Uuid, k).Delete(&model.BundleToValueAddService{}).Error; err != nil {
return res, errors.New("删除套餐与增值服务关联失败: " + err.Error())
}
}
cancel += "版币种与套餐币种不一致,已取消相关关联"
res.Msg = "保存成功 " + cancel
res.CancelNum = int64(len(cancelValueService))
}
2025-05-28 01:34:43 +00:00
}
updateBundleLang := map[string]interface{}{
"name": req.Name,
"content": req.Content,
"price": req.Price,
"price_type": req.PriceType,
}
if err = dao.TxUpdateBundleLang(tx, req.Uuid, req.Language, updateBundleLang); err != nil {
return res, err
}
res.Uuid = req.Uuid
if res.Msg == "" {
res.Msg = "保存成功"
}
}
return res, nil
}
func BundleListV2(req *bundle.BundleListRequest) (res *bundle.BundleListResponse, err error) {
res = new(bundle.BundleListResponse)
res, err = dao.BundleListV2(req)
return
}
func BundleDetailV2(req *bundle.BundleDetailRequest) (res *bundle.BundleDetailResponseV2, err error) {
res = new(bundle.BundleDetailResponseV2)
if req.Uuid == "" {
2025-06-06 07:27:06 +00:00
res.Msg = ""
2025-05-28 01:34:43 +00:00
return res, errors.New("uuid不能为空")
}
if req.Language == "" {
2025-06-06 07:27:06 +00:00
res.Msg = ""
2025-05-28 01:34:43 +00:00
return res, errors.New("language不能为空")
}
res, err = dao.BundleDetailV2(req)
if err != nil {
res.Msg = err.Error()
}
return
}
func HandShelf(req *bundle.HandShelfRequest) (res *bundle.CommonResponse, err error) {
res = new(bundle.CommonResponse)
if req.ShelfStatus != 1 && req.ShelfStatus != 2 {
2025-06-06 07:27:06 +00:00
res.Msg = ""
return res, errors.New("无效的上下架状态")
2025-05-28 01:34:43 +00:00
}
res, err = dao.HandShelf(req.Uuid, req.ShelfStatus)
return
}
// 差异更新套餐与增值服务中间表
func diffUpdateBundleToValueAddService(tx *gorm.DB, bundleUuid string, selectService []*model.BundleToValueAddService) error {
oldUuids, err := dao.GetValueAddServiceUuidsByBundleUuid(bundleUuid)
if err != nil {
return errors.New("查询旧套餐与增值服务关联失败: " + err.Error())
}
newUuids := make(map[string]*model.BundleToValueAddService)
for _, s := range selectService {
newUuids[s.ValueUid] = s
}
oldSet := make(map[string]struct{})
for _, uid := range oldUuids {
oldSet[uid] = struct{}{}
}
// 需要新增的
toAdd := make([]*model.BundleToValueAddService, 0)
for uid, s := range newUuids {
if _, exist := oldSet[uid]; !exist {
s.BundleUuid = bundleUuid
toAdd = append(toAdd, s)
}
}
// 需要删除的
toDel := make([]string, 0)
for _, uid := range oldUuids {
if _, exist := newUuids[uid]; !exist {
toDel = append(toDel, uid)
}
}
if len(toDel) > 0 {
if err = tx.Where("bundle_uuid = ? AND value_uid IN ?", bundleUuid, toDel).Delete(&model.BundleToValueAddService{}).Error; err != nil {
return errors.New("删除套餐与增值服务关联失败: " + err.Error())
}
}
if len(toAdd) > 0 {
if err = dao.CreateBundleToValueAddService(tx, toAdd); err != nil {
return errors.New("保存套餐与增值服务关联失败: " + err.Error())
}
}
return nil
}