446 lines
14 KiB
Go
446 lines
14 KiB
Go
package act
|
||
|
||
import (
|
||
"time"
|
||
|
||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||
"git.rosy.net.cn/jx-callback/business/partner"
|
||
"git.rosy.net.cn/jx-callback/globals"
|
||
|
||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||
"git.rosy.net.cn/jx-callback/business/model"
|
||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||
)
|
||
|
||
const (
|
||
ActionTypeNA = 0
|
||
)
|
||
|
||
type ActOrderRuleParam struct {
|
||
SalePrice int64 `orm:"" json:"salePrice"` // 满的价格
|
||
DeductPrice int64 `orm:"" json:"deductPrice"` // 减的价格
|
||
}
|
||
|
||
type ActStoreSkuParam struct {
|
||
model.ActStoreSku
|
||
|
||
Action int // -1删除,1修改,2新增
|
||
}
|
||
|
||
type ActDetail struct {
|
||
model.Act2
|
||
}
|
||
|
||
func ActStoreSkuParam2Model(ctx *jxcontext.Context, db *dao.DaoDB, act *model.Act, vendorIDs []int, actStoreSku []*ActStoreSkuParam) (validVendorIDs []int, actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap, err error) {
|
||
wholeValidVendorMap := make(map[int]int)
|
||
if len(actStoreSku) > 0 {
|
||
storeIDMap := make(map[int]int)
|
||
skuIDMap := make(map[int]int)
|
||
storeSkuParamMap := make(map[int][]*ActStoreSkuParam)
|
||
for _, v := range actStoreSku {
|
||
storeIDMap[v.StoreID] = 1
|
||
skuIDMap[v.SkuID] = 1
|
||
storeSkuParamMap[v.StoreID] = append(storeSkuParamMap[v.StoreID], v)
|
||
}
|
||
|
||
storeSkuList, err2 := dao.GetStoresSkusInfo(db, jxutils.IntMap2List(storeIDMap), jxutils.IntMap2List(skuIDMap))
|
||
if err = err2; err != nil {
|
||
return nil, nil, nil, err
|
||
}
|
||
storeSkuMap := make(map[int64]*model.StoreSkuBind)
|
||
for _, v := range storeSkuList {
|
||
storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v
|
||
}
|
||
|
||
for storeID, oneStoreSkuParam := range storeSkuParamMap {
|
||
validVendorMap := make(map[int]int)
|
||
validSkuMap := make(map[int]int)
|
||
for _, vendorID := range vendorIDs {
|
||
storeDetail, err2 := dao.GetStoreDetail(db, storeID, vendorID)
|
||
if err = err2; err == nil {
|
||
for _, v := range oneStoreSkuParam {
|
||
if storeSkuInfo := storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)]; storeSkuInfo != nil {
|
||
validVendorMap[vendorID] = 1
|
||
validSkuMap[v.SkuID] = 1
|
||
actSkuMap := &model.ActStoreSkuMap{
|
||
ActID: act.ID,
|
||
StoreID: storeID,
|
||
SkuID: v.SkuID,
|
||
VendorID: vendorID,
|
||
|
||
SyncStatus: model.SyncFlagNewMask,
|
||
}
|
||
if v.ActPrice != 0 {
|
||
actSkuMap.ActualActPrice = v.ActPrice
|
||
} else {
|
||
percentage := act.PricePercentage
|
||
if v.PricePercentage != 0 {
|
||
percentage = v.PricePercentage
|
||
}
|
||
percentage = percentage * int(storeDetail.PricePercentage) / 100
|
||
actSkuMap.ActualActPrice = int64(jxutils.CaculateSkuVendorPrice(storeSkuInfo.Price, percentage, 0))
|
||
}
|
||
dao.WrapAddIDCULDEntity(actSkuMap, ctx.GetUserName())
|
||
actStoreSkuMapList = append(actStoreSkuMapList, actSkuMap)
|
||
}
|
||
}
|
||
wholeValidVendorMap[vendorID] = 1
|
||
} else if !dao.IsNoRowsError(err) {
|
||
return nil, nil, nil, err
|
||
} else {
|
||
err = nil
|
||
}
|
||
}
|
||
|
||
for _, v := range oneStoreSkuParam {
|
||
if validSkuMap[v.SkuID] == 1 { // todo 这里是否需要判断
|
||
if storeSkuInfo := storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)]; storeSkuInfo != nil {
|
||
storeSku := &v.ActStoreSku
|
||
storeSku.ActID = act.ID
|
||
storeSku.OriginalPrice = int64(storeSkuInfo.Price)
|
||
dao.WrapAddIDCULDEntity(storeSku, ctx.GetUserName())
|
||
actStoreSkuList = append(actStoreSkuList, storeSku)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return jxutils.IntMap2List(wholeValidVendorMap), actStoreSkuList, actStoreSkuMapList, err
|
||
}
|
||
|
||
func addActStoreBind(ctx *jxcontext.Context, db *dao.DaoDB, actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap) (err error) {
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
|
||
storeSkuMap := make(map[int64]int)
|
||
for _, v := range actStoreSkuList {
|
||
err = dao.CreateEntity(db, v)
|
||
if err != nil {
|
||
dao.Rollback(db)
|
||
return err
|
||
}
|
||
storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v.ID
|
||
}
|
||
for _, v := range actStoreSkuMapList {
|
||
v.BindID = storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)]
|
||
}
|
||
|
||
if len(actStoreSkuMapList) > 0 {
|
||
err = dao.CreateMultiEntities(db, actStoreSkuMapList)
|
||
if err != nil {
|
||
dao.Rollback(db)
|
||
return err
|
||
}
|
||
}
|
||
dao.Commit(db)
|
||
return err
|
||
}
|
||
|
||
func AddActStoreBind(ctx *jxcontext.Context, actID int, actStoreSku []*ActStoreSkuParam) (err error) {
|
||
db := dao.GetDB()
|
||
var vendorIDs []int
|
||
actMap, err := dao.GetActVendorInfo(db, actID, nil)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
for vendorID := range actMap {
|
||
vendorIDs = append(vendorIDs, vendorID)
|
||
}
|
||
var act *model.Act
|
||
if len(vendorIDs) > 0 {
|
||
act = &actMap[vendorIDs[0]].Act
|
||
} else {
|
||
act = &model.Act{}
|
||
act.ID = actID
|
||
if err = dao.GetEntity(db, act); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
_, actStoreSkuList, actStoreSkuMapList, err := ActStoreSkuParam2Model(ctx, db, act, vendorIDs, actStoreSku)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
err = addActStoreBind(ctx, db, actStoreSkuList, actStoreSkuMapList)
|
||
return err
|
||
}
|
||
|
||
func CreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (actID int, err error) {
|
||
db := dao.GetDB()
|
||
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
|
||
dao.WrapAddIDCULDEntity(act, ctx.GetUserName())
|
||
err = dao.CreateEntity(db, act)
|
||
if err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
|
||
validVendorIDs, actStoreSkuList, actStoreSkuMapList, err := ActStoreSkuParam2Model(ctx, db, act, vendorIDs, actStoreSku)
|
||
if err != nil {
|
||
return 0, err
|
||
}
|
||
|
||
var actMapList []*model.ActMap
|
||
for vendorID := range validVendorIDs {
|
||
actMap := &model.ActMap{
|
||
ActID: act.ID,
|
||
VendorID: vendorID,
|
||
|
||
SyncStatus: model.SyncFlagNewMask,
|
||
}
|
||
dao.WrapAddIDCULDEntity(actMap, ctx.GetUserName())
|
||
actMapList = append(actMapList, actMap)
|
||
}
|
||
if len(actMapList) > 0 {
|
||
err = dao.CreateMultiEntities(db, actMapList)
|
||
if err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
}
|
||
|
||
if err = addActStoreBind(ctx, db, actStoreSkuList, actStoreSkuMapList); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
dao.Commit(db)
|
||
|
||
actID = act.ID
|
||
err = SyncAct(ctx, actID, nil, nil, nil)
|
||
return actID, err
|
||
}
|
||
|
||
func QueryActs(ctx *jxcontext.Context, actID int, keyword string, statusList []int, actTypeList []int, storeID, skuID int, beginAt, endAt time.Time) (actList []*model.Act, err error) {
|
||
return actList, err
|
||
}
|
||
|
||
func GetActDetail(ctx *jxcontext.Context, actID int) (actDetail *ActDetail, err error) {
|
||
return actDetail, err
|
||
}
|
||
|
||
func UpdateAct(ctx *jxcontext.Context, act *model.Act, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (err error) {
|
||
return err
|
||
}
|
||
|
||
func CancelAct(ctx *jxcontext.Context, actID int) (err error) {
|
||
db := dao.GetDB()
|
||
if err = deleteActStoreBind(ctx, db, actID, nil); err != nil {
|
||
return err
|
||
}
|
||
err = SyncAct(ctx, actID, nil, nil, nil)
|
||
return err
|
||
}
|
||
|
||
func DeleteActStoreBind(ctx *jxcontext.Context, actID int, actStoreSku []*ActStoreSkuParam) (err error) {
|
||
return deleteActStoreBind(ctx, dao.GetDB(), actID, actStoreSku)
|
||
}
|
||
|
||
func deleteActStoreBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, actStoreSkuParam []*ActStoreSkuParam) (err error) {
|
||
actMap, err := dao.GetActVendorInfo(db, actID, nil)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, nil, nil)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil || err != nil {
|
||
dao.Rollback(db)
|
||
if r != nil {
|
||
panic(r)
|
||
}
|
||
}
|
||
}()
|
||
|
||
actStoreSkuParamMap := make(map[int64]*ActStoreSkuParam)
|
||
for _, v := range actStoreSkuParam {
|
||
actStoreSkuParamMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v
|
||
if _, err = dao.DeleteEntityLogically(db, &model.ActStoreSku{}, nil, ctx.GetUserName(),
|
||
map[string]interface{}{
|
||
model.FieldActID: actID,
|
||
model.FieldStoreID: v.StoreID,
|
||
model.FieldSkuID: v.SkuID,
|
||
}); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
|
||
isNeedCancelAct := true
|
||
for vendorID, act := range actMap {
|
||
isDeleteAll := true
|
||
isDeleteAtLeastOne := false
|
||
actStoreSkuMap := partner.SplitActStoreSku(actStoreSkuMap[vendorID])
|
||
for storeID := range actStoreSkuMap {
|
||
for _, actStoreSku := range actStoreSkuMap[storeID] {
|
||
if actStoreSkuParam == nil || actStoreSkuParamMap[jxutils.Combine2Int(actStoreSku.StoreID, actStoreSku.SkuID)] != nil {
|
||
if _, err = dao.UpdateEntityLogically(db, partner.ActStoreSku2ActStoreSkuMap(actStoreSku),
|
||
map[string]interface{}{
|
||
model.FieldSyncStatus: actStoreSku.SyncStatus | model.SyncFlagDeletedMask,
|
||
}, ctx.GetUserName(), nil); err != nil {
|
||
return err
|
||
}
|
||
isDeleteAtLeastOne = true
|
||
} else {
|
||
isNeedCancelAct = false
|
||
isDeleteAll = false
|
||
}
|
||
}
|
||
}
|
||
if isDeleteAll || isDeleteAtLeastOne {
|
||
// globals.SugarLogger.Debugf("isDeleteAll:%t", isDeleteAll)
|
||
syncStatus := model.SyncFlagModifiedMask
|
||
if isDeleteAll {
|
||
syncStatus = model.SyncFlagDeletedMask
|
||
}
|
||
syncStatus |= act.SyncStatus
|
||
if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act),
|
||
map[string]interface{}{
|
||
model.FieldSyncStatus: syncStatus,
|
||
}, ctx.GetUserName(), nil); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
if isDeleteAll != isNeedCancelAct {
|
||
globals.SugarLogger.Warnf("deleteActStoreBind, actID:%d isDeleteAll:%t != isNeedCancelAct:%t", act.ID, isDeleteAll, isNeedCancelAct)
|
||
}
|
||
}
|
||
|
||
if isNeedCancelAct {
|
||
act := &model.Act{}
|
||
act.ID = actID
|
||
if _, err = dao.UpdateEntityLogically(db, act,
|
||
map[string]interface{}{
|
||
model.FieldStatus: model.ActStatusCanceled,
|
||
}, ctx.GetUserName(), nil); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
dao.Commit(db)
|
||
return err
|
||
}
|
||
|
||
func SyncAct(ctx *jxcontext.Context, actID int, vendorIDs, storeIDs, skuIDs []int) (err error) {
|
||
db := dao.GetDB()
|
||
actMap, err := dao.GetActVendorInfo(db, actID, vendorIDs)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, storeIDs, skuIDs)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
for vendorID := range actMap {
|
||
if handler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformActHandler); handler != nil {
|
||
if err = handler.SyncAct(ctx, nil, actMap[vendorID], nil, actStoreSkuMap[vendorID]); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
}
|
||
return err
|
||
// var actOrderRules []*model.ActOrderRule
|
||
// db := dao.GetDB()
|
||
// actMap, err := dao.GetActVendorInfo(db, actID, vendorIDs)
|
||
// if err != nil {
|
||
// return err
|
||
// }
|
||
// actStoreMap, err := dao.GetActStoreVendorInfo(db, actID, vendorIDs, storeIDs)
|
||
// if err != nil {
|
||
// return err
|
||
// }
|
||
// actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, vendorIDs, storeIDs, skuIDs)
|
||
// if err != nil {
|
||
// return err
|
||
// }
|
||
// var realVendorIDs []int
|
||
// for vendorID := range actMap {
|
||
// realVendorIDs = append(realVendorIDs, vendorID)
|
||
// }
|
||
|
||
// task := tasksch.NewParallelTask("SyncAct", nil, ctx,
|
||
// func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
// vendorID := batchItemList[0].(int)
|
||
// handler := partner.GetPurchasePlatformFromVendorID(vendorID)
|
||
// if handler == nil {
|
||
// err = fmt.Errorf("不被支持的vendorID:%d", vendorID)
|
||
// } else {
|
||
// act := actMap[vendorID]
|
||
// actStore := actStoreMap[vendorID]
|
||
// actStoreSku := actStoreSkuMap[vendorID]
|
||
// // globals.SugarLogger.Debugf("%s", utils.Format4Output(act, false))
|
||
// // globals.SugarLogger.Debugf("%s", utils.Format4Output(actStore, false))
|
||
// // globals.SugarLogger.Debugf("%s", utils.Format4Output(actStoreSku, false))
|
||
// if act != nil && actStore != nil && actStoreSku != nil {
|
||
// if model.IsSyncStatusNeedCreate(act.SyncStatus) {
|
||
// err = handler.CreateAct(ctx, task, act, actOrderRules, actStore, actStoreSku)
|
||
// } else if model.IsSyncStatusNeedUpdate(act.SyncStatus) {
|
||
// if act.Status == model.ActStatusCanceled {
|
||
// err = handler.CancelAct(ctx, task, act, actStore, actStoreSku)
|
||
// } else {
|
||
// // actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update := splitActStore(actStore)
|
||
// // err = handler.UpdateAct(ctx, task, act, actOrderRules, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update, actStoreSku)
|
||
// }
|
||
// }
|
||
// if err == nil {
|
||
// actMap := &model.ActMap{}
|
||
// actMap.ID = act.MapID
|
||
// dao.UpdateEntityLogically(db, actMap, map[string]interface{}{
|
||
// model.FieldSyncStatus: 0,
|
||
// model.FieldVendorActID: act.VendorActID,
|
||
// }, ctx.GetUserName(), nil)
|
||
// for _, v := range actStore {
|
||
// storeMap := model.ActStoreMap{}
|
||
// storeMap.ID = v.MapID
|
||
// dao.UpdateEntityLogically(db, storeMap, map[string]interface{}{
|
||
// model.FieldSyncStatus: 0,
|
||
// model.FieldVendorActID: v.VendorActID,
|
||
// }, ctx.GetUserName(), nil)
|
||
// }
|
||
// for _, v := range actStoreSku {
|
||
// storeSkuMap := model.ActStoreSkuMap{}
|
||
// storeSkuMap.ID = v.MapID
|
||
// dao.UpdateEntityLogically(db, storeSkuMap, map[string]interface{}{
|
||
// model.FieldSyncStatus: 0,
|
||
// model.FieldVendorActID: v.VendorActID,
|
||
// }, ctx.GetUserName(), nil)
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
// return nil, err
|
||
// }, realVendorIDs)
|
||
// tasksch.ManageTask(task).Run()
|
||
// _, err = task.GetResult(0)
|
||
return err
|
||
}
|
||
|
||
// func splitActStore(actStore []*model.ActStore2) (actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2) {
|
||
// for _, v := range actStore {
|
||
// if model.IsSyncStatusNeedDelete(v.SyncStatus) {
|
||
// if !dao.IsVendorThingIDEmpty(v.VendorActID) {
|
||
// actStoreMap2Remove = append(actStoreMap2Remove, v)
|
||
// }
|
||
// } else if model.IsSyncStatusNeedCreate(v.SyncStatus) {
|
||
// actStoreMap2Add = append(actStoreMap2Add, v)
|
||
// } else if model.IsSyncStatusNeedUpdate(v.SyncStatus) {
|
||
// actStoreMap2Update = append(actStoreMap2Update, v)
|
||
// }
|
||
// }
|
||
// return actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update
|
||
// }
|