3056 lines
97 KiB
Go
3056 lines
97 KiB
Go
package cms
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"io"
|
||
"mime/multipart"
|
||
"net/http"
|
||
"regexp"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/astaxie/beego"
|
||
|
||
"git.rosy.net.cn/baseapi/platformapi/aliupcapi"
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
|
||
"git.rosy.net.cn/baseapi"
|
||
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
|
||
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
|
||
"github.com/360EntSecGroup-Skylar/excelize"
|
||
|
||
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
|
||
"git.rosy.net.cn/jx-callback/business/jxutils/excel"
|
||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||
|
||
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||
|
||
"git.rosy.net.cn/jx-callback/globals/api"
|
||
"git.rosy.net.cn/jx-callback/globals/refutil"
|
||
|
||
"git.rosy.net.cn/baseapi/utils/errlist"
|
||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||
"git.rosy.net.cn/jx-callback/business/jxutils/datares"
|
||
"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"
|
||
"git.rosy.net.cn/jx-callback/business/partner"
|
||
"git.rosy.net.cn/jx-callback/globals"
|
||
)
|
||
|
||
type SkuNamesInfo struct {
|
||
TotalCount int `json:"totalCount"`
|
||
SkuNames []*model.SkuNameExt `json:"skuNames"`
|
||
}
|
||
|
||
type CreateUpcSkuByExcelErr struct {
|
||
Upc string `json:"商品条码"`
|
||
Name string `json:"商品名称"`
|
||
Unit string `json:"单位"`
|
||
SpecQuality string `json:"重量(g)"`
|
||
Price int `json:"售价"`
|
||
Err string `json:"错误原因"`
|
||
}
|
||
|
||
var (
|
||
ErrInputCatsDoesntMatch = errors.New("输入的类别列表不合法,需要输入一个父ID下的所有子类别")
|
||
)
|
||
|
||
var (
|
||
ebaiUploadRTFShopID string // 饿百找一个店用于调用SkuUploadRTF
|
||
)
|
||
|
||
var (
|
||
sendNoCatSkusMobile = []string{
|
||
"18048531223",
|
||
"18982250714",
|
||
}
|
||
)
|
||
|
||
// func getAndSetEbaiUploadRTFShopID() (shopID string) {
|
||
// if ebaiUploadRTFShopID == "" {
|
||
// if storeDetail, err := dao.GetStoreDetail(dao.GetDB(), 0, model.VendorIDEBAI); err == nil {
|
||
// ebaiUploadRTFShopID = utils.Int2Str(storeDetail.Store.ID)
|
||
// }
|
||
// }
|
||
// return ebaiUploadRTFShopID
|
||
// }
|
||
|
||
// parentID 为-1表示所有
|
||
func GetVendorCategories(ctx *jxcontext.Context, vendorID int, parentID string) (vendorCats []*model.SkuVendorCategory, err error) {
|
||
cond := map[string]interface{}{
|
||
model.FieldVendorID: vendorID,
|
||
}
|
||
if parentID != "-1" {
|
||
cond[model.FieldParentID] = parentID
|
||
}
|
||
return vendorCats, dao.GetEntitiesByKV(nil, &vendorCats, cond, false)
|
||
}
|
||
|
||
// parentID 为-1表示所有
|
||
func GetCategories(ctx *jxcontext.Context, parentID int, isExd bool) (catList []*dao.SkuCategoryWithVendor, err error) {
|
||
db := dao.GetDB()
|
||
cats, err := dao.GetCategories(db, parentID, 0, nil, isExd)
|
||
if err == nil {
|
||
var ids []int
|
||
for _, v := range cats {
|
||
ids = append(ids, v.ID)
|
||
}
|
||
thingMapMap, err2 := dao.GetThingMapMap(db, model.ThingTypeCategory, nil, ids)
|
||
// globals.SugarLogger.Debug(utils.Format4Output(thingMapMap, false))
|
||
if err = err2; err == nil {
|
||
for _, v := range cats {
|
||
catList = append(catList, &dao.SkuCategoryWithVendor{
|
||
SkuCategory: v,
|
||
MapList: thingMapMap[int64(v.ID)],
|
||
})
|
||
}
|
||
}
|
||
}
|
||
return catList, err
|
||
}
|
||
|
||
func AddCategory(ctx *jxcontext.Context, cat *model.SkuCategory, userName string) (outCat *model.SkuCategory, err error) {
|
||
db := dao.GetDB()
|
||
if cat.Level < 0 || cat.Level > 3 {
|
||
return nil, errors.New("Level必须为1或2,3")
|
||
} else if cat.Level == 1 && cat.ParentID != 0 {
|
||
return nil, errors.New("Level1的分类其父分类必须为0")
|
||
} else if cat.Level == 2 {
|
||
if cat.ParentID == 0 {
|
||
return nil, errors.New("Level2的分类其父分类必须不为0")
|
||
}
|
||
parentCat := &model.SkuCategory{}
|
||
parentCat.ID = cat.ParentID
|
||
if err = dao.GetEntity(db, parentCat); err != nil {
|
||
return nil, err
|
||
}
|
||
if parentCat.Level != 1 {
|
||
return nil, errors.New("Level2的分类其父分类必须为Level1分类")
|
||
}
|
||
} else if cat.Level == 3 {
|
||
if cat.ParentID == 0 {
|
||
return nil, errors.New("Level3的分类其父分类必须不为0")
|
||
}
|
||
parentCat := &model.SkuCategory{}
|
||
parentCat.ID = cat.ParentID
|
||
if err = dao.GetEntity(db, parentCat); err != nil {
|
||
return nil, err
|
||
}
|
||
if parentCat.Level != 2 {
|
||
return nil, errors.New("Level3的分类其父分类必须为Level2分类")
|
||
}
|
||
}
|
||
if catsByName, err := dao.GetCategoriesByName(db, cat.Name); err == nil && len(catsByName) > 0 {
|
||
return nil, fmt.Errorf("已有分类名:[%v],分类名不允许重复!", cat.Name)
|
||
} else if err != nil {
|
||
return nil, err
|
||
}
|
||
dao.WrapAddIDCULDEntity(cat, userName)
|
||
// cat.JdSyncStatus = model.SyncFlagNewMask
|
||
// cat.JdID = 0
|
||
cat.Status = model.CategoryStatusEnable
|
||
cat.Name = strings.Trim(cat.Name, " ")
|
||
if cat.Img != "" {
|
||
_, err2 := datares.TryRegisterDataResource(ctx, cat.Name, cat.Img, model.ImgTypeLocal, false)
|
||
if err = err2; err != nil {
|
||
return nil, err
|
||
}
|
||
}
|
||
|
||
if cat.Seq <= 0 {
|
||
var maxSeq struct {
|
||
MaxSeq int
|
||
}
|
||
if err = dao.GetRow(db, &maxSeq, "SELECT MAX(seq) max_seq FROM sku_category t1 WHERE level = ?", cat.Level); err != nil {
|
||
return nil, err
|
||
}
|
||
cat.Seq = maxSeq.MaxSeq + 1
|
||
}
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if err = dao.CreateEntity(db, cat); err != nil {
|
||
dao.Rollback(db)
|
||
return nil, err
|
||
}
|
||
if cat.IsExdSpec == model.NO {
|
||
if err = OnCreateThing(ctx, db, nil, int64(cat.ID), model.ThingTypeCategory, model.SyncFlagNewMask, false); err != nil {
|
||
dao.Rollback(db)
|
||
return nil, err
|
||
}
|
||
}
|
||
dao.Commit(db)
|
||
outCat = cat
|
||
|
||
_, err = CurVendorSync.SyncCategory(ctx, nil, cat.ID, false, userName)
|
||
return outCat, err
|
||
}
|
||
|
||
func UpdateCategory(ctx *jxcontext.Context, categoryID int, payload map[string]interface{}, userName string) (num int64, err error) {
|
||
cat := &model.SkuCategory{}
|
||
cat.ID = categoryID
|
||
db := dao.GetDB()
|
||
if err = dao.GetEntity(db, cat); err != nil {
|
||
return 0, err
|
||
}
|
||
for k, v := range payload {
|
||
if v == nil {
|
||
delete(payload, k)
|
||
}
|
||
}
|
||
valid := dao.StrictMakeMapByStructObject(payload, cat, userName)
|
||
if len(valid) > 0 {
|
||
// syncStatus := 0
|
||
// if valid["name"] != nil {
|
||
// valid["name"] = strings.Trim(valid["name"].(string), " ")
|
||
// syncStatus = model.SyncFlagModifiedMask
|
||
// valid[model.FieldJdSyncStatus] = int8(syncStatus) | cat.JdSyncStatus
|
||
// }
|
||
if valid["status"] != nil {
|
||
if utils.Interface2Int64WithDefault(valid["status"], -1) == model.CategoryStatusDisabled {
|
||
if skuList, err2 := dao.GetSkuByCats(db, []int{categoryID}); err2 == nil && len(skuList) > 0 {
|
||
return 0, fmt.Errorf("暂不允许禁用分类下有商品的分类!")
|
||
}
|
||
}
|
||
}
|
||
|
||
if valid["img"] != nil {
|
||
if imgStr := utils.Interface2String(valid["img"]); imgStr != "" {
|
||
_, err2 := datares.TryRegisterDataResource(ctx, cat.Name, utils.Interface2String(valid["img"]), model.ImgTypeLocal, false)
|
||
if err = err2; err != nil {
|
||
return 0, err
|
||
}
|
||
}
|
||
}
|
||
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if num, err = dao.UpdateEntityLogically(db, cat, valid, userName, nil); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
if cat.IsExdSpec == model.NO {
|
||
if err = OnUpdateThing(ctx, db, nil, int64(categoryID), model.ThingTypeCategory); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
}
|
||
dao.Commit(db)
|
||
|
||
SetStoreCategorySyncStatus2(db, nil, []int{categoryID}, model.SyncFlagModifiedMask)
|
||
var skuIDs []int
|
||
if valid["jdCategoryID"] != nil || valid["ebaiCategoryID"] != nil || valid["mtwmCategoryID"] != nil ||
|
||
valid["jdPricePercentage"] != nil || valid["ebaiPricePercentage"] != nil || valid["mtwmPricePercentage"] != nil {
|
||
if skuList, err2 := dao.GetSkuByCats(db, []int{categoryID}); err2 == nil && len(skuList) > 0 {
|
||
for _, sku := range skuList {
|
||
skuIDs = append(skuIDs, sku.ID)
|
||
}
|
||
if valid["jdCategoryID"] != nil {
|
||
dao.SetSkuSyncStatus(db, model.VendorIDJD, skuIDs, model.SyncFlagModifiedMask)
|
||
}
|
||
|
||
// todo 如下逻辑,在不同平台同时改pricePercentage与平台分类映射时,会不必要的打上多余的标记
|
||
var vendorIDs []int
|
||
syncStatus := model.SyncFlagModifiedMask
|
||
if valid["jdPricePercentage"] != nil {
|
||
vendorIDs = append(vendorIDs, model.VendorIDJD)
|
||
syncStatus |= model.SyncFlagPriceMask
|
||
}
|
||
|
||
if valid["ebaiPricePercentage"] != nil {
|
||
vendorIDs = append(vendorIDs, model.VendorIDEBAI)
|
||
syncStatus |= model.SyncFlagPriceMask
|
||
} else if valid["ebaiCategoryID"] != nil {
|
||
vendorIDs = append(vendorIDs, model.VendorIDEBAI)
|
||
}
|
||
|
||
if valid["mtwmPricePercentage"] != nil {
|
||
vendorIDs = append(vendorIDs, model.VendorIDMTWM)
|
||
syncStatus |= model.SyncFlagPriceMask
|
||
} else if valid["mtwmCategoryID"] != nil {
|
||
vendorIDs = append(vendorIDs, model.VendorIDMTWM)
|
||
}
|
||
if len(vendorIDs) > 0 {
|
||
SetStoreSkuSyncStatus2(db, nil, vendorIDs, skuIDs, syncStatus)
|
||
}
|
||
}
|
||
}
|
||
_, err = CurVendorSync.SyncCategory(ctx, db, categoryID, false, userName)
|
||
if len(skuIDs) > 0 {
|
||
CurVendorSync.SyncSkus(ctx, db, nil, skuIDs, true, true, userName)
|
||
}
|
||
}
|
||
return num, err
|
||
}
|
||
|
||
func SetStoreCategorySyncStatus2(db *dao.DaoDB, storeIDs []int, catIDs []int, syncStatus int) (num int64, err error) {
|
||
for _, vendorID := range partner.GetSingleStoreVendorIDs() {
|
||
num2, err2 := dao.SetStoreCategorySyncStatus(db, vendorID, storeIDs, catIDs, syncStatus)
|
||
if err = err2; err != nil {
|
||
return 0, err
|
||
}
|
||
num += num2
|
||
}
|
||
return num, nil
|
||
}
|
||
|
||
func ReorderCategories(ctx *jxcontext.Context, parentID int, categoryIDs []int, userName string, isExd bool) (err error) {
|
||
var cats []*model.SkuCategory
|
||
db := dao.GetDB()
|
||
if err = dao.GetEntitiesByKV(db, &cats, utils.Params2Map(model.FieldParentID, parentID), false); err == nil {
|
||
catsLen := len(cats)
|
||
if !isExd {
|
||
for _, v := range cats {
|
||
if v.IsExdSpec == 1 {
|
||
catsLen--
|
||
}
|
||
}
|
||
}
|
||
if catsLen != len(categoryIDs) {
|
||
return ErrInputCatsDoesntMatch
|
||
}
|
||
catsMap := make(map[int]*model.SkuCategory, catsLen)
|
||
for _, cat := range cats {
|
||
catsMap[cat.ID] = cat
|
||
}
|
||
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
for k, v := range categoryIDs {
|
||
if catsMap[v] == nil {
|
||
dao.Rollback(db)
|
||
return fmt.Errorf("分类:%d不在%d分类下", v, parentID)
|
||
}
|
||
if isExd {
|
||
catsMap[v].ExdSeq = k
|
||
} else {
|
||
catsMap[v].Seq = k
|
||
}
|
||
catsMap[v].LastOperator = ctx.GetUserName()
|
||
if _, err = dao.UpdateEntity(db, catsMap[v]); err != nil {
|
||
dao.Rollback(db)
|
||
return err
|
||
}
|
||
if catsMap[v].IsExdSpec == model.NO {
|
||
if err = OnUpdateThing(ctx, db, nil, int64(catsMap[v].ID), model.ThingTypeCategory); err != nil {
|
||
dao.Rollback(db)
|
||
return err
|
||
}
|
||
}
|
||
}
|
||
dao.Commit(db)
|
||
SetStoreCategorySyncStatus2(db, nil, categoryIDs, model.SyncFlagModifiedMask)
|
||
if err == nil {
|
||
_, err = CurVendorSync.SyncReorderCategories(ctx, db, parentID, false, userName)
|
||
CurVendorSync.SyncStoresCategory(ctx, db, nil, nil, false, true, true)
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func DeleteCategory(ctx *jxcontext.Context, categoryID int, userName string) (num int64, err error) {
|
||
cat := &model.SkuCategory{}
|
||
cat.ID = categoryID
|
||
var countInfos []*struct{ Ct int }
|
||
db := dao.GetDB()
|
||
if err = dao.GetRows(db, &countInfos, `
|
||
SELECT COUNT(*) ct
|
||
FROM sku t1
|
||
WHERE t1.category_id = ? AND t1.deleted_at = ?
|
||
UNION ALL
|
||
SELECT COUNT(*) ct
|
||
FROM sku_name t1
|
||
WHERE t1.category_id = ? AND t1.deleted_at = ?
|
||
UNION ALL
|
||
SELECT COUNT(*) ct
|
||
FROM sku_category t1
|
||
WHERE t1.parent_id = ? AND t1.deleted_at = ?
|
||
`, categoryID, utils.DefaultTimeValue, categoryID, utils.DefaultTimeValue, categoryID, utils.DefaultTimeValue, &countInfos); err == nil {
|
||
if countInfos[0].Ct != 0 {
|
||
return 0, errors.New("还有商品使用此类别,不能删除")
|
||
} else if countInfos[1].Ct != 0 {
|
||
return 0, errors.New("还有商品名使用此类别,不能删除")
|
||
} else if countInfos[2].Ct != 0 {
|
||
return 0, errors.New("还有商品类别使用此类别,不能删除")
|
||
}
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if _, err = DeleteCategoryMap(ctx, db, categoryID); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
if err = OnDeleteThing(ctx, db, nil, int64(categoryID), model.ThingTypeCategory); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
if num, err = dao.DeleteEntityLogically(db, cat, map[string]interface{}{
|
||
// model.FieldJdSyncStatus: model.SyncFlagDeletedMask,
|
||
model.FieldStatus: 0,
|
||
}, userName, nil); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
dao.Commit(db)
|
||
_, err = CurVendorSync.SyncCategory(ctx, db, cat.ID, false, userName)
|
||
}
|
||
return num, err
|
||
}
|
||
|
||
func DeleteCategoryMap(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int) (num int64, err error) {
|
||
if db == nil {
|
||
db = dao.GetDB()
|
||
}
|
||
catMap := &model.StoreSkuCategoryMap{}
|
||
return dao.DeleteEntityLogically(db, catMap, map[string]interface{}{
|
||
model.FieldEbaiSyncStatus: model.SyncFlagDeletedMask,
|
||
model.FieldMtwmSyncStatus: model.SyncFlagDeletedMask,
|
||
}, ctx.GetUserName(), map[string]interface{}{
|
||
model.FieldCategoryID: categoryID,
|
||
model.FieldDeletedAt: utils.DefaultTimeValue,
|
||
})
|
||
}
|
||
|
||
func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku, isQueryMidPrice bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *SkuNamesInfo, err error) {
|
||
db := dao.GetDB()
|
||
sql := `
|
||
FROM sku_name t1
|
||
LEFT JOIN sku t2 ON t1.id = t2.name_id AND t2.deleted_at = ?
|
||
LEFT JOIN sku_name_place_bind t3 ON t1.id = t3.name_id
|
||
`
|
||
sqlParams := []interface{}{
|
||
utils.DefaultTimeValue,
|
||
}
|
||
if isQueryMidPrice {
|
||
sql += ` LEFT JOIN price_refer_snapshot t4 ON t4.city_code = ? AND t4.snapshot_at = ? AND t4.name_id = t1.id`
|
||
sqlParams = append(sqlParams, 0, utils.Time2Date(time.Now().AddDate(0, 0, -1)))
|
||
}
|
||
sql += " WHERE t1.deleted_at = ?"
|
||
sqlParams = append(sqlParams, utils.DefaultTimeValue)
|
||
if keyword != "" {
|
||
keywordLike := "%" + keyword + "%"
|
||
sql += `
|
||
AND (t1.name LIKE ? OR t1.prefix LIKE ? OR t2.comment LIKE ? OR t1.upc LIKE ? OR t1.img LIKE ?
|
||
OR (SELECT COUNT(*) FROM thing_map tm WHERE tm.vendor_thing_id LIKE ? AND tm.thing_type = ? AND tm.thing_id = t2.id AND tm.deleted_at = ?) > 0`
|
||
sqlParams = append(sqlParams,
|
||
keywordLike, keywordLike, keywordLike, keywordLike, keywordLike,
|
||
keywordLike, model.ThingTypeSku, utils.DefaultTimeValue)
|
||
if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil {
|
||
sql += " OR t1.id = ? OR t2.id = ? OR t1.category_id = ?"
|
||
sqlParams = append(sqlParams, keywordInt64, keywordInt64, keywordInt64)
|
||
}
|
||
sql += ")"
|
||
}
|
||
if params["isSpu"] != nil {
|
||
sql += " AND t1.is_spu = ?"
|
||
sqlParams = append(sqlParams, utils.Bool2Int(params["isSpu"].(bool)))
|
||
}
|
||
if params["nameID"] != nil {
|
||
sql += " AND t1.id = ?"
|
||
sqlParams = append(sqlParams, params["nameID"].(int))
|
||
}
|
||
if params["nameIDs"] != nil {
|
||
var nameIDs []int
|
||
if ids, ok := params["nameIDs"].([]int); ok {
|
||
nameIDs = ids
|
||
} else {
|
||
if err = utils.UnmarshalUseNumber([]byte(params["nameIDs"].(string)), &nameIDs); err != nil {
|
||
return nil, err
|
||
}
|
||
}
|
||
if len(nameIDs) > 0 {
|
||
sql += " AND t1.id IN (" + dao.GenQuestionMarks(len(nameIDs)) + ")"
|
||
sqlParams = append(sqlParams, nameIDs)
|
||
}
|
||
}
|
||
if params["categoryID"] != nil {
|
||
cat := &model.SkuCategory{}
|
||
cat.ID = params["categoryID"].(int)
|
||
if err = dao.GetEntity(db, cat); err != nil {
|
||
return nil, err
|
||
}
|
||
sql += " AND (t1.category_id = ?"
|
||
sqlParams = append(sqlParams, cat.ID)
|
||
if cat.Level == 1 {
|
||
sql += " OR t1.category_id IN (SELECT id FROM sku_category WHERE parent_id = ?)"
|
||
sqlParams = append(sqlParams, cat.ID)
|
||
}
|
||
sql += ")"
|
||
}
|
||
if params["isExd"] != nil {
|
||
var idExd = params["isExd"].(bool)
|
||
if idExd {
|
||
sql += " AND t2.exd_sku_id <> ''"
|
||
} else {
|
||
sql += " AND t2.exd_sku_id = ''"
|
||
}
|
||
} else {
|
||
sql += " AND t2.exd_sku_id = ''"
|
||
}
|
||
if params["skuCategoryID"] != nil {
|
||
cat := &model.SkuCategory{}
|
||
cat.ID = params["skuCategoryID"].(int)
|
||
if err = dao.GetEntity(db, cat); err != nil {
|
||
return nil, err
|
||
}
|
||
sql += " AND (t2.category_id = ?"
|
||
sqlParams = append(sqlParams, cat.ID)
|
||
if cat.Level == 1 {
|
||
sql += " OR t2.category_id IN (SELECT id FROM sku_category WHERE parent_id = ?)"
|
||
sqlParams = append(sqlParams, cat.ID)
|
||
}
|
||
sql += ")"
|
||
}
|
||
if params["vendorSkuIDs"] != nil {
|
||
var vendorSkuIDs []int
|
||
if err = utils.UnmarshalUseNumber([]byte(params["vendorSkuIDs"].(string)), &vendorSkuIDs); err != nil {
|
||
return nil, err
|
||
}
|
||
if len(vendorSkuIDs) > 0 {
|
||
sql += " AND (SELECT COUNT(*) FROM thing_map tm WHERE tm.thing_type = ? AND tm.thing_id = t2.id AND tm.deleted_at = ? AND tm.vendor_thing_id IN (" + dao.GenQuestionMarks(len(vendorSkuIDs)) + ")) > 0"
|
||
sqlParams = append(sqlParams, utils.DefaultTimeValue, vendorSkuIDs)
|
||
}
|
||
}
|
||
if params["name"] != nil {
|
||
sql += " AND t1.name LIKE ?"
|
||
sqlParams = append(sqlParams, "%"+params["name"].(string)+"%")
|
||
}
|
||
if params["prefix"] != nil {
|
||
sql += " AND t1.prefix LIKE ?"
|
||
sqlParams = append(sqlParams, "%"+params["prefix"].(string)+"%")
|
||
}
|
||
if params["unit"] != nil {
|
||
sql += " AND t1.unit = ?"
|
||
sqlParams = append(sqlParams, params["unit"].(string))
|
||
}
|
||
if placeCond := strings.ToUpper(utils.Interface2String(params["placeCond"])); placeCond == "AND" || placeCond == "OR" {
|
||
sqlPlaceCond := ""
|
||
if placeCond == "AND" {
|
||
sqlPlaceCond += " AND ( 1 = 1"
|
||
} else {
|
||
sqlPlaceCond += " AND ( 1 = 0"
|
||
}
|
||
if params["placeCode"] != nil {
|
||
sqlPlaceCond += " " + placeCond + " t3.place_code = ?"
|
||
sqlParams = append(sqlParams, params["placeCode"].(int))
|
||
}
|
||
if params["isGlobal"] != nil {
|
||
if params["isGlobal"].(bool) {
|
||
sqlPlaceCond += " " + placeCond + " t1.is_global = 1"
|
||
} else {
|
||
sqlPlaceCond += " " + placeCond + " t1.is_global = 0"
|
||
}
|
||
}
|
||
if sqlPlaceCond != " AND ( 1 = 0" {
|
||
sql += sqlPlaceCond + ")"
|
||
}
|
||
}
|
||
if params["skuID"] != nil {
|
||
sql += " AND t2.id = ?"
|
||
sqlParams = append(sqlParams, params["skuID"].(int))
|
||
}
|
||
if params["skuIDs"] != nil {
|
||
var skuIDs []int
|
||
if err = utils.UnmarshalUseNumber([]byte(params["skuIDs"].(string)), &skuIDs); err != nil {
|
||
return nil, err
|
||
}
|
||
if len(skuIDs) > 0 {
|
||
sql += " AND t2.id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")"
|
||
sqlParams = append(sqlParams, skuIDs)
|
||
}
|
||
}
|
||
if params["fromStatus"] != nil {
|
||
fromStatus := params["fromStatus"].(int)
|
||
toStatus := fromStatus
|
||
if params["toStatus"] != nil {
|
||
toStatus = params["toStatus"].(int)
|
||
}
|
||
sql += " AND t2.status >= ? AND t2.status <= ?"
|
||
sqlParams = append(sqlParams, fromStatus, toStatus)
|
||
}
|
||
sqlData := `
|
||
SELECT
|
||
SQL_CALC_FOUND_ROWS
|
||
DISTINCT
|
||
t1.id,
|
||
t1.created_at,
|
||
t1.updated_at,
|
||
t1.last_operator,
|
||
t1.deleted_at,
|
||
t1.prefix,
|
||
t1.name,
|
||
t1.brand_id,
|
||
t1.category_id,
|
||
t1.jd_category_id,
|
||
t1.is_global,
|
||
t1.unit,
|
||
t1.price,
|
||
t1.img,
|
||
t1.img2,
|
||
t1.img3,
|
||
t1.img_watermark,
|
||
t1.img_mix,
|
||
t1.status,
|
||
t1.is_spu,
|
||
t1.desc_img,
|
||
t1.upc,
|
||
t1.ex_prefix,
|
||
t1.ex_prefix_begin,
|
||
t1.ex_prefix_end,
|
||
t1.yb_name_suffix,
|
||
t1.jds_stock_switch,
|
||
t1.preparation_time,
|
||
t1.best_seller
|
||
`
|
||
if isBySku {
|
||
sqlData += " ,t2.id sku_id"
|
||
}
|
||
if isQueryMidPrice {
|
||
sqlData += ",t4.mid_unit_price"
|
||
}
|
||
sqlData += sql + `
|
||
ORDER BY t1.id DESC
|
||
LIMIT ? OFFSET ?`
|
||
pageSize = jxutils.FormalizePageSize(pageSize)
|
||
offset = jxutils.FormalizePageOffset(offset)
|
||
sqlParams = append(sqlParams, pageSize, offset)
|
||
skuNamesInfo = &SkuNamesInfo{}
|
||
dao.Begin(db) // todo 这里用事务的原因是,SQL_CALC_FOUND_ROWS会出错
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if err = dao.GetRows(db, &skuNamesInfo.SkuNames, sqlData, sqlParams...); err == nil {
|
||
skuNamesInfo.TotalCount = dao.GetLastTotalRowCount(db)
|
||
dao.Commit(db)
|
||
|
||
// var skuIDs []int
|
||
for _, skuName := range skuNamesInfo.SkuNames {
|
||
skuName.FullName = jxutils.ComposeSkuName(skuName.Prefix, skuName.Name, "", "", 0, "", 0, skuName.ExPrefix, skuName.ExPrefixBegin, skuName.ExPrefixEnd)
|
||
// if skuName.SkusStr != "" {
|
||
// if err = utils.UnmarshalUseNumber([]byte(skuName.SkusStr), &skuName.Skus); err != nil {
|
||
// dao.Rollback(db)
|
||
// return nil, err
|
||
// }
|
||
// for _, v := range skuName.Skus {
|
||
// skuIDs = append(skuIDs, v.ID)
|
||
// }
|
||
// }
|
||
// if skuName.PlacesStr != "" {
|
||
// if err = utils.UnmarshalUseNumber([]byte(skuName.PlacesStr), &skuName.Places); err != nil {
|
||
// dao.Rollback(db)
|
||
// return nil, err
|
||
// }
|
||
// }
|
||
skuVendorCats, _ := dao.GetSkuVendorCategoryMaps(db, []int{skuName.ID}, []int{model.VendorIDMTWM, model.VendorIDEBAI, model.VendorIDJDShop, model.VendorIDJD}, nil)
|
||
if len(skuVendorCats) > 0 {
|
||
for _, v := range skuVendorCats {
|
||
if v.VendorID == model.VendorIDJD {
|
||
skuName.JdCategoryID = v.VendorCategoryID
|
||
}
|
||
if v.VendorID == model.VendorIDEBAI {
|
||
skuName.EbaiCategoryID = v.VendorCategoryID
|
||
}
|
||
if v.VendorID == model.VendorIDMTWM {
|
||
skuName.MtwmCategoryID = v.VendorCategoryID
|
||
}
|
||
if v.VendorID == model.VendorIDJDShop {
|
||
skuName.JdsCategoryID = v.VendorCategoryID
|
||
}
|
||
}
|
||
}
|
||
var (
|
||
skus []*model.Sku
|
||
sqlParams = []interface{}{utils.DefaultTimeValue}
|
||
sql string
|
||
)
|
||
if !isBySku {
|
||
sql = `
|
||
SELECT * FROM sku WHERE deleted_at = ? AND name_id = ?
|
||
`
|
||
sqlParams = append(sqlParams, skuName.ID)
|
||
} else {
|
||
sql = `
|
||
SELECT * FROM sku WHERE deleted_at = ? AND id = ?
|
||
`
|
||
sqlParams = append(sqlParams, skuName.SkuID)
|
||
}
|
||
if err = dao.GetRows(db, &skus, sql, sqlParams); err == nil {
|
||
var skusVendors []*model.SkuWithVendor
|
||
for _, v := range skus {
|
||
skusVendor := &model.SkuWithVendor{
|
||
Sku: v,
|
||
}
|
||
skusVendors = append(skusVendors, skusVendor)
|
||
}
|
||
skuName.Skus = skusVendors
|
||
// thingMapMap, err2 := dao.GetThingMapMap(db, model.ThingTypeSku, nil, nil)
|
||
// if err = err2; err == nil {
|
||
// for _, skuName := range skuNamesInfo.SkuNames {
|
||
// for _, v := range skuName.Skus {
|
||
// v.MapList = thingMapMap[int64(v.ID)]
|
||
// }
|
||
// }
|
||
// }
|
||
}
|
||
var (
|
||
places []*model.SkuNamePlaceBind
|
||
placeCodes []int
|
||
)
|
||
sql2 := `
|
||
SELECT * FROM sku_name_place_bind WHERE name_id = ?
|
||
`
|
||
sqlParams2 := []interface{}{skuName.ID}
|
||
if err = dao.GetRows(db, &places, sql2, sqlParams2); err == nil {
|
||
for _, v := range places {
|
||
placeCodes = append(placeCodes, v.PlaceCode)
|
||
}
|
||
skuName.Places = placeCodes
|
||
}
|
||
}
|
||
} else {
|
||
dao.Rollback(db)
|
||
}
|
||
return skuNamesInfo, err
|
||
}
|
||
|
||
func CheckHasSensitiveWord(word string) (bool, string) {
|
||
if hasSensitiveWord, sensitiveWord := IsSensitiveWordInList(word); hasSensitiveWord {
|
||
return true, sensitiveWord
|
||
}
|
||
|
||
return false, ""
|
||
}
|
||
|
||
func IsSensitiveWordInList(str string) (bool, string) {
|
||
wordList, err := dao.GetSensitiveWordList(-1)
|
||
if err == nil {
|
||
for _, value := range wordList {
|
||
keyWord := value.Word
|
||
if value.VendorID != -2 {
|
||
checkHas := strings.Contains(str, keyWord)
|
||
if checkHas {
|
||
return true, keyWord
|
||
}
|
||
} else {
|
||
var index int
|
||
for index > 0 {
|
||
index = strings.Index(keyWord, ",")
|
||
keyWord = keyWord[:index-1]
|
||
globals.SugarLogger.Debug("keyWord", keyWord)
|
||
checkHas := strings.Contains(str, keyWord)
|
||
if checkHas {
|
||
return true, keyWord
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
return false, ""
|
||
}
|
||
|
||
func AddSkuName(ctx *jxcontext.Context, skuNameExt *model.SkuNameExt, userName string) (outSkuNameExt *model.SkuNameExt, err error) {
|
||
if skuNameExt.CategoryID == 0 {
|
||
return nil, errors.New("CategoryID不能为空")
|
||
}
|
||
if len(skuNameExt.Skus) == 0 {
|
||
return nil, errors.New("创建SKU NAME时必须至少创建一个SKU")
|
||
} else if skuNameExt.Unit != model.SpecialUnit {
|
||
if len(skuNameExt.Skus) != 1 {
|
||
return nil, errors.New("不为份的SKU NAME只能有一个SKU")
|
||
}
|
||
}
|
||
|
||
skuNameExt.Name = utils.TrimBlankChar(skuNameExt.Name)
|
||
if hasSensitiveWord, word := CheckHasSensitiveWord(skuNameExt.Name); hasSensitiveWord {
|
||
skuNameExt.Name = strings.ReplaceAll(skuNameExt.Name, word, "")
|
||
}
|
||
upc := utils.Pointer2String(skuNameExt.Upc)
|
||
if upc == "" {
|
||
skuNameExt.Upc = nil
|
||
} else if !jxutils.IsUpcValid(upc) {
|
||
return nil, fmt.Errorf("upc:%s不合法,请仔细检查", upc)
|
||
}
|
||
|
||
db := dao.GetDB()
|
||
skuNameExt.SkuName.Status = model.SkuStatusNormal
|
||
if skuNameExt.IsSpu == 1 {
|
||
return nil, fmt.Errorf("不允许创建多规格商品")
|
||
// skuNameExt.SkuName.JdSyncStatus = model.SyncFlagNewMask
|
||
}
|
||
if skuNameExt.Unit == model.SpecialUnit {
|
||
skuNameExt.SpecQuality = float32(model.SpecialSpecQuality)
|
||
skuNameExt.SpecUnit = model.SpecialSpecUnit
|
||
} else {
|
||
skuNameExt.SpecQuality = skuNameExt.Skus[0].SpecQuality
|
||
skuNameExt.SpecUnit = skuNameExt.Skus[0].SpecUnit
|
||
}
|
||
|
||
if skuNameExt.YbNameSuffix == "" {
|
||
var name *model.SkuName
|
||
sql := "SELECT * FROM sku_name WHERE yb_name_suffix <> '' ORDER BY yb_name_suffix DESC LIMIT 1"
|
||
dao.GetRow(db, &name, sql, nil)
|
||
if name != nil {
|
||
if skuNameExt.Unit == model.UnitNames[0] {
|
||
prefix := utils.Int64ToStr(utils.Str2Int64(name.YbNameSuffix) + 1)
|
||
realPrefix := prefix
|
||
for i := 0; i < 4-len(prefix); i++ {
|
||
realPrefix = "0" + realPrefix
|
||
}
|
||
skuNameExt.YbNameSuffix = realPrefix
|
||
if utils.Str2Int64(prefix) > 9999 {
|
||
return nil, fmt.Errorf("银豹的商品后缀已超过9999!")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
picType := true
|
||
for _, imgName := range []string{skuNameExt.Img, skuNameExt.Img2, skuNameExt.Img3, skuNameExt.Img4, skuNameExt.Img5} {
|
||
if imgName != "" {
|
||
dataRes, err2 := datares.TryRegisterDataResource(ctx, skuNameExt.Name, imgName, model.ImgTypeMain, false)
|
||
if err = err2; err != nil {
|
||
return nil, err
|
||
}
|
||
if dataRes.ResourceType == model.MimeTypeJpeg || dataRes.ResourceType == model.MimeTypePng {
|
||
picType = false
|
||
}
|
||
}
|
||
}
|
||
|
||
if picType {
|
||
return nil, fmt.Errorf("商品图片应至少包含一张非gif格式的图片!")
|
||
}
|
||
|
||
if skuNameExt.DescImg != "" {
|
||
dataRes, err2 := datares.TryRegisterDataResource(ctx, skuNameExt.Name+"desc", skuNameExt.DescImg, model.ImgTypeDesc, false)
|
||
if err = err2; err != nil {
|
||
return nil, err
|
||
}
|
||
if dataRes.ResourceType == model.MimeTypeGif {
|
||
return nil, fmt.Errorf("商品详情图片不能上传gif格式的图片!")
|
||
}
|
||
}
|
||
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
dao.WrapAddIDCULDEntity(&skuNameExt.SkuName, userName)
|
||
if err = dao.CreateEntity(db, &skuNameExt.SkuName); err != nil {
|
||
dao.Rollback(db)
|
||
return nil, err
|
||
}
|
||
if err = OnCreateThing(ctx, db, nil, int64(skuNameExt.SkuName.ID), model.ThingTypeSkuName, model.SyncFlagNewMask, false); err != nil {
|
||
dao.Rollback(db)
|
||
return nil, err
|
||
}
|
||
for _, v := range skuNameExt.Skus {
|
||
sku := v.Sku
|
||
dao.WrapAddIDCULDEntity(sku, userName)
|
||
sku.NameID = skuNameExt.ID
|
||
if beego.BConfig.RunMode == "jxgy" {
|
||
sku.LadderBoxPrice = 0
|
||
} else if beego.BConfig.RunMode == "prod" {
|
||
sku.LadderBoxPrice = 10
|
||
}
|
||
sku.LadderBoxNum = 1
|
||
if err = dao.CreateEntity(db, sku); err != nil {
|
||
dao.Rollback(db)
|
||
return nil, err
|
||
}
|
||
if sku.EclpID == "" {
|
||
if err = OnCreateThing(ctx, db, nil, int64(sku.ID), model.ThingTypeSku, 0, false); err != nil {
|
||
dao.Rollback(db)
|
||
return nil, err
|
||
}
|
||
}
|
||
}
|
||
for _, placeCode := range skuNameExt.Places {
|
||
placeBind := &model.SkuNamePlaceBind{}
|
||
dao.WrapAddIDCULEntity(placeBind, userName)
|
||
placeBind.NameID = skuNameExt.ID
|
||
placeBind.PlaceCode = placeCode
|
||
if err = dao.CreateEntity(db, placeBind); err != nil {
|
||
dao.Rollback(db)
|
||
return nil, err
|
||
}
|
||
}
|
||
dao.Commit(db)
|
||
|
||
tmpInfo, err := GetSkuNames(ctx, "", false, false, utils.Params2Map("nameID", skuNameExt.SkuName.ID), 0, 1)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
if tmpInfo.TotalCount != 1 {
|
||
return nil, ErrEntityNotExist
|
||
}
|
||
outSkuNameExt = tmpInfo.SkuNames[0]
|
||
_, err = CurVendorSync.SyncSku(ctx, db, outSkuNameExt.SkuName.ID, -1, false, false, userName)
|
||
|
||
updateOrCreateSkuVendorCategoryMap(db, ctx, outSkuNameExt.SkuName.ID, nil, skuNameExt, false)
|
||
return outSkuNameExt, err
|
||
}
|
||
|
||
func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interface{}, isExd bool) (num int64, err error) {
|
||
userName := ctx.GetUserName()
|
||
skuName := &model.SkuName{}
|
||
skuName.ID = nameID
|
||
db := dao.GetDB()
|
||
if err = dao.GetEntity(db, skuName); err != nil {
|
||
return 0, err
|
||
}
|
||
var beforSkuName = *skuName
|
||
if payload["name"] != nil {
|
||
newSkuName := utils.TrimBlankChar(utils.Interface2String(payload["name"]))
|
||
if hasSensitiveWord, word := CheckHasSensitiveWord(newSkuName); hasSensitiveWord {
|
||
payload["name"] = strings.ReplaceAll(payload["name"].(string), word, "")
|
||
} else {
|
||
payload["name"] = newSkuName
|
||
}
|
||
}
|
||
|
||
delete(payload, "isSpu")
|
||
delete(payload, "seq")
|
||
|
||
valid := dao.StrictMakeMapByStructObject(payload, skuName, userName)
|
||
valid = utils.RemoveGeneralMapKeys(valid, model.FieldSpecQuality, model.FieldSpecUnit)
|
||
_, hasPlaces := payload["places"]
|
||
flag := updateOrCreateSkuVendorCategoryMap(db, ctx, nameID, payload, nil, false)
|
||
if len(valid) > 0 || hasPlaces || flag {
|
||
if valid["Upc"] != nil {
|
||
if upc, _ := valid["Upc"].(string); upc == "" {
|
||
valid["Upc"] = nil
|
||
} else if !jxutils.IsUpcValid(upc) {
|
||
return 0, fmt.Errorf("upc:%s不合法,请仔细检查", upc)
|
||
}
|
||
}
|
||
globals.SugarLogger.Debugf("UpdateSkuName valid:%s", utils.Format4Output(valid, false))
|
||
for _, imgName := range []string{"img", "img2", "img3", "img4", "img5"} {
|
||
if valid[imgName] != nil {
|
||
if imgStr := utils.Interface2String(valid[imgName]); imgStr != "" {
|
||
_, err2 := datares.TryRegisterDataResource(ctx, skuName.Name, valid[imgName].(string), model.ImgTypeMain, true)
|
||
if err = err2; err != nil {
|
||
return 0, err
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if valid["descImg"] != nil {
|
||
descImg := valid["descImg"].(string)
|
||
if descImg != "" {
|
||
_, err2 := datares.TryRegisterDataResource(ctx, skuName.Name+"_desc", descImg, model.ImgTypeDesc, false)
|
||
if err = err2; err != nil {
|
||
return 0, err
|
||
}
|
||
}
|
||
}
|
||
var eclpID string
|
||
if payload["eclpID"] != nil {
|
||
eclpID = payload["eclpID"].(string)
|
||
}
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
// valid[model.FieldJdSyncStatus] = model.SyncFlagModifiedMask | skuName.JdSyncStatus
|
||
if num, err = dao.UpdateEntityLogically(db, skuName, valid, userName, nil); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
if !isExd && eclpID == "" {
|
||
if err = OnUpdateThing(ctx, db, nil, int64(nameID), model.ThingTypeSkuName); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
}
|
||
if utils.Interface2Int64WithDefault(payload["isGlobal"], 0) == 0 && payload["places"] != nil {
|
||
if places, ok := payload["places"].([]interface{}); ok {
|
||
if _, err = dao.DeleteSkuNamePlace(db, nameID, nil); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
for _, placeCode := range places {
|
||
placeBind := &model.SkuNamePlaceBind{}
|
||
placeBind.PlaceCode = int(utils.Interface2Int64WithDefault(placeCode, 0))
|
||
if placeBind.PlaceCode > 0 {
|
||
dao.WrapAddIDCULEntity(placeBind, userName)
|
||
placeBind.NameID = nameID
|
||
err = dao.CreateEntity(db, placeBind)
|
||
} else {
|
||
dao.Rollback(db)
|
||
return 0, errors.New("地点代码非法")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
skuList, err2 := dao.GetSkus(db, nil, []int{nameID}, nil, nil, nil)
|
||
if err = err2; err == nil {
|
||
for _, v := range skuList {
|
||
sku := &v.Sku
|
||
// sku.JdSyncStatus |= model.SyncFlagModifiedMask
|
||
sku.LastOperator = userName
|
||
sku.UpdatedAt = time.Now()
|
||
if _, err = dao.UpdateEntity(db, sku); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
if sku.ExdSkuID == "" && sku.EclpID == "" {
|
||
if err = OnUpdateThing(ctx, db, nil, int64(v.ID), model.ThingTypeSku); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
}
|
||
}
|
||
}
|
||
skuIDs, err2 := dao.GetSkuIDByNames(db, []int{nameID})
|
||
if err = err2; err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
if len(skuIDs) > 0 {
|
||
if _, err = SetStoreSkuSyncStatus2(db, nil, partner.GetSingleStoreVendorIDs(), skuIDs, model.SyncFlagModifiedMask); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
if valid["jdsStockSwitch"] != nil {
|
||
if _, err = SetStoreSkuSyncStatus2(db, []int{model.JdShopMainStoreID}, []int{model.VendorIDJDShop}, skuIDs, model.SyncFlagSaleMask); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
}
|
||
}
|
||
dao.Commit(db)
|
||
|
||
errList := errlist.New()
|
||
errList.AddErr(err)
|
||
_, err = CurVendorSync.SyncSku(ctx, db, nameID, -1, false, false, userName)
|
||
errList.AddErr(err)
|
||
err = errList.GetErrListAsOne()
|
||
if globals.IsAddEvent {
|
||
mapBefore := refutil.FindMapAndStructMixed(valid, beforSkuName)
|
||
err = AddEventDetail(db, ctx, model.OperateUpdate, nameID, model.ThingTypeSkuName, 0, BuildDiffData(mapBefore), BuildDiffData(valid))
|
||
}
|
||
}
|
||
return num, err
|
||
}
|
||
|
||
func updateOrCreateSkuVendorCategoryMap(db *dao.DaoDB, ctx *jxcontext.Context, nameID int, payload map[string]interface{}, skuNameExt *model.SkuNameExt, isDelete bool) (flag bool) {
|
||
if isDelete {
|
||
skuVendorCatMaps, _ := dao.GetSkuVendorCategoryMaps(db, []int{nameID}, nil, nil)
|
||
for _, v := range skuVendorCatMaps {
|
||
v.DeletedAt = time.Now()
|
||
v.LastOperator = ctx.GetUserName()
|
||
dao.UpdateEntity(db, v, "DeletedAt", "LastOperator")
|
||
}
|
||
flag = true
|
||
} else {
|
||
updateOrCreate := func(vendorID, nameID int, vendorCatID string) {
|
||
skuVendorCatMaps, _ := dao.GetSkuVendorCategoryMaps(db, []int{nameID}, []int{vendorID}, nil)
|
||
if len(skuVendorCatMaps) > 0 {
|
||
skuVendorCatMaps[0].VendorCategoryID = vendorCatID
|
||
dao.UpdateEntity(db, skuVendorCatMaps[0], "VendorCategoryID")
|
||
} else {
|
||
skuVendorCatMap := &model.SkuVendorCategoryMap{
|
||
NameID: nameID,
|
||
VendorID: vendorID,
|
||
VendorCategoryID: vendorCatID,
|
||
}
|
||
dao.WrapAddIDCULDEntity(skuVendorCatMap, ctx.GetUserName())
|
||
dao.CreateEntity(db, skuVendorCatMap)
|
||
}
|
||
}
|
||
if skuNameExt != nil {
|
||
if skuNameExt.JdCategoryID != "" {
|
||
updateOrCreate(model.VendorIDJD, nameID, skuNameExt.JdCategoryID)
|
||
flag = true
|
||
}
|
||
if skuNameExt.JdsCategoryID != "" {
|
||
updateOrCreate(model.VendorIDJDShop, nameID, skuNameExt.JdsCategoryID)
|
||
flag = true
|
||
}
|
||
if skuNameExt.EbaiCategoryID != "" {
|
||
updateOrCreate(model.VendorIDEBAI, nameID, skuNameExt.EbaiCategoryID)
|
||
flag = true
|
||
}
|
||
if skuNameExt.MtwmCategoryID != "" {
|
||
updateOrCreate(model.VendorIDMTWM, nameID, skuNameExt.MtwmCategoryID)
|
||
flag = true
|
||
}
|
||
} else {
|
||
if payload["jdCategoryID"] != nil {
|
||
updateOrCreate(model.VendorIDJD, nameID, payload["jdCategoryID"].(string))
|
||
flag = true
|
||
}
|
||
if payload["jdsCategoryID"] != nil {
|
||
updateOrCreate(model.VendorIDJDShop, nameID, payload["jdsCategoryID"].(string))
|
||
flag = true
|
||
}
|
||
if payload["ebaiCategoryID"] != nil {
|
||
updateOrCreate(model.VendorIDEBAI, nameID, payload["ebaiCategoryID"].(string))
|
||
flag = true
|
||
}
|
||
if payload["mtwmCategoryID"] != nil {
|
||
updateOrCreate(model.VendorIDMTWM, nameID, payload["mtwmCategoryID"].(string))
|
||
flag = true
|
||
}
|
||
}
|
||
}
|
||
return flag
|
||
}
|
||
|
||
func SetStoreSkuSyncStatus2(db *dao.DaoDB, storeIDs []int, vendorIDs, skuIDs []int, syncStatus int) (num int64, err error) {
|
||
for _, vendorID := range vendorIDs {
|
||
num2, err2 := dao.SetStoreSkuSyncStatus(db, vendorID, storeIDs, skuIDs, syncStatus)
|
||
if err = err2; err != nil {
|
||
return 0, err
|
||
}
|
||
num += num2
|
||
}
|
||
return num, nil
|
||
}
|
||
|
||
func DeleteSkuName(ctx *jxcontext.Context, nameID int, userName string) (num int64, err error) {
|
||
db := dao.GetDB()
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
|
||
if _, err := dao.DeleteSkuNamePlace(db, nameID, nil); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
if _, err = DeleteStoreSku(ctx, db, nameID, 0); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
|
||
skuList, err2 := dao.GetSkus(db, nil, []int{nameID}, nil, nil, nil)
|
||
if err = err2; err == nil {
|
||
for _, v := range skuList {
|
||
sku := &v.Sku
|
||
if err = OnDeleteThing(ctx, db, nil, int64(v.ID), model.ThingTypeSku); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
if _, err = dao.DeleteEntityLogically(db, sku, map[string]interface{}{
|
||
// model.FieldJdSyncStatus: model.SyncFlagDeletedMask,
|
||
model.FieldStatus: model.SkuStatusDeleted,
|
||
}, userName, nil); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
}
|
||
}
|
||
|
||
if err = OnDeleteThing(ctx, db, nil, int64(nameID), model.ThingTypeSkuName); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
|
||
skuName := &model.SkuName{}
|
||
skuName.ID = nameID
|
||
if num, err = dao.DeleteEntityLogically(db, skuName, map[string]interface{}{
|
||
// model.FieldJdSyncStatus: model.SyncFlagDeletedMask,
|
||
model.FieldStatus: model.SkuStatusDeleted,
|
||
}, userName, nil); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
dao.Commit(db)
|
||
|
||
if len(skuList) > 0 {
|
||
_, err = CurVendorSync.SyncSku(ctx, db, skuName.ID, -1, false, false, userName)
|
||
}
|
||
updateOrCreateSkuVendorCategoryMap(db, ctx, nameID, nil, nil, true)
|
||
return num, err
|
||
}
|
||
|
||
func AddSku(ctx *jxcontext.Context, nameID int, sku *model.Sku, userName string) (outSkuNameExt *model.SkuNameExt, err error) {
|
||
db := dao.GetDB()
|
||
skuName := &model.SkuName{}
|
||
skuName.ID = nameID
|
||
if err = dao.GetEntity(db, skuName); err != nil {
|
||
return nil, err
|
||
}
|
||
if skuName.Unit != model.SpecialUnit {
|
||
return nil, errors.New("不为份的SKU NAME只能有一个SKU")
|
||
}
|
||
|
||
dao.WrapAddIDCULDEntity(sku, userName)
|
||
// sku.JdSyncStatus = model.SyncFlagNewMask
|
||
// sku.JdID = 0
|
||
sku.NameID = nameID
|
||
if beego.BConfig.RunMode == "jxgy" {
|
||
sku.LadderBoxPrice = 0
|
||
} else if beego.BConfig.RunMode == "prod" {
|
||
sku.LadderBoxPrice = 10
|
||
}
|
||
sku.LadderBoxNum = 1
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if err = dao.CreateEntity(db, sku); err != nil {
|
||
dao.Rollback(db)
|
||
return nil, err
|
||
}
|
||
if err = OnCreateThing(ctx, db, nil, int64(sku.ID), model.ThingTypeSku, 0, false); err != nil {
|
||
dao.Rollback(db)
|
||
return nil, err
|
||
}
|
||
dao.Commit(db)
|
||
|
||
result, err2 := GetSkuNames(ctx, "", false, false, utils.Params2Map("skuID", sku.ID), 0, 0)
|
||
if err = err2; err == nil {
|
||
if result.TotalCount == 1 {
|
||
outSkuNameExt = result.SkuNames[0]
|
||
_, err = CurVendorSync.SyncSku(ctx, db, outSkuNameExt.SkuName.ID, sku.ID, false, false, userName)
|
||
} else {
|
||
err = ErrEntityNotExist
|
||
}
|
||
}
|
||
//增加规格则同步到门店,目前只做了京东商城的。
|
||
storeSkus, err := dao.GetStoreSkusByNameIDs(db, []int{model.JdShopMainStoreID}, nameID)
|
||
if len(storeSkus) > 0 {
|
||
storeIDs := make(map[int]int)
|
||
storeMaps, err2 := dao.GetStoresMapList(db, []int{model.VendorIDJDShop}, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "", "")
|
||
err = err2
|
||
for _, v := range storeMaps {
|
||
storeSkus2, err2 := dao.GetStoreSkusByNameIDs(db, []int{v.StoreID}, nameID)
|
||
err = err2
|
||
if len(storeSkus2) > 0 {
|
||
storeIDs[v.StoreID] = v.StoreID
|
||
}
|
||
}
|
||
skuBindInfos := []*StoreSkuBindInfo{}
|
||
for _, v := range storeIDs {
|
||
skus2 := []*StoreSkuBindSkuInfo{}
|
||
skuBindInfo := &StoreSkuBindInfo{
|
||
StoreID: v,
|
||
}
|
||
sku2 := &StoreSkuBindSkuInfo{
|
||
SkuID: sku.ID,
|
||
}
|
||
skus2 = append(skus2, sku2)
|
||
skuBindInfo.Skus = skus2
|
||
skuBindInfos = append(skuBindInfos, skuBindInfo)
|
||
}
|
||
FocusStoreSkusBySku(ctx, skuBindInfos, true, true)
|
||
}
|
||
return outSkuNameExt, err
|
||
}
|
||
|
||
func UpdateSku(ctx *jxcontext.Context, skuID int, payload map[string]interface{}) (num int64, err error) {
|
||
userName := ctx.GetUserName()
|
||
sku := &model.Sku{}
|
||
sku.ID = skuID
|
||
db := dao.GetDB()
|
||
if err = dao.GetEntity(db, sku); err != nil {
|
||
return 0, err
|
||
}
|
||
var beforSku = *sku
|
||
valid := dao.StrictMakeMapByStructObject(payload, sku, userName)
|
||
if len(valid) > 0 {
|
||
// globals.SugarLogger.Debug(utils.Format4Output(valid, false))
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
maskValue := int8(model.SyncFlagModifiedMask)
|
||
if valid["specQuality"] != nil || valid["specUnit"] != nil {
|
||
maskValue |= model.SyncFlagSpecMask
|
||
}
|
||
// valid[model.FieldJdSyncStatus] = maskValue | sku.JdSyncStatus
|
||
if num, err = dao.UpdateEntityLogically(db, sku, valid, userName, nil); err != nil || num == 0 {
|
||
dao.Rollback(db)
|
||
if err == nil {
|
||
err = ErrEntityNotExist
|
||
}
|
||
return 0, err
|
||
}
|
||
if _, err = dao.ExecuteSQL(db, `
|
||
UPDATE sku_name t1
|
||
JOIN sku t2 ON t1.id = t2.name_id
|
||
SET t1.spec_quality = t2.spec_quality,
|
||
t1.spec_unit = t2.spec_unit
|
||
WHERE t1.deleted_at = ? AND t2.id = ? AND t1.unit <> ?
|
||
`, utils.DefaultTimeValue, skuID, model.SpecialUnit); err != nil {
|
||
dao.Rollback(db)
|
||
if err == nil {
|
||
err = ErrEntityNotExist
|
||
}
|
||
return 0, err
|
||
}
|
||
if sku.ExdSkuID == "" && sku.EclpID == "" {
|
||
if err = OnUpdateThing(ctx, db, nil, int64(skuID), model.ThingTypeSku); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
}
|
||
dao.Commit(db)
|
||
|
||
if _, err = SetStoreSkuSyncStatus2(db, nil, partner.GetSingleStoreVendorIDs(), []int{skuID}, model.SyncFlagModifiedMask); err == nil {
|
||
if maskValue&model.SyncFlagSpecMask != 0 {
|
||
err = refreshStoreSkuPrice(ctx, db, skuID)
|
||
}
|
||
if valid["status"] != nil {
|
||
SetStoreSkuSyncStatus2(db, nil, partner.GetSingleStoreVendorIDs(), []int{skuID}, model.SyncFlagSaleMask)
|
||
}
|
||
}
|
||
errList := errlist.New()
|
||
errList.AddErr(err)
|
||
_, err = CurVendorSync.SyncSku(ctx, db, -1, sku.ID, false, false, userName)
|
||
errList.AddErr(err)
|
||
err = errList.GetErrListAsOne()
|
||
if globals.IsAddEvent {
|
||
mapBefore := refutil.FindMapAndStructMixed(valid, beforSku)
|
||
err = AddEventDetail(db, ctx, model.OperateUpdate, skuID, model.ThingTypeSku, 0, BuildDiffData(mapBefore), BuildDiffData(valid))
|
||
}
|
||
}
|
||
return num, err
|
||
}
|
||
|
||
func refreshStoreSkuPrice(ctx *jxcontext.Context, db *dao.DaoDB, skuID int) (err error) {
|
||
list, err := dao.GetStoreSkusAndSkuName(db, nil, []int{skuID}, nil)
|
||
task := tasksch.NewParallelTask("refreshStoreSkuPrice", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(true), ctx,
|
||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
v := batchItemList[0].(*dao.StoreSkuAndName)
|
||
storeID := v.StoreID
|
||
storeDetail, _ := dao.GetStoreDetail(db, storeID, model.VendorIDJX, "")
|
||
if storeDetail == nil {
|
||
return retVal, err
|
||
}
|
||
storeSku := &model.StoreSkuBind{}
|
||
storeSku.ID = v.BindID
|
||
storeSku.JdSyncStatus = v.JdSyncStatus | model.SyncFlagPriceMask
|
||
storeSku.MtwmSyncStatus = v.MtwmSyncStatus | model.SyncFlagPriceMask
|
||
storeSku.EbaiSyncStatus = v.EbaiSyncStatus | model.SyncFlagPriceMask
|
||
storeSku.Price = jxutils.CaculateSkuPrice(int(v.UnitPrice), v.SpecQuality, v.SpecUnit, v.Unit)
|
||
storeSku.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), int(storeSku.Price))
|
||
storeSku.LastOperator = ctx.GetUserName()
|
||
storeSku.UpdatedAt = time.Now()
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil || err != nil {
|
||
dao.Rollback(db)
|
||
if r != nil {
|
||
panic(r)
|
||
}
|
||
}
|
||
}()
|
||
dao.UpdateEntity(db, storeSku, "Price", "JdSyncStatus", "MtwmSyncStatus", "EbaiSyncStatus", "JxPrice", "LastOperator")
|
||
dao.Commit(db)
|
||
return retVal, err
|
||
}, list)
|
||
tasksch.HandleTask(task, nil, true).Run()
|
||
_, err = task.GetResult(0)
|
||
return err
|
||
}
|
||
|
||
func DeleteSku(ctx *jxcontext.Context, skuID int, userName string) (num int64, err error) {
|
||
db := dao.GetDB()
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
|
||
if _, err = DeleteStoreSku(ctx, db, 0, skuID); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
if err = OnDeleteThing(ctx, db, nil, int64(skuID), model.ThingTypeSku); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
sku := &model.Sku{}
|
||
sku.ID = skuID
|
||
if num, err = dao.DeleteEntityLogically(db, sku, map[string]interface{}{
|
||
model.FieldStatus: model.SkuStatusDeleted,
|
||
// model.FieldJdSyncStatus: model.SyncFlagDeletedMask,
|
||
}, userName, nil); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
dao.Commit(db)
|
||
if num == 1 {
|
||
_, err = CurVendorSync.SyncSku(ctx, db, -1, sku.ID, false, false, userName)
|
||
}
|
||
err = deleteJdsSku(db, skuID)
|
||
return num, err
|
||
}
|
||
|
||
func DeleteStoreSku(ctx *jxcontext.Context, db *dao.DaoDB, nameID, skuID int) (num int64, err error) {
|
||
if db == nil {
|
||
db = dao.GetDB()
|
||
}
|
||
|
||
sql := `
|
||
SELECT *
|
||
FROM sku t1
|
||
WHERE 1 = 1
|
||
`
|
||
sqlParams := []interface{}{}
|
||
if nameID > 0 {
|
||
sql += " AND t1.name_id = ?"
|
||
sqlParams = append(sqlParams, nameID)
|
||
} else {
|
||
sql += " AND t1.id = ?"
|
||
sqlParams = append(sqlParams, skuID)
|
||
}
|
||
|
||
var skuList []*model.Sku
|
||
if err = dao.GetRows(db, &skuList, sql, sqlParams); err == nil {
|
||
num = int64(len(skuList))
|
||
for _, v := range skuList {
|
||
storeSkuBind := &model.StoreSkuBind{}
|
||
_, err = dao.DeleteEntityLogically(db, storeSkuBind, map[string]interface{}{
|
||
model.FieldJdSyncStatus: model.SyncFlagDeletedMask,
|
||
model.FieldMtwmSyncStatus: model.SyncFlagDeletedMask,
|
||
model.FieldEbaiSyncStatus: model.SyncFlagDeletedMask,
|
||
model.FieldJdsSyncStatus: model.SyncFlagDeletedMask,
|
||
}, ctx.GetUserName(), map[string]interface{}{
|
||
model.FieldSkuID: v.ID,
|
||
model.FieldDeletedAt: utils.DefaultTimeValue,
|
||
})
|
||
if err != nil {
|
||
break
|
||
}
|
||
}
|
||
}
|
||
return num, err
|
||
}
|
||
|
||
func AddSkuNamePlace(ctx *jxcontext.Context, nameID, placeCode int, userName string) (outPlaceBind *model.SkuNamePlaceBind, err error) {
|
||
db := dao.GetDB()
|
||
placeBind := &model.SkuNamePlaceBind{
|
||
NameID: nameID,
|
||
PlaceCode: placeCode,
|
||
}
|
||
dao.WrapAddIDCULEntity(placeBind, userName)
|
||
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if err = dao.CreateEntity(db, placeBind); err != nil {
|
||
dao.Rollback(db)
|
||
return nil, err
|
||
}
|
||
if err = OnUpdateThing(ctx, db, nil, int64(nameID), model.ThingTypeSkuName); err != nil {
|
||
dao.Rollback(db)
|
||
return nil, err
|
||
}
|
||
dao.Commit(db)
|
||
|
||
_, err = CurVendorSync.SyncSku(ctx, db, nameID, -1, false, false, userName)
|
||
return placeBind, err
|
||
}
|
||
|
||
func DeleteSkuNamePlace(ctx *jxcontext.Context, nameID, placeCode int, userName string) (num int64, err error) {
|
||
db := dao.GetDB()
|
||
placeBind := &model.SkuNamePlaceBind{}
|
||
placeBind.NameID = nameID
|
||
placeBind.PlaceCode = placeCode
|
||
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if num, err = dao.DeleteEntity(db, placeBind, model.FieldNameID, model.FieldPlaceCode); err != nil || num == 0 {
|
||
dao.Rollback(db)
|
||
if err == nil {
|
||
err = ErrEntityNotExist
|
||
}
|
||
return 0, err
|
||
}
|
||
if err = OnUpdateThing(ctx, db, nil, int64(nameID), model.ThingTypeSkuName); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
dao.Commit(db)
|
||
|
||
_, err = CurVendorSync.SyncSku(ctx, db, nameID, -1, false, false, userName)
|
||
return num, err
|
||
}
|
||
|
||
// func GetVendorSku(ctx *jxcontext.Context, vendorID int, vendorOrgCode, vendorSkuID string) (skuNameInfo *model.SkuNameExt, err error) {
|
||
// if handler := CurVendorSync.GetMultiStoreHandler(vendorID); handler != nil {
|
||
// return handler.ReadSku(ctx, vendorOrgCode, vendorSkuID)
|
||
// }
|
||
// return nil, ErrCanNotFindVendor
|
||
// }
|
||
|
||
func SortCategorySkus(ctx *jxcontext.Context, catID int, skuIDList []int) (err error) {
|
||
db := dao.GetDB()
|
||
userName := ctx.GetUserName()
|
||
var skuList []*model.Sku
|
||
if skuList, err = dao.GetSkuByCats(db, []int{catID}); err == nil && len(skuList) > 0 {
|
||
if len(skuList) != len(skuIDList) {
|
||
return errors.New("商品数量不匹配!")
|
||
}
|
||
skuIDMap := make(map[int]int)
|
||
for index, id := range skuIDList {
|
||
skuIDMap[id] = index + 1
|
||
}
|
||
for _, value := range skuList {
|
||
if _, ok := skuIDMap[value.ID]; !ok {
|
||
return errors.New("商品数据不匹配!")
|
||
}
|
||
}
|
||
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
nameIDList := []int{}
|
||
for _, value := range skuList {
|
||
seq := skuIDMap[value.ID]
|
||
if value.Seq != seq {
|
||
kvs := map[string]interface{}{
|
||
model.FieldSkuSeq: seq,
|
||
//model.FieldJdSyncStatus: (value.JdSyncStatus | model.SyncFlagModifiedMask),
|
||
}
|
||
dao.UpdateEntityLogically(db, value, kvs, userName, nil)
|
||
nameIDList = append(nameIDList, value.NameID)
|
||
}
|
||
}
|
||
//_, err = CurVendorSync.SyncSkus(ctx, db, nameIDList, []int{}, false, false, userName)
|
||
|
||
if err == nil && len(nameIDList) > 0 {
|
||
dao.Commit(db)
|
||
skuIDs, err2 := dao.GetSkuIDByNames(db, nameIDList)
|
||
if err = err2; err == nil && len(skuIDs) > 0 {
|
||
_, err = SetStoreSkuSyncStatus2(db, nil, partner.GetSingleStoreVendorIDs(), skuIDs, model.SyncFlagModifiedMask)
|
||
}
|
||
} else {
|
||
dao.Rollback(db)
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func GetJdUpcCodeByCode(ctx *jxcontext.Context, upcCode string) (productInfos []*jdapi.ProductInfo, err error) {
|
||
productInfo, err := api.JdAPI.GetJdUpcCodeByName("", upcCode, 1, 30)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
for _, v := range productInfo {
|
||
_, name, _, specUnit, unit, specQuality := jxutils.SplitSkuName(v.OriginalName)
|
||
v.Name = name
|
||
v.SpecQuality = specQuality
|
||
v.SpecUnit = specUnit
|
||
v.Unit = unit
|
||
}
|
||
return productInfo, err
|
||
}
|
||
|
||
func GetJdUpcCodeByName(ctx *jxcontext.Context, name, upcCode string) (productInfos []*jdapi.ProductInfo, err error) {
|
||
if name != "" {
|
||
var (
|
||
pageNo = 5
|
||
pageSize = 30
|
||
pageNoList []int
|
||
)
|
||
if name == "" && upcCode == "" {
|
||
return nil, fmt.Errorf("至少输入一个条件查询,商品名或者upc码!")
|
||
}
|
||
for i := 1; i < pageNo+1; i++ {
|
||
pageNoList = append(pageNoList, i)
|
||
}
|
||
task := tasksch.NewParallelTask("获取京东商品", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
|
||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
pageNum := batchItemList[0].(int)
|
||
productInfo, err := api.JdAPI.GetJdUpcCodeByName(name, upcCode, pageNum, pageSize)
|
||
if err != nil {
|
||
return retVal, err
|
||
}
|
||
for _, v := range productInfo {
|
||
_, name, _, specUnit, unit, specQuality := jxutils.SplitSkuName(v.OriginalName)
|
||
v.Name = name
|
||
v.SpecQuality = specQuality
|
||
v.SpecUnit = specUnit
|
||
v.Unit = unit
|
||
}
|
||
retVal = productInfo
|
||
return retVal, err
|
||
}, pageNoList)
|
||
tasksch.HandleTask(task, nil, true).Run()
|
||
productInfoInterface, err2 := task.GetResult(0)
|
||
err = err2
|
||
for _, v := range productInfoInterface {
|
||
productInfos = append(productInfos, v.(*jdapi.ProductInfo))
|
||
}
|
||
} else {
|
||
productInfos, err = GetJdUpcCodeByCode(ctx, upcCode)
|
||
if len(productInfos) == 0 {
|
||
if configs, err := dao.QueryConfigs(dao.GetDB(), "mtwmCookieStr", model.ConfigTypeCookie, ""); err == nil {
|
||
api.MtwmAPI.SetCookieWithStr(configs[0].Value)
|
||
}
|
||
if result, err := api.MtwmAPI.GetStandardProductListWithCond(upcCode); err == nil && result != nil {
|
||
productInfo := &jdapi.ProductInfo{
|
||
OriginalName: result.Name,
|
||
OriginalSpec: result.Spec,
|
||
}
|
||
// _, name, _, specUnit, unit, specQuality := jxutils.SplitSkuName(productInfo.OriginalName)
|
||
productInfo.Name = name
|
||
productInfo.SpecUnit = result.SpecUnit
|
||
productInfo.Unit = result.Unit
|
||
productInfo.SpecQuality = float32(result.SpecNew)
|
||
productInfo.ImgList = strings.Split(result.Pic, ",")
|
||
productInfo.Weight = float32(result.Weight)
|
||
productInfo.Price = result.AvgPrice
|
||
productInfo.BrandName = result.BrandNamePath
|
||
productInfos = append(productInfos, productInfo)
|
||
}
|
||
}
|
||
}
|
||
return productInfos, err
|
||
}
|
||
|
||
func UpdateSkuNamesExPrefix(ctx *jxcontext.Context, nameIDs []int, imgWaterMark string, vendorID int, exPrefix, fromTime, toTime string, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||
var (
|
||
fromTimeP time.Time
|
||
toTimeP time.Time
|
||
db = dao.GetDB()
|
||
)
|
||
if fromTime != "" {
|
||
fromTimeP = utils.Time2Date(utils.Str2Time(fromTime))
|
||
}
|
||
if toTime != "" {
|
||
toTimeP = utils.Time2Date(utils.Str2Time(toTime))
|
||
}
|
||
if toTimeP.Before(fromTimeP) {
|
||
return "", fmt.Errorf("结束时间不可以小于开始时间!开始时间:[%v],结束时间:[%v]", fromTimeP, toTimeP)
|
||
}
|
||
task := tasksch.NewParallelTask("批量设置商品前缀", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx,
|
||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
step := batchItemList[0].(int)
|
||
now := utils.Time2Date(time.Now())
|
||
switch step {
|
||
case 0:
|
||
task := tasksch.NewParallelTask("批量设置商品前缀", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
nameID := batchItemList[0].(int)
|
||
payload := map[string]interface{}{
|
||
"exPrefix": exPrefix,
|
||
"exPrefixBegin": fromTimeP,
|
||
"exPrefixEnd": toTimeP,
|
||
"imgWaterMark": imgWaterMark,
|
||
"exVendorID": vendorID,
|
||
}
|
||
if now.Sub(toTimeP) <= 0 && now.Sub(fromTimeP) <= 0 {
|
||
_, err = UpdateSkuName(ctx, nameID, payload, false)
|
||
} else if now.Sub(fromTimeP) > 0 && now.Sub(toTimeP) > 0 {
|
||
payload["exPrefixBegin"] = nil
|
||
payload["exPrefixEnd"] = nil
|
||
payload["imgWaterMark"] = nil
|
||
payload["exVendorID"] = nil
|
||
_, err = UpdateSkuName(ctx, nameID, payload, false)
|
||
} else {
|
||
skuList, err := dao.GetSkus(db, nil, []int{nameID}, nil, nil, nil)
|
||
if err == nil && len(skuList) > 0 {
|
||
if skuList[0].ExPrefixBegin != nil {
|
||
_, err = UpdateSkuName(ctx, nameID, payload, false)
|
||
CurVendorSync.SyncStoresSkus2(ctx, nil, 0, db, []int{vendorID}, nil, false, []int{skuList[0].ID}, nil, model.SyncFlagModifiedMask, true, true)
|
||
} else {
|
||
skuName := &model.SkuName{
|
||
ExPrefix: exPrefix,
|
||
ExPrefixBegin: &fromTimeP,
|
||
ExPrefixEnd: &toTimeP,
|
||
ImgWatermark: imgWaterMark,
|
||
ExVendorID: vendorID,
|
||
}
|
||
skuName.ID = nameID
|
||
skuName.LastOperator = ctx.GetLoginID()
|
||
skuName.UpdatedAt = time.Now()
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
_, err = dao.UpdateEntity(db, skuName, "ImgWatermark", "ExVendorID", "ExPrefix", "ExPrefixBegin", "ExPrefixEnd", "LastOperator", "UpdatedAt")
|
||
dao.Commit(db)
|
||
}
|
||
}
|
||
}
|
||
return retVal, err
|
||
}, nameIDs)
|
||
tasksch.HandleTask(task, nil, true).Run()
|
||
_, err = task.GetResult(0)
|
||
case 1:
|
||
if (now.Sub(toTimeP) <= 0 && now.Sub(fromTimeP) >= 0) || (now.Sub(fromTimeP) > 0 && now.Sub(toTimeP) > 0) {
|
||
var skuIDs []int
|
||
skuList, err2 := dao.GetSkus(db, nil, nameIDs, nil, nil, nil)
|
||
if err = err2; err == nil {
|
||
if len(skuList) > 0 {
|
||
for _, v := range skuList {
|
||
skuIDs = append(skuIDs, v.ID)
|
||
}
|
||
CurVendorSync.SyncStoresSkus2(ctx, nil, 0, db, []int{vendorID}, nil, false, skuIDs, nil, model.SyncFlagModifiedMask, true, true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return retVal, err
|
||
}, []int{0, 1})
|
||
tasksch.HandleTask(task, nil, true).Run()
|
||
if !isAsync {
|
||
_, err = task.GetResult(0)
|
||
hint = "1"
|
||
} else {
|
||
hint = task.GetID()
|
||
}
|
||
return hint, err
|
||
}
|
||
|
||
func SetSingleStoreSkuSyncModifyStatus(db *dao.DaoDB, vendorIDs []int) (err error) {
|
||
_, err = dao.UpdateStoreSkuBindSyncStatusForExPrefix(db, vendorIDs)
|
||
return err
|
||
}
|
||
|
||
func SetMultiStoreSkuSyncModifyStatus(db *dao.DaoDB, vendorIDs []int) (err error) {
|
||
_, err = dao.UpdateSkuSyncStatusForExPrefix(db, vendorIDs)
|
||
return err
|
||
}
|
||
|
||
func DeleteSkuNameExPrefixOverdue(db *dao.DaoDB) (err error) {
|
||
_, err = dao.DeleteSkuNameExPrefixOverdue(db)
|
||
return err
|
||
}
|
||
|
||
func SumExianDaDepot(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||
db := dao.GetDB()
|
||
results, err := api.EbaiAPI.GetExianDaSkuDepot("")
|
||
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||
switch step {
|
||
case 0:
|
||
taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
v := batchItemList[0].(*ebaiapi.ExianDaSkus)
|
||
skus, err := api.EbaiAPI.GetExianDaSku(utils.Str2Int64(v.ElemeGoodsID))
|
||
if err != nil || skus == nil {
|
||
globals.SugarLogger.Debugf("GetExianDaSku,[%v]", v.ElemeGoodsID)
|
||
return result, err
|
||
}
|
||
// sku := &model.Sku{}
|
||
// sku.ExdSkuID = v.ElemeGoodsID
|
||
// sku.DeletedAt = utils.DefaultTimeValue
|
||
// dao.GetEntity(db, sku, "ExdSkuID","DeletedAt")
|
||
skuNameExt := &model.SkuName{}
|
||
sql2 := `
|
||
SELECT a.*
|
||
FROM sku_name a
|
||
JOIN sku b ON b.name_id = a.id
|
||
WHERE a.upc = ?
|
||
AND a.deleted_at = ? AND b.deleted_at = ?
|
||
`
|
||
sqlParams2 := []interface{}{
|
||
skus.UpcIds[0],
|
||
utils.DefaultTimeValue, utils.DefaultTimeValue,
|
||
}
|
||
dao.GetRow(db, skuNameExt, sql2, sqlParams2)
|
||
prefix, _, _, specUnit, unit, specQuality := jxutils.SplitSkuName(v.GoodsName)
|
||
//京西库中存在此商品
|
||
if skuNameExt.ID != 0 {
|
||
var flag = false
|
||
if skuNameExt.Name != v.GoodsName {
|
||
skuNameExt.Name = v.GoodsName
|
||
skuNameExt.Prefix = prefix
|
||
skuNameExt.SpecUnit = specUnit
|
||
skuNameExt.Unit = unit
|
||
skuNameExt.SpecQuality = specQuality
|
||
flag = true
|
||
}
|
||
if skuNameExt.Img != v.ImageURL {
|
||
skuNameExt.Img = v.ImageURL
|
||
flag = true
|
||
}
|
||
if flag {
|
||
_, err = dao.UpdateEntity(db, skuNameExt, "Name", "Prefix", "SpecUnit", "Unit", "SpecQuality", "Img")
|
||
if err != nil {
|
||
return result, err
|
||
}
|
||
}
|
||
} else {
|
||
skuName := &model.SkuName{
|
||
Prefix: prefix,
|
||
Name: v.GoodsName,
|
||
IsGlobal: model.YES,
|
||
Unit: unit,
|
||
SpecQuality: specQuality,
|
||
SpecUnit: specUnit,
|
||
Price: 100,
|
||
Img: v.ImageURL,
|
||
Upc: &v.UpcID,
|
||
Status: model.SkuStatusNormal,
|
||
}
|
||
skuName.CategoryID = model.NoCatCatgoryID //默认给了个分类
|
||
dao.WrapAddIDCULDEntity(skuName, ctx.GetUserName())
|
||
err = dao.CreateEntity(db, skuName)
|
||
if err != nil {
|
||
return result, err
|
||
}
|
||
sku := &model.Sku{
|
||
NameID: skuName.ID,
|
||
SpecQuality: specQuality,
|
||
SpecUnit: specUnit,
|
||
Weight: int(utils.Str2Int64(skus.Weight)),
|
||
Status: model.SkuStatusNormal,
|
||
ExdSkuID: v.ElemeGoodsID,
|
||
ExdCategoryThirdID: skus.CategoryIDThird,
|
||
}
|
||
dao.WrapAddIDCULDEntity(sku, ctx.GetUserName())
|
||
err = dao.CreateEntity(db, sku)
|
||
if err != nil {
|
||
return result, err
|
||
}
|
||
}
|
||
return retVal, err
|
||
}
|
||
taskParallel := tasksch.NewParallelTask("更新京西上饿鲜达商品库", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, results)
|
||
tasksch.HandleTask(taskParallel, task, true).Run()
|
||
_, err = taskParallel.GetResult(0)
|
||
case 1:
|
||
}
|
||
return result, err
|
||
}
|
||
taskSeq := tasksch.NewSeqTask2("合并饿鲜达商品库", ctx, isContinueWhenError, taskSeqFunc, 2)
|
||
tasksch.HandleTask(taskSeq, nil, true).Run()
|
||
if !isAsync {
|
||
_, err = taskSeq.GetResult(0)
|
||
hint = "1"
|
||
} else {
|
||
hint = taskSeq.GetID()
|
||
}
|
||
return hint, err
|
||
}
|
||
|
||
func UpdateExianDaSkuCategory(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
skus []*model.SkuName
|
||
)
|
||
sql := `
|
||
SELECT a.*
|
||
FROM sku_name a
|
||
JOIN sku b ON b.name_id = a.id
|
||
WHERE b.exd_sku_id <> ''
|
||
AND a.deleted_at = ?
|
||
AND b.deleted_at = ?
|
||
`
|
||
sqlParams := []interface{}{
|
||
utils.DefaultTimeValue, utils.DefaultTimeValue,
|
||
}
|
||
err = dao.GetRows(db, &skus, sql, sqlParams...)
|
||
task := tasksch.NewParallelTask("更新京西上饿鲜达商品分类", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
v := batchItemList[0].(*model.SkuName)
|
||
skuList, err := api.Ebai2API.GetEbaiDepotSku(ebaiapi.EbaiWholeCountryStore, *v.Upc)
|
||
if err != nil || len(skuList) == 0 || skuList[0] == nil {
|
||
return retVal, err
|
||
}
|
||
sku, err := api.Ebai2API.GetEbaiSku(skuList[0].UpcID, ebaiapi.EbaiWholeCountryStore)
|
||
if err != nil || sku == nil || sku.CustomCatName == "" {
|
||
return retVal, err
|
||
}
|
||
skuCat := &model.SkuCategory{}
|
||
sql := `
|
||
SELECT *
|
||
FROM sku_category
|
||
WHERE exd_name like ?
|
||
`
|
||
sqlParams := []interface{}{
|
||
"%" + sku.CustomCatName + "%",
|
||
}
|
||
err = dao.GetRow(db, skuCat, sql, sqlParams)
|
||
v.CategoryID = skuCat.ID
|
||
_, err = dao.UpdateEntity(db, v, "CategoryID")
|
||
if err != nil {
|
||
return retVal, err
|
||
}
|
||
return retVal, err
|
||
}, skus)
|
||
tasksch.HandleTask(task, nil, true).Run()
|
||
if !isAsync {
|
||
_, err = task.GetResult(0)
|
||
hint = "1"
|
||
} else {
|
||
hint = task.GetID()
|
||
}
|
||
return hint, err
|
||
}
|
||
|
||
func SendNoCatSkusToOperater(ctx *jxcontext.Context) (err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
skuNames []*model.SkuName
|
||
)
|
||
globals.SugarLogger.Debugf("SendNoCatSkusToOperater")
|
||
sql := `
|
||
SELECT * FROM sku_name WHERE deleted_at = ? AND (category_id = ? OR img = ?) AND unit <> ?
|
||
`
|
||
sqlParams := []interface{}{utils.DefaultTimeValue, model.NoCatCatgoryID, model.NOSkuNameImg, model.UnitNames[0]}
|
||
err = dao.GetRows(db, &skuNames, sql, sqlParams)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if len(skuNames) > 10 {
|
||
noticeMsg := "有超过10个标品未进行分类和未设置图片!"
|
||
for _, v := range skuNames {
|
||
noticeMsg += "NameID:" + utils.Int2Str(v.ID) + ",商品名:" + v.Name + ","
|
||
}
|
||
for _, mobile := range sendNoCatSkusMobile {
|
||
if user, err := dao.GetUserByID(db, "mobile", mobile); err != nil {
|
||
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.UserID, "标品未分类和未设置图片", noticeMsg)
|
||
}
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func buildCreateUpcSkuByExcelErr(v *model.SkuName, errMsg string) (createUpcSkuByExcelErr *CreateUpcSkuByExcelErr) {
|
||
createUpcSkuByExcelErr = &CreateUpcSkuByExcelErr{
|
||
Upc: *v.Upc,
|
||
Name: v.Name,
|
||
Unit: v.Unit,
|
||
SpecQuality: utils.Float64ToStr(float64(v.SpecQuality)),
|
||
Price: v.Price / 100,
|
||
Err: errMsg,
|
||
}
|
||
return createUpcSkuByExcelErr
|
||
}
|
||
|
||
func CreateUpcSkuByExcel(ctx *jxcontext.Context, files []*multipart.FileHeader, categoryID int) (hint string, err error) {
|
||
if len(files) == 0 {
|
||
return "", errors.New("没有文件上传!")
|
||
}
|
||
fileHeader := files[0]
|
||
file, err := fileHeader.Open()
|
||
hint, err = CreateUpcSkuByExcelBin(ctx, file, categoryID)
|
||
file.Close()
|
||
return hint, err
|
||
}
|
||
|
||
func CreateUpcSkuByExcelBin(ctx *jxcontext.Context, reader io.Reader, categoryID int) (hint string, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
skuParams []*model.SkuName
|
||
createUpcSkuByExcelErrList []*CreateUpcSkuByExcelErr
|
||
createUpcSkuByExcelErrListInterface []interface{}
|
||
excelTitle = []string{
|
||
"商品条码",
|
||
"商品名称",
|
||
"单位",
|
||
"重量(g)",
|
||
"售价",
|
||
"错误原因",
|
||
}
|
||
upcRegexp = regexp.MustCompile(`(^\d{12,13}$)`)
|
||
)
|
||
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result2 interface{}, err error) {
|
||
switch step {
|
||
case 0:
|
||
xlsx, err := excelize.OpenReader(reader)
|
||
if err != nil {
|
||
return result2, err
|
||
}
|
||
rows, _ := xlsx.GetRows(xlsx.GetSheetName(1))
|
||
for rowNum, row := range rows {
|
||
if rowNum < 1 {
|
||
continue
|
||
}
|
||
var (
|
||
skuParam = &model.SkuName{}
|
||
upc string
|
||
unit string
|
||
specQuality float32
|
||
price int
|
||
name string
|
||
)
|
||
for k, cell := range row {
|
||
if cell != "" {
|
||
if k == 0 {
|
||
upc = cell
|
||
}
|
||
if k == 1 {
|
||
name = cell
|
||
}
|
||
if k == 2 {
|
||
unit = cell
|
||
}
|
||
if k == 3 {
|
||
specQuality = float32(utils.Str2Float64WithDefault(cell, 0))
|
||
}
|
||
if k == 4 {
|
||
price = int(utils.Str2Float64WithDefault(cell, 0) * 100)
|
||
}
|
||
}
|
||
}
|
||
skuParam.Upc = &upc
|
||
skuParam.Unit = unit
|
||
skuParam.SpecQuality = specQuality
|
||
skuParam.Price = price
|
||
skuParam.Name = name
|
||
skuParams = append(skuParams, skuParam)
|
||
}
|
||
case 1:
|
||
taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
var (
|
||
v = batchItemList[0].(*model.SkuName)
|
||
skuNames []model.SkuName
|
||
skuName = &model.SkuNameExt{
|
||
SkuName: model.SkuName{},
|
||
Skus: []*model.SkuWithVendor{
|
||
&model.SkuWithVendor{
|
||
Sku: &model.Sku{},
|
||
},
|
||
},
|
||
}
|
||
)
|
||
if v.Upc != nil {
|
||
upc := upcRegexp.FindString(*v.Upc)
|
||
if upc == "" {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "请输入正确的商品条码!")}
|
||
return retVal, err
|
||
}
|
||
skuName.Upc = v.Upc
|
||
} else {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "商品的条码不能为空!")}
|
||
return retVal, err
|
||
}
|
||
sql := `
|
||
SELECT * FROM sku_name WHERE upc = ? AND deleted_at = ?
|
||
`
|
||
sqlParams := []interface{}{*v.Upc, utils.DefaultTimeValue}
|
||
err = dao.GetRows(db, &skuNames, sql, sqlParams)
|
||
if len(skuNames) > 0 {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "商品在京西库中已存在!")}
|
||
return retVal, err
|
||
}
|
||
productInfos, err := GetJdUpcCodeByCode(ctx, *v.Upc)
|
||
if err != nil {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())}
|
||
return retVal, err
|
||
}
|
||
var productInfo = &jdapi.ProductInfo{}
|
||
if len(productInfos) == 0 {
|
||
if configs, err := dao.QueryConfigs(dao.GetDB(), "mtwmCookieStr", model.ConfigTypeCookie, ""); err == nil {
|
||
api.MtwmAPI.SetCookieWithStr(configs[0].Value)
|
||
}
|
||
result, _ := api.MtwmAPI.GetStandardProductListWithCond(*skuName.Upc)
|
||
if result != nil {
|
||
productInfo.OriginalName = result.Name
|
||
productInfo.OriginalSpec = result.Spec
|
||
productInfo.Name = result.Name
|
||
productInfo.SpecUnit = result.SpecUnit
|
||
productInfo.Unit = result.Unit
|
||
productInfo.SpecQuality = float32(result.SpecNew)
|
||
productInfo.ImgList = strings.Split(result.Pic, ",")
|
||
productInfo.Weight = float32(result.Weight)
|
||
productInfo.BrandName = result.BrandNamePath
|
||
setImgs(skuName, productInfo.ImgList)
|
||
} else {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "美团cookie过期了吧")}
|
||
return retVal, err
|
||
}
|
||
} else {
|
||
productInfo = productInfos[0]
|
||
}
|
||
if productInfo.Name == "" {
|
||
if v.Name != "" {
|
||
productInfo.Name = v.Name
|
||
} else if productInfo.OriginalName != "" {
|
||
productInfo.Name = productInfo.OriginalName
|
||
} else {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "需要填上一个合适的商品名!")}
|
||
return retVal, err
|
||
}
|
||
}
|
||
if v.Price == 0 {
|
||
result, err := api.AliUpcAPI.GetAliUpcInfo(*v.Upc)
|
||
if err != nil {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())}
|
||
return retVal, err
|
||
}
|
||
if result.Price == "" {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "未查询到商品售价,请补充商品售价!")}
|
||
return retVal, err
|
||
} else {
|
||
skuName.Price = int(utils.Str2Int64(result.Price) * 100)
|
||
}
|
||
} else {
|
||
skuName.Price = v.Price
|
||
}
|
||
skuName.Name = productInfo.Name
|
||
getNetUpcInfo, err := api.AliUpcAPI.GetNetUpcInfo(*v.Upc)
|
||
if v.Unit != "" {
|
||
skuName.Unit = v.Unit
|
||
} else {
|
||
if productInfo.Unit == "" {
|
||
if getNetUpcInfo.Unit != "" {
|
||
skuName.Unit = getNetUpcInfo.Unit
|
||
} else {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "未查询到商品单位,请补充商品单位!")}
|
||
return retVal, err
|
||
}
|
||
} else {
|
||
skuName.Unit = productInfo.Unit
|
||
}
|
||
}
|
||
if v.SpecQuality != 0 {
|
||
skuName.Skus[0].SpecQuality = v.SpecQuality
|
||
skuName.Skus[0].Weight = utils.Float32ToInt(v.SpecQuality)
|
||
skuName.Skus[0].SpecUnit = model.SpecUnitNames[0]
|
||
} else {
|
||
_, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(v.Name)
|
||
if specQuality != 0 {
|
||
skuName.Skus[0].SpecQuality = specQuality
|
||
if specUnit == model.SpecUnitNames[1] || specUnit == model.SpecUnitNames[2] {
|
||
skuName.Skus[0].Weight = int(utils.Str2Int64(utils.Float64ToStr(float64(specQuality) * 1000)))
|
||
} else {
|
||
skuName.Skus[0].Weight = utils.Float32ToInt(specQuality)
|
||
}
|
||
} else {
|
||
if productInfo.SpecQuality == 0 {
|
||
if getNetUpcInfo.SpecQuality != 0 {
|
||
if getNetUpcInfo.SpecUnit == model.SpecUnitNames[1] || getNetUpcInfo.SpecUnit == model.SpecUnitNames[2] ||
|
||
getNetUpcInfo.SpecUnit == "KG" || getNetUpcInfo.SpecUnit == "l" {
|
||
skuName.Skus[0].Weight = int(utils.Str2Int64(utils.Float64ToStr(float64(getNetUpcInfo.SpecQuality) * 1000)))
|
||
} else {
|
||
skuName.Skus[0].Weight = utils.Float32ToInt(getNetUpcInfo.SpecQuality)
|
||
}
|
||
skuName.Skus[0].SpecQuality = getNetUpcInfo.SpecQuality
|
||
} else {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "未查询到商品重量,请补充商品重量!")}
|
||
return retVal, err
|
||
}
|
||
} else {
|
||
if productInfo.Weight != 0 {
|
||
skuName.Skus[0].Weight = int(utils.Str2Int64(utils.Float64ToStr(float64(productInfo.Weight))))
|
||
} else {
|
||
skuName.Skus[0].Weight = utils.Float32ToInt(v.SpecQuality)
|
||
}
|
||
skuName.Skus[0].SpecQuality = productInfo.SpecQuality
|
||
}
|
||
}
|
||
if productInfo.SpecUnit == "" {
|
||
if getNetUpcInfo.SpecUnit != "" {
|
||
skuName.Skus[0].SpecUnit = getNetUpcInfo.SpecUnit
|
||
} else {
|
||
skuName.Skus[0].SpecUnit = model.SpecUnitNames[0]
|
||
}
|
||
} else {
|
||
skuName.Skus[0].SpecUnit = productInfo.SpecUnit
|
||
}
|
||
}
|
||
if len(productInfo.ImgList) > 0 {
|
||
setImgs(skuName, productInfo.ImgList)
|
||
} else {
|
||
skuName.Img = model.NOSkuNameImg
|
||
}
|
||
if skuName.Img == "" {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "未查询到商品图片请联系开发!")}
|
||
return retVal, err
|
||
}
|
||
suffix := skuName.Img[strings.LastIndex(skuName.Img, "."):]
|
||
if suffix != ".jpg" && suffix != ".png" && suffix != ".jpeg" && suffix != ".gif" {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, fmt.Sprintf("暂不支持的图片格式:[%v]", skuName.Img))}
|
||
return retVal, err
|
||
}
|
||
skuName.Status = model.SkuStatusNormal
|
||
skuName.IsGlobal = model.YES
|
||
if categoryID == 0 {
|
||
skuName.CategoryID = model.NoCatCatgoryID
|
||
} else {
|
||
skuName.CategoryID = categoryID
|
||
}
|
||
skuName.Skus[0].Status = model.SkuStatusNormal
|
||
//需要把图片传到七牛云上, 很难受
|
||
if !strings.Contains(skuName.Img, "image.jxc4.com") {
|
||
downloadURL, err := uploadImgStandard(skuName.Img)
|
||
if err != nil {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())}
|
||
return retVal, err
|
||
}
|
||
skuName.Img = downloadURL
|
||
}
|
||
if skuName.Img2 != "" {
|
||
if !strings.Contains(skuName.Img2, "image.jxc4.com") {
|
||
downloadURL, err := uploadImgStandard(skuName.Img2)
|
||
if err != nil {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())}
|
||
return retVal, err
|
||
}
|
||
skuName.Img2 = downloadURL
|
||
}
|
||
}
|
||
if skuName.Img3 != "" {
|
||
if !strings.Contains(skuName.Img3, "image.jxc4.com") {
|
||
downloadURL, err := uploadImgStandard(skuName.Img3)
|
||
if err != nil {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())}
|
||
return retVal, err
|
||
}
|
||
skuName.Img3 = downloadURL
|
||
}
|
||
}
|
||
if skuName.Img4 != "" {
|
||
if !strings.Contains(skuName.Img4, "image.jxc4.com") {
|
||
downloadURL, err := uploadImgStandard(skuName.Img4)
|
||
if err != nil {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())}
|
||
return retVal, err
|
||
}
|
||
skuName.Img4 = downloadURL
|
||
}
|
||
}
|
||
if skuName.Img5 != "" {
|
||
if !strings.Contains(skuName.Img5, "image.jxc4.com") {
|
||
downloadURL, err := uploadImgStandard(skuName.Img5)
|
||
if err != nil {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())}
|
||
return retVal, err
|
||
}
|
||
skuName.Img5 = downloadURL
|
||
}
|
||
}
|
||
_, err = AddSkuName(ctx, skuName, ctx.GetUserName())
|
||
if err != nil {
|
||
retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())}
|
||
return retVal, err
|
||
}
|
||
return retVal, err
|
||
}
|
||
taskParallel := tasksch.NewParallelTask("创建标品中", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, taskFunc, skuParams)
|
||
tasksch.HandleTask(taskParallel, task, true).Run()
|
||
createUpcSkuByExcelErrListInterface, err = taskParallel.GetResult(0)
|
||
case 2:
|
||
if len(createUpcSkuByExcelErrListInterface) > 0 {
|
||
for _, v := range createUpcSkuByExcelErrListInterface {
|
||
createUpcSkuByExcelErrList = append(createUpcSkuByExcelErrList, v.(*CreateUpcSkuByExcelErr))
|
||
}
|
||
if len(createUpcSkuByExcelErrList) > 0 {
|
||
err = writeToExcel(excelTitle, createUpcSkuByExcelErrList, ctx)
|
||
}
|
||
}
|
||
}
|
||
return result2, err
|
||
}
|
||
taskSeq := tasksch.NewSeqTask2("根据excel创建标品-序列任务", ctx, true, taskSeqFunc, 3)
|
||
tasksch.HandleTask(taskSeq, nil, true).Run()
|
||
hint = taskSeq.GetID()
|
||
return hint, err
|
||
}
|
||
|
||
func writeToExcel(excelTitle []string, dataList interface{}, ctx *jxcontext.Context) (err error) {
|
||
var sheetList []*excel.Obj2ExcelSheetConfig
|
||
var downloadURL, fileName string
|
||
excelConf := &excel.Obj2ExcelSheetConfig{
|
||
Title: "sheet1",
|
||
Data: dataList,
|
||
CaptionList: excelTitle,
|
||
}
|
||
sheetList = append(sheetList, excelConf)
|
||
if excelConf != nil {
|
||
downloadURL, fileName, err = jxutils.UploadExeclAndPushMsg(sheetList, "创建标品错误")
|
||
} else {
|
||
baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess is nil!")
|
||
}
|
||
if err != nil {
|
||
baseapi.SugarLogger.Errorf("WriteToExcel:upload %s , %s failed error:%v", fileName, err)
|
||
} else {
|
||
noticeMsg := fmt.Sprintf("[详情点我]%s/billshow/?normal=true&path=%s \n", globals.BackstageHost, downloadURL)
|
||
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, ctx.GetUserID(), "异步任务完成", noticeMsg)
|
||
baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess downloadURL: [%v]", downloadURL)
|
||
}
|
||
return err
|
||
}
|
||
|
||
//恢复京东回收站,修改京西的京东id
|
||
func RefreshJdDepot(ctx *jxcontext.Context) (err error) {
|
||
var (
|
||
pageSize = 20
|
||
searchResults []*jdapi.SearchDeleteWareResult
|
||
db = dao.GetDB()
|
||
// pageList []int
|
||
// skuIDs []int
|
||
)
|
||
for page := 1; page < 2; page++ {
|
||
searchDeleteWareResults, err := api.JdAPI.SearchDeleteWare("2020-04-22", "2020-04-22", page, pageSize)
|
||
if err == nil && len(searchDeleteWareResults) > 0 {
|
||
searchResults = append(searchResults, searchDeleteWareResults...)
|
||
}
|
||
}
|
||
|
||
for _, v := range searchResults {
|
||
param := &jdapi.OpSkuParam{
|
||
TraceID: ctx.GetTrackInfo(),
|
||
OutSkuID: utils.Int2Str(v.SkuID),
|
||
FixedStatus: jdapi.SkuFixedStatusDeleted,
|
||
}
|
||
time.Sleep(time.Second * 1)
|
||
_, err = api.JdAPI.UpdateSku2(param)
|
||
if err != nil {
|
||
globals.SugarLogger.Debugf("RefreshJdDepot UpdateSku2", err.Error())
|
||
continue
|
||
}
|
||
api.JdAPI.RefreshJdDepot(v.JdID)
|
||
sql := `
|
||
UPDATE thing_map SET vendor_thing_id = ?, sync_status = ?, updated_at = NOW()
|
||
WHERE thing_type = ? AND vendor_id = ? AND vendor_org_code = ? AND deleted_at = ? AND thing_id = ?
|
||
`
|
||
sqlParams := []interface{}{v.JdID, model.SyncFlagModifiedMask, model.ThingTypeSku, model.VendorIDJD, "320406", utils.DefaultTimeValue, v.SkuID}
|
||
dao.ExecuteSQL(db, sql, sqlParams)
|
||
_, err = SyncSkus(ctx, nil, []int{0}, []string{"320406"}, nil, []int{v.SkuID}, false)
|
||
time.Sleep(time.Second * 1)
|
||
// skuIDs = append(skuIDs, v.SkuID)
|
||
}
|
||
return err
|
||
}
|
||
|
||
//标准化上传图片。
|
||
//图片是非京西图片上传到七牛云转换为京西图片
|
||
func uploadImgStandard(imgUrl string) (downloadResult string, err error) {
|
||
if resBinary, _, err := jxutils.DownloadFileByURL(imgUrl); err == nil {
|
||
if downloadURL, err := jxutils.UploadExportContent(resBinary, utils.Int64ToStr(time.Now().Unix())+"origin"+imgUrl[strings.LastIndex(imgUrl, "/")+1:len(imgUrl)]); err == nil {
|
||
if img, _, err := datares.Binary2Image(resBinary, http.DetectContentType(resBinary)); err == nil {
|
||
if img.Bounds().Dx() != datares.MainImgWidth || img.Bounds().Dy() != datares.MainImgHeight { //如果不是标准的800x800就再把图片格式化上传
|
||
if resBinary2, _, err := jxutils.DownloadFileByURL(downloadURL + model.SkuNameImgStandard); err == nil {
|
||
if downloadURL2, err := jxutils.UploadExportContent(resBinary2, utils.Int64ToStr(time.Now().Unix())+imgUrl[strings.LastIndex(imgUrl, "/")+1:len(imgUrl)]); err == nil {
|
||
downloadResult = downloadURL2
|
||
} else {
|
||
return downloadResult, err
|
||
}
|
||
} else {
|
||
return downloadResult, err
|
||
}
|
||
} else {
|
||
downloadResult = downloadURL
|
||
}
|
||
} else {
|
||
return downloadResult, err
|
||
}
|
||
} else {
|
||
return downloadResult, err
|
||
}
|
||
} else {
|
||
return downloadResult, err
|
||
}
|
||
return downloadResult, err
|
||
}
|
||
|
||
func AddSkuNameByUpc(ctx *jxcontext.Context, upc string, store *dao.StoreDetail, v *partner.SkuNameInfo) (err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
// skuBindInfos []*StoreSkuBindInfo
|
||
)
|
||
skuNames, err := dao.GetSkuNames(db, nil, []string{upc}, "", false)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
//表示我们商品库中没有这个upc商品,如果有就直接关注上
|
||
if len(skuNames) == 0 {
|
||
skuNameExt := &model.SkuNameExt{
|
||
SkuName: model.SkuName{
|
||
Upc: &upc,
|
||
Status: model.SkuStatusNormal,
|
||
CategoryID: model.NoCatCatgoryID,
|
||
IsGlobal: model.YES,
|
||
Price: int(v.SkuList[0].VendorPrice),
|
||
},
|
||
Skus: []*model.SkuWithVendor{
|
||
&model.SkuWithVendor{
|
||
Sku: &model.Sku{
|
||
Status: model.SkuStatusNormal,
|
||
},
|
||
},
|
||
},
|
||
}
|
||
//我们商品库中有这个商品,但是upc没有填,则尝试用upc去查一下
|
||
productInfos, err2 := GetJdUpcCodeByName(ctx, "", upc)
|
||
getNetUpcInfo, err2 := api.AliUpcAPI.GetNetUpcInfo(upc)
|
||
err = err2
|
||
//表示用upc也没有找到这个商品
|
||
if len(productInfos) == 0 {
|
||
if getNetUpcInfo == nil || getNetUpcInfo.SpecQuality == 0 || getNetUpcInfo.Unit == "" {
|
||
return fmt.Errorf("此商品无规格无法创建,upc :[%s] , unit: [%s], specQuality : [%v]", upc, getNetUpcInfo.Unit, getNetUpcInfo.SpecQuality)
|
||
}
|
||
if len(v.PictureList) > 0 {
|
||
skuNameExt.Img = v.PictureList[0]
|
||
} else {
|
||
img := getImgFromNet(db, upc)
|
||
if img != "" {
|
||
skuNameExt.Img = img
|
||
} else {
|
||
skuNameExt.Img = model.NOSkuNameImg
|
||
}
|
||
}
|
||
if skuNameExt.Name == "" {
|
||
skuNameExt.Name = v.SkuList[0].SkuName
|
||
} else {
|
||
skuNameExt.Name = v.Name
|
||
}
|
||
skuNameExt.Name = v.Name
|
||
skuNameExt.Unit = getNetUpcInfo.Unit
|
||
skuNameExt.Skus[0].SpecQuality = getNetUpcInfo.SpecQuality
|
||
skuNameExt.Skus[0].SpecUnit = getNetUpcInfo.SpecUnit
|
||
skuNameExt.Skus[0].Weight = utils.Float32ToInt(getNetUpcInfo.SpecQuality)
|
||
} else {
|
||
productInfo := productInfos[0]
|
||
if (productInfo.SpecQuality == 0 || productInfo.Unit == "") && (getNetUpcInfo == nil || getNetUpcInfo.SpecQuality == 0 || getNetUpcInfo.Unit == "") {
|
||
return fmt.Errorf("此商品无规格无法创建,upc :[%s] , unit: [%s], specQuality : [%v]", upc, getNetUpcInfo.Unit, getNetUpcInfo.SpecQuality)
|
||
}
|
||
if productInfo.SpecQuality == 0 {
|
||
skuNameExt.Skus[0].SpecQuality = getNetUpcInfo.SpecQuality
|
||
skuNameExt.Skus[0].Weight = utils.Float32ToInt(getNetUpcInfo.SpecQuality)
|
||
} else {
|
||
skuNameExt.Skus[0].SpecQuality = productInfo.SpecQuality
|
||
skuNameExt.Skus[0].Weight = utils.Float32ToInt(productInfo.SpecQuality)
|
||
}
|
||
if productInfo.SpecUnit == "" {
|
||
skuNameExt.Skus[0].SpecUnit = getNetUpcInfo.SpecUnit
|
||
} else {
|
||
skuNameExt.Skus[0].SpecUnit = productInfo.SpecUnit
|
||
}
|
||
if len(productInfo.ImgList) > 0 {
|
||
skuNameExt.Img = productInfo.ImgList[0]
|
||
} else {
|
||
img := getImgFromNet(db, upc)
|
||
if img != "" {
|
||
skuNameExt.Img = img
|
||
} else {
|
||
skuNameExt.Img = model.NOSkuNameImg
|
||
}
|
||
}
|
||
if productInfo.Name == "" {
|
||
if v.Name == "" {
|
||
skuNameExt.Name = v.SkuList[0].SkuName
|
||
} else {
|
||
skuNameExt.Name = v.Name
|
||
}
|
||
} else {
|
||
skuNameExt.Name = productInfo.Name
|
||
}
|
||
if productInfo.Unit == "" {
|
||
skuNameExt.Unit = getNetUpcInfo.Unit
|
||
} else {
|
||
skuNameExt.Unit = productInfo.Unit
|
||
}
|
||
}
|
||
if flag := checkAndUpdateUpc(ctx, db, skuNameExt, v, store); !flag {
|
||
if !strings.Contains(skuNameExt.Img, "image.jxc4.com") {
|
||
downloadURL, err := uploadImgStandard(skuNameExt.Img)
|
||
if err != nil {
|
||
skuNameExt.Img = model.NOSkuNameImg
|
||
} else {
|
||
skuNameExt.Img = downloadURL
|
||
}
|
||
}
|
||
if resBinary, _, err := jxutils.DownloadFileByURL(skuNameExt.Img); err == nil {
|
||
if model.ValidMimeTypes[http.DetectContentType(resBinary)] == 0 {
|
||
skuNameExt.Img = model.NOSkuNameImg
|
||
}
|
||
}
|
||
if skuNameExt.Skus[0].SpecUnit == model.SpecUnitNames[1] || skuNameExt.Skus[0].SpecUnit == model.SpecUnitNames[2] ||
|
||
skuNameExt.Skus[0].SpecUnit == "KG" || skuNameExt.Skus[0].SpecUnit == "l" {
|
||
skuNameExt.Skus[0].Weight = skuNameExt.Skus[0].Weight * 1000
|
||
}
|
||
outSkuNameExt, err := AddSkuName(ctx, skuNameExt, ctx.GetUserName())
|
||
if err != nil {
|
||
return err
|
||
}
|
||
// skuBindInfo := &StoreSkuBindInfo{
|
||
// NameID: outSkuNameExt.SkuName.ID,
|
||
// IsFocus: 1,
|
||
// UnitPrice: outSkuNameExt.SkuName.Price,
|
||
// }
|
||
// skuBindInfos = append(skuBindInfos, skuBindInfo)
|
||
// updateStoresSkusWithoutSync(ctx, db, []int{store.ID}, skuBindInfos, false)
|
||
buildStoreSkuBindInfosAndFocus(ctx, db, store, v, outSkuNameExt.ID)
|
||
}
|
||
} else {
|
||
// skuBindInfo := &StoreSkuBindInfo{
|
||
// NameID: skuNames[0].ID,
|
||
// IsFocus: 1,
|
||
// UnitPrice: skuNames[0].Price,
|
||
// }
|
||
// skuBindInfos = append(skuBindInfos, skuBindInfo)
|
||
// updateStoresSkusWithoutSync(ctx, db, []int{store.ID}, skuBindInfos, false)
|
||
buildStoreSkuBindInfosAndFocus(ctx, db, store, v, skuNames[0].ID)
|
||
}
|
||
return err
|
||
}
|
||
|
||
//该商品名,规格在库中能查询出则更新upc不插入
|
||
func checkAndUpdateUpc(ctx *jxcontext.Context, db *dao.DaoDB, skuNameExt *model.SkuNameExt, v *partner.SkuNameInfo, store *dao.StoreDetail) (flag bool) {
|
||
skuNames2, err := dao.GetSkuNames(db, nil, nil, skuNameExt.Name, false)
|
||
if err != nil {
|
||
return false
|
||
}
|
||
if len(skuNames2) == 0 {
|
||
return false
|
||
}
|
||
//表示查到了,需要把upc更新上去,没查到就要新建
|
||
if skuNameExt.SpecQuality == skuNames2[0].SpecQuality {
|
||
skuNames2[0].Upc = skuNameExt.Upc
|
||
dao.UpdateEntity(db, skuNames2[0], "Upc")
|
||
// var skuBindInfos []*StoreSkuBindInfo
|
||
// skuBindInfo := &StoreSkuBindInfo{
|
||
// NameID: skuNames2[0].ID,
|
||
// IsFocus: 1,
|
||
// UnitPrice: skuNames2[0].Price,
|
||
// }
|
||
// skuBindInfos = append(skuBindInfos, skuBindInfo)
|
||
// updateStoresSkusWithoutSync(ctx, db, []int{store.ID}, skuBindInfos, false)
|
||
buildStoreSkuBindInfosAndFocus(ctx, db, store, v, skuNames2[0].ID)
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
func getImgFromNet(db *dao.DaoDB, upc string) (img string) {
|
||
var result *aliupcapi.GetAliUpcInfoResult
|
||
upcDepot, err := dao.GetUpcDepot(db, upc)
|
||
if upcDepot == nil {
|
||
result, err = api.AliUpcAPI.GetAliUpcInfo(upc)
|
||
if err == nil {
|
||
err = dao.InsertUpcDepot(db, result)
|
||
}
|
||
} else {
|
||
result = upcDepot
|
||
}
|
||
img = result.Img
|
||
return img
|
||
}
|
||
|
||
func deleteJdsSku(db *dao.DaoDB, skuID int) (err error) {
|
||
storeBinds, err := dao.GetStoresSkusInfo(db, []int{model.JdShopMainStoreID}, []int{skuID})
|
||
if err == nil && len(storeBinds) > 0 {
|
||
err = api.JdShopAPI.DeleteSku(storeBinds[0].JdsID)
|
||
}
|
||
return err
|
||
}
|
||
|
||
func UpdateSkuExinfoMap(ctx *jxcontext.Context, nameIDs []int, imgWaterMark string, brandID, vendorID int, vendorOrgCode, exPrefix, fromTime, toTime string, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||
var (
|
||
fromTimeP time.Time
|
||
toTimeP time.Time
|
||
db = dao.GetDB()
|
||
// skuIDs []int
|
||
)
|
||
if fromTime != "" {
|
||
fromTimeP = utils.Time2Date(utils.Str2Time(fromTime))
|
||
}
|
||
if toTime != "" {
|
||
toTimeP = utils.Time2Date(utils.Str2Time(toTime))
|
||
}
|
||
if toTimeP.Before(fromTimeP) {
|
||
return "", fmt.Errorf("结束时间不可以小于开始时间!开始时间:[%v],结束时间:[%v]", fromTimeP, toTimeP)
|
||
}
|
||
task := tasksch.NewParallelTask("刷新商品前缀水印图", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx,
|
||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
nameID := batchItemList[0].(int)
|
||
skuEx := &model.SkuExinfoMap{
|
||
NameID: nameID,
|
||
ImgWatermark: imgWaterMark,
|
||
ExPrefix: exPrefix,
|
||
VendorID: vendorID,
|
||
BeginAt: fromTimeP,
|
||
EndAt: toTimeP,
|
||
BrandID: brandID,
|
||
}
|
||
dao.WrapAddIDCULDEntity(skuEx, ctx.GetUserName())
|
||
if imgWaterMark != "" {
|
||
if skuNames, err := dao.GetSkuNames(db, []int{nameID}, nil, "", false); err == nil {
|
||
if ImgMix := jxutils.MixWatermarkImg(imgWaterMark, skuNames[0].Img, &fromTimeP, &toTimeP); ImgMix != "" {
|
||
skuEx.ImgWatermarkMix = ImgMix
|
||
}
|
||
}
|
||
}
|
||
skuExs, _ := dao.GetSkuExinfos(db, []int{nameID}, []int{vendorID}, "", utils.ZeroTimeValue, utils.ZeroTimeValue)
|
||
if len(skuExs) > 0 {
|
||
skuEx2 := skuExs[0]
|
||
skuEx2.DeletedAt = time.Now()
|
||
skuEx2.LastOperator = ctx.GetUserName()
|
||
dao.UpdateEntity(db, skuEx2, "DeletedAt", "LastOperator")
|
||
dao.CreateEntity(db, skuEx)
|
||
} else {
|
||
dao.CreateEntity(db, skuEx)
|
||
}
|
||
now := utils.Time2Date(time.Now())
|
||
if now.Sub(fromTimeP) >= 0 && now.Sub(toTimeP) <= 0 {
|
||
var skuIDs []int
|
||
skuList, err2 := dao.GetSkus(db, nil, []int{nameID}, nil, nil, nil)
|
||
if err = err2; err == nil {
|
||
if len(skuList) > 0 {
|
||
for _, v := range skuList {
|
||
skuIDs = append(skuIDs, v.ID)
|
||
}
|
||
if partner.IsMultiStore(vendorID) {
|
||
for _, v := range skuIDs {
|
||
OnUpdateThing(ctx, db, nil, int64(v), model.ThingTypeSku)
|
||
}
|
||
} else {
|
||
var storeIDs []int
|
||
if brandID != 0 {
|
||
if stores, _ := dao.GetStoreList(db, nil, nil, nil, []int{brandID}, nil, ""); len(stores) > 0 {
|
||
for _, v := range stores {
|
||
storeIDs = append(storeIDs, v.ID)
|
||
}
|
||
}
|
||
}
|
||
SetStoreSkuSyncStatus2(db, storeIDs, []int{vendorID}, skuIDs, model.SyncFlagModifiedMask)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return retVal, err
|
||
}, nameIDs)
|
||
tasksch.HandleTask(task, nil, true).Run()
|
||
if isAsync {
|
||
hint = task.GetID()
|
||
} else {
|
||
_, err = task.GetResult(0)
|
||
hint = "1"
|
||
}
|
||
return hint, err
|
||
}
|
||
|
||
func GetVendorCategoryMap(ctx *jxcontext.Context, parentID, level, vendorID int, vendorOrgCode string) (vendorMaps []*model.VendorCategoryMap, err error) {
|
||
db := dao.GetDB()
|
||
vendorMaps, err = dao.GetVendorCategoryMap(db, parentID, level, vendorID, vendorOrgCode, 0)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return vendorMaps, err
|
||
}
|
||
|
||
func AddVendorCategoryMap(ctx *jxcontext.Context, vendorCategoryMap *model.VendorCategoryMap) (result *model.VendorCategoryMap, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
)
|
||
if vendorCategoryMap.Level != 1 {
|
||
storeCatMaps, _ := dao.GetVendorCategoryMap(db, -1, 0, vendorCategoryMap.VendorID, vendorCategoryMap.VendorOrgCode, vendorCategoryMap.CategoryID)
|
||
if len(storeCatMaps) > 0 {
|
||
return nil, fmt.Errorf("已存在绑定的京西分类,分类名:[%v]", storeCatMaps[0].VendorCategoryName)
|
||
}
|
||
}
|
||
vendorOrgCodes, _ := dao.GetVendorOrgCode(db, vendorCategoryMap.VendorID, vendorCategoryMap.VendorOrgCode, model.VendorOrgTypePlatform)
|
||
vendorCategoryMap.VendorCategoryName = strings.Trim(vendorCategoryMap.VendorCategoryName, " ")
|
||
dao.WrapAddIDCULDEntity(vendorCategoryMap, ctx.GetUserName())
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if err = dao.CreateEntity(db, vendorCategoryMap); err != nil {
|
||
dao.Rollback(db)
|
||
return nil, err
|
||
}
|
||
//如果传了京西绑定,要去thingmap里改同步标志
|
||
if vendorCategoryMap.CategoryID != 0 {
|
||
if err = OnCreateThing(ctx, db, vendorOrgCodes, int64(vendorCategoryMap.CategoryID), model.ThingTypeCategory, model.SyncFlagNewMask, true); err != nil {
|
||
dao.Rollback(db)
|
||
return nil, err
|
||
}
|
||
}
|
||
dao.Commit(db)
|
||
result = vendorCategoryMap
|
||
if vendorCategoryMap.CategoryID != 0 {
|
||
SyncCategories(ctx, nil, []int{vendorCategoryMap.VendorID}, []string{vendorCategoryMap.VendorOrgCode}, []int{vendorCategoryMap.CategoryID}, true)
|
||
// _, err = CurVendorSync.SyncCategory(ctx, nil, vendorCategoryMap.CategoryID, false, ctx.GetUserName())
|
||
}
|
||
return result, err
|
||
}
|
||
|
||
func UpdateVendorCategoryMap(ctx *jxcontext.Context, ID int, vendorCategoryMap *model.VendorCategoryMap, isDelete bool) (num int64, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
valid = make(map[string]interface{})
|
||
vendorCategoryMap2 = &model.VendorCategoryMap{}
|
||
vendorCategoryID int
|
||
)
|
||
vendorCategoryMap2.ID = ID
|
||
if err = dao.GetEntity(db, vendorCategoryMap2); err != nil {
|
||
return 0, err
|
||
}
|
||
if vendorCategoryMap.VendorCategoryName != "" {
|
||
valid["vendorCategoryName"] = vendorCategoryMap.VendorCategoryName
|
||
}
|
||
if vendorCategoryMap.CategoryID != 0 {
|
||
valid["categoryID"] = vendorCategoryMap.CategoryID
|
||
if !isDelete {
|
||
storeCatMaps, _ := dao.GetVendorCategoryMap(db, -1, 0, vendorCategoryMap2.VendorID, vendorCategoryMap2.VendorOrgCode, vendorCategoryMap.CategoryID)
|
||
if len(storeCatMaps) > 0 {
|
||
for _, v := range storeCatMaps {
|
||
if v.ID != ID {
|
||
return 0, fmt.Errorf("已存在绑定的京西分类,分类名:[%v]", storeCatMaps[0].VendorCategoryName)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
vendorCategoryID = vendorCategoryMap.CategoryID
|
||
} else {
|
||
vendorCategoryID = vendorCategoryMap2.CategoryID
|
||
}
|
||
if vendorCategoryMap.Level != 0 {
|
||
valid["level"] = vendorCategoryMap.Level
|
||
if vendorCategoryMap.Level == 2 {
|
||
cat2, _ := dao.GetCategories(db, -1, 0, []int{vendorCategoryMap.CategoryID}, false)
|
||
if len(cat2) > 0 {
|
||
if cat2[0].ParentID != vendorCategoryMap.ParentID {
|
||
return 0, fmt.Errorf("此二级分类只能绑定到对应一级分类下!")
|
||
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if isDelete {
|
||
valid["deletedAt"] = time.Now()
|
||
valid["updatedAt"] = time.Now()
|
||
valid["lastOperator"] = ctx.GetUserName()
|
||
//如果是1级分类则删除下面的子分类
|
||
var catIDs []int
|
||
if vendorCategoryMap2.Level == 1 {
|
||
storeCatMaps, _ := dao.GetVendorCategoryMap(db, vendorCategoryMap2.CategoryID, 2, vendorCategoryMap2.VendorID, vendorCategoryMap2.VendorOrgCode, 0)
|
||
if len(storeCatMaps) > 0 {
|
||
for _, v := range storeCatMaps {
|
||
catIDs = append(catIDs, v.CategoryID)
|
||
v.DeletedAt = time.Now()
|
||
v.LastOperator = ctx.GetUserName()
|
||
dao.UpdateEntity(db, v, "DeletedAt", "LastOperator")
|
||
}
|
||
}
|
||
}
|
||
var countInfos []*struct{ Ct int }
|
||
db := dao.GetDB()
|
||
if err = dao.GetRows(db, &countInfos, `
|
||
SELECT COUNT(*) ct
|
||
FROM sku t1
|
||
WHERE t1.category_id = ? AND t1.deleted_at = ?
|
||
UNION ALL
|
||
SELECT COUNT(*) ct
|
||
FROM sku_name t1
|
||
WHERE t1.category_id = ? AND t1.deleted_at = ?
|
||
UNION ALL
|
||
SELECT COUNT(*) ct
|
||
FROM sku_category t1
|
||
WHERE t1.parent_id = ? AND t1.deleted_at = ?
|
||
`, vendorCategoryMap2.CategoryID, utils.DefaultTimeValue, vendorCategoryMap2.CategoryID, utils.DefaultTimeValue, vendorCategoryMap2.CategoryID, utils.DefaultTimeValue, &countInfos); err == nil {
|
||
if countInfos[0].Ct != 0 {
|
||
return 0, errors.New("还有商品使用此类别,不能删除")
|
||
} else if countInfos[1].Ct != 0 {
|
||
return 0, errors.New("还有商品名使用此类别,不能删除")
|
||
} else if countInfos[2].Ct != 0 {
|
||
return 0, errors.New("还有商品类别使用此类别,不能删除")
|
||
}
|
||
}
|
||
}
|
||
vendorOrgCodes, err := dao.GetVendorOrgCode(db, vendorCategoryMap2.VendorID, vendorCategoryMap2.VendorOrgCode, model.VendorOrgTypePlatform)
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if num, err = dao.UpdateEntityLogically(db, vendorCategoryMap2, valid, ctx.GetUserName(), nil); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
if err = OnUpdateThing(ctx, db, vendorOrgCodes, int64(vendorCategoryID), model.ThingTypeCategory); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
dao.Commit(db)
|
||
SyncCategories(ctx, nil, []int{vendorCategoryMap.VendorID}, []string{vendorCategoryMap.VendorOrgCode}, []int{vendorCategoryID}, true)
|
||
return num, err
|
||
}
|
||
|
||
func ReorderVendorCategories(ctx *jxcontext.Context, parentID, vendorID int, vendorOrgCode string, categoryIDs []int) (err error) {
|
||
var (
|
||
vendorCatsMap []*model.VendorCategoryMap
|
||
)
|
||
db := dao.GetDB()
|
||
vendorCatsMap, err = dao.GetVendorCategoryMap(db, parentID, 0, vendorID, vendorOrgCode, 0)
|
||
catsLen := len(vendorCatsMap)
|
||
if catsLen != len(categoryIDs) {
|
||
return ErrInputCatsDoesntMatch
|
||
}
|
||
catsMap := make(map[int]*model.VendorCategoryMap, catsLen)
|
||
for _, cat := range vendorCatsMap {
|
||
catsMap[cat.CategoryID] = cat
|
||
}
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
for k, v := range categoryIDs {
|
||
if catsMap[v] == nil {
|
||
dao.Rollback(db)
|
||
return fmt.Errorf("分类:%d不在%d分类下", v, parentID)
|
||
}
|
||
catsMap[v].VendorCategorySeq = k
|
||
catsMap[v].LastOperator = ctx.GetUserName()
|
||
if _, err = dao.UpdateEntity(db, catsMap[v]); err != nil {
|
||
dao.Rollback(db)
|
||
return err
|
||
}
|
||
}
|
||
dao.Commit(db)
|
||
err = SyncReorderCategories2(ctx, parentID, vendorID, vendorOrgCode)
|
||
return err
|
||
}
|
||
|
||
func LoadStoreVendorCategories(ctx *jxcontext.Context, vendorOrgCode string, vendorID, storeID int) (err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
)
|
||
|
||
storeCats, err := dao.GetStoreCategoryMap(db, -1, 0, storeID, 0)
|
||
if len(storeCats) == 0 {
|
||
return fmt.Errorf("未查询到该门店有门店分类,请重新选择! [%v]", storeID)
|
||
}
|
||
vendorOrgCodes, _ := dao.GetVendorOrgCode(db, vendorID, vendorOrgCode, model.VendorOrgTypePlatform)
|
||
if vendorCatMap, _ := dao.GetVendorCategoryMap(db, -1, 0, vendorID, vendorOrgCode, 0); len(vendorCatMap) > 0 {
|
||
return fmt.Errorf("该账号下已有分类,请在这里修改!")
|
||
}
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
sql := `
|
||
DELETE FROM vendor_category_map WHERE vendor_id = ? AND vendor_org_code = ?
|
||
`
|
||
sqlParams := []interface{}{
|
||
vendorID, vendorOrgCode,
|
||
}
|
||
if _, err = dao.ExecuteSQL(db, sql, sqlParams); err != nil {
|
||
dao.Rollback(db)
|
||
return err
|
||
}
|
||
sql2 := `
|
||
INSERT INTO vendor_category_map
|
||
(created_at, updated_at, last_operator, deleted_at, vendor_id, vendor_org_code, category_id, vendor_category_name, vendor_category_seq, level, parent_id)
|
||
SELECT ?, ?, ?, ?, ?, ?, category_id, store_category_name, store_category_seq, level, parent_id
|
||
FROM store_category_map
|
||
WHERE deleted_at = ?
|
||
AND store_id = ?
|
||
`
|
||
sqlParams2 := []interface{}{
|
||
time.Now(), time.Now(), ctx.GetUserName(), utils.DefaultTimeValue,
|
||
vendorID, vendorOrgCode,
|
||
utils.DefaultTimeValue,
|
||
storeID,
|
||
}
|
||
if _, err = dao.ExecuteSQL(db, sql2, sqlParams2); err != nil {
|
||
dao.Rollback(db)
|
||
return err
|
||
}
|
||
dao.Commit(db)
|
||
catList, _ := dao.GetSkuCategoryWithVendor(db, []int{vendorID}, []string{vendorOrgCode}, -1, nil, false)
|
||
for _, v := range storeCats {
|
||
if len(catList) > 0 {
|
||
OnUpdateThing(ctx, db, vendorOrgCodes, int64(v.CategoryID), model.ThingTypeCategory)
|
||
} else {
|
||
OnCreateThing(ctx, db, vendorOrgCodes, int64(v.CategoryID), model.ThingTypeCategory, model.SyncFlagNewMask, true)
|
||
}
|
||
}
|
||
if _, err = SyncCategories(ctx, nil, []int{vendorID}, []string{vendorOrgCode}, nil, false); err == nil {
|
||
SyncReorderCategories2(ctx, 0, vendorID, vendorOrgCode)
|
||
}
|
||
return err
|
||
}
|
||
|
||
func RefreshNoImgSku(ctx *jxcontext.Context) (err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
skuNames []*model.SkuName
|
||
)
|
||
sql := `
|
||
SELECT * FROM sku_name WHERE deleted_at = ? AND upc <> '' AND img2 = ''
|
||
`
|
||
sqlParams := []interface{}{
|
||
utils.DefaultTimeValue,
|
||
}
|
||
dao.GetRows(db, &skuNames, sql, sqlParams)
|
||
task := tasksch.NewParallelTask("uuuuu", tasksch.NewParallelConfig().SetParallelCount(20).SetIsContinueWhenError(true), ctx,
|
||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
v := batchItemList[0].(*model.SkuName)
|
||
if v.Upc != nil {
|
||
productInfos, _ := api.JdAPI.GetJdUpcCodeByName("", *v.Upc, 1, 30)
|
||
if len(productInfos) > 0 {
|
||
productInfo := productInfos[0]
|
||
if len(productInfo.ImgList) >= 5 {
|
||
v.Img = productInfo.ImgList[0]
|
||
v.Img2 = productInfo.ImgList[1]
|
||
v.Img3 = productInfo.ImgList[2]
|
||
v.Img4 = productInfo.ImgList[3]
|
||
v.Img5 = productInfo.ImgList[4]
|
||
} else {
|
||
result, _ := api.MtwmAPI.GetStandardProductListWithCond(*v.Upc)
|
||
if result != nil {
|
||
imgs := strings.Split(result.Pic, ",")
|
||
if len(imgs) >= 5 {
|
||
v.Img = imgs[0]
|
||
v.Img2 = imgs[1]
|
||
v.Img3 = imgs[2]
|
||
v.Img4 = imgs[3]
|
||
v.Img5 = imgs[4]
|
||
} else {
|
||
if len(imgs) > len(productInfo.ImgList) {
|
||
setImgs2(v, imgs)
|
||
} else {
|
||
setImgs2(v, productInfo.ImgList)
|
||
}
|
||
}
|
||
} else {
|
||
setImgs2(v, productInfo.ImgList)
|
||
}
|
||
}
|
||
} else {
|
||
result, _ := api.MtwmAPI.GetStandardProductListWithCond(*v.Upc)
|
||
if result != nil {
|
||
imgs := strings.Split(result.Pic, ",")
|
||
setImgs2(v, imgs)
|
||
}
|
||
}
|
||
dao.UpdateEntity(db, v, "Img", "Img2", "Img3", "Img4", "Img5")
|
||
}
|
||
return retVal, err
|
||
}, skuNames)
|
||
tasksch.HandleTask(task, nil, true).Run()
|
||
_, err = task.GetResult(0)
|
||
return err
|
||
}
|
||
|
||
func setImgs(v *model.SkuNameExt, imgs []string) (err error) {
|
||
switch len(imgs) {
|
||
case 0:
|
||
case 1:
|
||
v.Img = imgs[0]
|
||
case 2:
|
||
v.Img = imgs[0]
|
||
v.Img2 = imgs[1]
|
||
case 3:
|
||
v.Img = imgs[0]
|
||
v.Img2 = imgs[1]
|
||
v.Img3 = imgs[2]
|
||
case 4:
|
||
v.Img = imgs[0]
|
||
v.Img2 = imgs[1]
|
||
v.Img3 = imgs[2]
|
||
v.Img4 = imgs[3]
|
||
case 5:
|
||
v.Img = imgs[0]
|
||
v.Img2 = imgs[1]
|
||
v.Img3 = imgs[2]
|
||
v.Img4 = imgs[3]
|
||
v.Img5 = imgs[4]
|
||
default:
|
||
v.Img = imgs[0]
|
||
v.Img2 = imgs[1]
|
||
v.Img3 = imgs[2]
|
||
v.Img4 = imgs[3]
|
||
v.Img5 = imgs[4]
|
||
}
|
||
return err
|
||
}
|
||
|
||
func setImgs2(v *model.SkuName, imgs []string) (err error) {
|
||
switch len(imgs) {
|
||
case 0:
|
||
case 1:
|
||
v.Img = imgs[0]
|
||
case 2:
|
||
v.Img = imgs[0]
|
||
v.Img2 = imgs[1]
|
||
case 3:
|
||
v.Img = imgs[0]
|
||
v.Img2 = imgs[1]
|
||
v.Img3 = imgs[2]
|
||
case 4:
|
||
v.Img = imgs[0]
|
||
v.Img2 = imgs[1]
|
||
v.Img3 = imgs[2]
|
||
v.Img4 = imgs[3]
|
||
case 5:
|
||
v.Img = imgs[0]
|
||
v.Img2 = imgs[1]
|
||
v.Img3 = imgs[2]
|
||
v.Img4 = imgs[3]
|
||
v.Img5 = imgs[4]
|
||
default:
|
||
v.Img = imgs[0]
|
||
v.Img2 = imgs[1]
|
||
v.Img3 = imgs[2]
|
||
v.Img4 = imgs[3]
|
||
v.Img5 = imgs[4]
|
||
}
|
||
return err
|
||
}
|