Files
jx-callback/business/jxstore/cms/sku.go
2018-09-13 11:29:28 +08:00

459 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package cms
import (
"errors"
"strconv"
"strings"
"time"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/globals"
)
type SkuNameExt struct {
model.SkuName
Skus []*model.Sku `orm:"-" json:"skus"`
SkusStr string `json:"-"`
Places []*model.SkuNamePlaceBind `orm:"-" json:"places"`
PlacesStr string `json:"-"`
}
type SkuNamesInfo struct {
TotalCount int `json:"totalCount"`
SkuNames []*SkuNameExt `json:"skuNames"`
}
var (
ErrInputCatsDoesntMatch = errors.New("输入的类别列表不合法需要输入一个父ID下的所有子类别")
)
// parentID 为-1表示所有
func GetVendorCategories(vendorID int, parentID int) (vendorCats []*model.SkuVendorCategory, err error) {
cond := map[string]interface{}{
model.FieldVendorID: vendorID,
}
if parentID != -1 {
cond[model.FieldParentID] = parentID
}
return vendorCats, dao.GetEntities(nil, &vendorCats, cond, false)
}
// parentID 为-1表示所有
func GetCategories(parentID int) (cats []*model.SkuCategory, err error) {
if parentID == -1 {
return cats, dao.GetEntities(nil, &cats, nil, false)
}
return cats, dao.GetEntities(nil, &cats, utils.Params2Map(model.FieldParentID, parentID), false)
}
func AddCategory(cat *model.SkuCategory, userName string) (outCat *model.SkuCategory, err error) {
dao.WrapAddIDCULDEntity(cat, userName)
cat.JdSyncStatus = model.SyncFlagNewMask
if err = dao.CreateEntity(nil, cat); err == nil {
outCat = cat
err = CurVendorSync.SyncCategory(nil, cat.ID, false, userName)
}
return outCat, err
}
func UpdateCategory(categoryID int, payload map[string]interface{}, userName string) (num int64, err error) {
cat := &model.SkuCategory{}
cat.ID = categoryID
valid := dao.NormalMakeMapByStructObject(payload, cat, userName)
if len(valid) > 0 {
valid[model.FieldJdSyncStatus] = model.SyncFlagModifiedMask
db := dao.GetDB()
if num, err = dao.UpdateEntityByKV(db, cat, valid, nil); err == nil {
err = CurVendorSync.SyncCategory(db, categoryID, false, userName)
}
}
return num, err
}
func ReorderCategories(parentID int, categoryIDs []int, userName string) (err error) {
var cats []*model.SkuCategory
parentCat := &model.SkuCategory{}
parentCat.ID = parentID
db := dao.GetDB()
if err = dao.GetEntity(db, parentCat); err == nil {
if err = dao.GetEntities(db, &cats, utils.Params2Map(model.FieldParentID, parentID), false); err == nil {
catsLen := len(cats)
if catsLen != len(categoryIDs) {
return ErrInputCatsDoesntMatch
}
catsMap := make(map[int]*model.SkuCategory, catsLen)
for _, cat := range cats {
catsMap[cat.ID] = cat
}
for k, v := range categoryIDs {
catsMap[v].Seq = k * 5
// catsMap[v].JdSyncStatus = model.SyncFlagModifiedMask
if _, err = dao.UpdateEntity(db, catsMap[v], "Seq"); err != nil {
break
}
}
// todo 这里应该也需要先置标记
if err == nil {
err = GetPurchaseHandler(model.VendorIDJD).ReorderCategories(parentCat, userName)
}
}
}
return err
}
func DeleteCategory(categoryID int, isForce bool, 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 = ?
UNION ALL
SELECT COUNT(*) ct
FROM sku_name t1
WHERE t1.category_id = ?
UNION ALL
SELECT COUNT(*) ct
FROM sku_category t1
WHERE t1.parent_id = ?
`, categoryID, categoryID, categoryID, &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("还有商品类别使用此类别,不能删除")
}
if num, err = dao.DeleteEntityLogically(db, cat, nil, userName, utils.Params2Map(model.FieldJdSyncStatus, model.SyncFlagDeletedMask)); err == nil && num == 1 {
err = CurVendorSync.SyncCategory(db, cat.ID, false, userName)
}
}
return num, err
}
func GetSkuNames(keyword string, 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 = '1970-01-01 00:00:00'
LEFT JOIN sku_name_place_bind t3 ON t1.id = t3.name_id
WHERE t1.deleted_at = '1970-01-01 00:00:00'`
sqlParams := make([]interface{}, 0)
if keyword != "" {
keywordLike := "%" + keyword + "%"
sql += " AND (t1.name LIKE ? OR t1.prefix LIKE ? OR t1.comment LIKE ?"
sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike)
if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil {
sql += " OR t2.jd_id = ? OR t1.id = ? OR t1.category_id = ?"
sqlParams = append(sqlParams, keywordInt64, keywordInt64, keywordInt64)
}
sql += ")"
}
if params["nameID"] != nil {
sql += " AND t1.id = ?"
sqlParams = append(sqlParams, params["nameID"].(int))
}
if params["categoryID"] != nil {
cat := &model.SkuCategory{}
cat.ID = params["categoryID"].(int)
if err = dao.GetEntity(db, cat); err != nil {
return nil, err
}
if cat.Level == 1 {
sql += " AND t1.category_id IN (SELECT id FROM sku_category WHERE parent_id = ?)"
} else {
sql += " AND t1.category_id = ?"
}
sqlParams = append(sqlParams, cat.ID)
}
if params["jdID"] != nil {
sql += " AND t1.jd_id = ?"
sqlParams = append(sqlParams, params["jdID"].(int))
}
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["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)
}
sql += `
GROUP BY
t1.id,
t1.created_at,
t1.updated_at,
t1.last_operator,
t1.prefix,
t1.name,
t1.comment,
t1.brand_id,
t1.category_id,
t1.is_global,
t1.unit,
t1.price,
t1.img,
t1.elm_img_hash_code
`
sqlData := `
SELECT
SQL_CALC_FOUND_ROWS
t1.id,
t1.created_at,
t1.updated_at,
t1.last_operator,
t1.prefix,
t1.name,
t1.comment,
t1.brand_id,
t1.category_id,
t1.is_global,
t1.unit,
t1.price,
t1.img,
t1.elm_img_hash_code,
CONCAT("[", GROUP_CONCAT(DISTINCT CONCAT('{"id":', t2.id, ',"status":', t2.status, ',"createdAt":"', CONCAT(REPLACE(t2.created_at," ","T"),"+08:00"), '","updatedAt":"', CONCAT(REPLACE(t2.updated_at," ","T"),"+08:00"), '","lastOperator":"', t2.last_operator, '","specQuality":', t2.spec_quality, ',"specUnit":"', t2.spec_unit, '","weight":', t2.weight, ',"jdID":', t2.jd_id, ',"categoryID":', t2.category_id, ',"nameID":', t2.name_id, "}")), "]") skus_str,
CONCAT("[", GROUP_CONCAT(DISTINCT CONCAT('{"id":', t3.id, ',"createdAt":"', CONCAT(REPLACE(t3.created_at," ","T"),"+08:00"), '","updatedAt":"', CONCAT(REPLACE(t3.updated_at," ","T"),"+08:00"), '","lastOperator":"', t3.last_operator, '","nameID":', t3.name_id, ',"placeCode":', t3.place_code, "}")), "]") places_str
` + sql + `
ORDER BY t1.id
LIMIT ? OFFSET ?`
if pageSize == 0 {
pageSize = model.DefPageSize
}
if offset < 0 {
offset = 0
}
sqlParams = append(sqlParams, pageSize, offset)
skuNamesInfo = &SkuNamesInfo{}
globals.SugarLogger.Debug(sqlData)
if err = dao.GetRows(db, &skuNamesInfo.SkuNames, sqlData, sqlParams...); err == nil {
countInfo := &struct{ Ct int }{}
if err = dao.GetRow(db, countInfo, "SELECT FOUND_ROWS() ct"); err == nil {
skuNamesInfo.TotalCount = countInfo.Ct
for _, skuName := range skuNamesInfo.SkuNames {
if skuName.SkusStr != "" {
if err = utils.UnmarshalUseNumber([]byte(skuName.SkusStr), &skuName.Skus); err != nil {
break
}
}
if skuName.PlacesStr != "" {
if err = utils.UnmarshalUseNumber([]byte(skuName.PlacesStr), &skuName.Places); err != nil {
break
}
}
}
}
}
return skuNamesInfo, err
}
func AddSkuName(skuNameExt *SkuNameExt, userName string) (outSkuNameExt *SkuNameExt, err error) {
if skuNameExt.CategoryID == 0 {
return nil, errors.New("CategoryID不能为空")
}
db := dao.GetDB()
dao.Begin(db)
dao.WrapAddIDCULDEntity(&skuNameExt.SkuName, userName)
if err = dao.CreateEntity(db, &skuNameExt.SkuName); err != nil {
dao.Rollback(db)
return nil, err
}
for _, sku := range skuNameExt.Skus {
dao.WrapAddIDCULDEntity(sku, userName)
sku.NameID = skuNameExt.ID
sku.JdSyncStatus = model.SyncFlagNewMask
if err = dao.CreateEntity(db, sku); err != nil {
dao.Rollback(db)
return nil, err
}
}
for _, placeBind := range skuNameExt.Places {
dao.WrapAddIDCULEntity(placeBind, userName)
placeBind.NameID = skuNameExt.ID
if err = dao.CreateEntity(db, placeBind); err != nil {
dao.Rollback(db)
return nil, err
}
}
dao.Commit(db)
tmpInfo, err := GetSkuNames("", utils.Params2Map("id", 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(db, outSkuNameExt.SkuName.ID, -1, false, userName)
return outSkuNameExt, err
}
func UpdateSkuName(nameID int, payload map[string]interface{}, userName string) (num int64, err error) {
skuName := &model.SkuName{}
skuName.ID = nameID
valid := dao.NormalMakeMapByStructObject(payload, skuName, userName)
if len(valid) > 0 {
db := dao.GetDB()
if num, err = dao.UpdateEntityByKV(db, skuName, valid, nil); err == nil && num == 1 {
sku := &model.Sku{}
_, err2 := dao.UpdateEntityByKV(db, sku, utils.Params2Map(model.FieldJdSyncStatus, model.SyncFlagModifiedMask), utils.Params2Map(model.FieldNameID, skuName.ID))
if err = err2; err == nil {
if err = dao.GetEntity(db, skuName); err == nil {
err = CurVendorSync.SyncSku(db, skuName.ID, -1, false, userName)
}
}
}
}
return num, err
}
func DeleteSkuName(nameID int, userName string) (num int64, err error) {
db := dao.GetDB()
dao.Begin(db)
skuName := &model.SkuName{}
skuName.ID = nameID
if num, err = dao.DeleteEntityLogically(db, skuName, nil, userName, nil); err == nil && num == 1 {
dummy := &model.Sku{}
num2, err2 := dao.UpdateEntityByKV(db, dummy, map[string]interface{}{
model.FieldDeletedAt: time.Now(),
model.FieldLastOperator: userName,
model.FieldJdSyncStatus: model.SyncFlagDeletedMask,
"Status": model.SkuStatusDeleted,
}, utils.Params2Map(model.FieldNameID, skuName.ID))
if err2 == nil {
dao.Commit(db)
if num2 > 0 {
err = CurVendorSync.SyncSku(db, skuName.ID, -1, false, userName)
}
return num, err
}
}
dao.Rollback(db)
return num, err
}
func AddSku(nameID int, sku *model.Sku, userName string) (outSkuNameExt *SkuNameExt, err error) {
db := dao.GetDB()
dao.WrapAddIDCULDEntity(sku, userName)
sku.JdSyncStatus = model.SyncFlagNewMask
sku.NameID = nameID
if err = dao.CreateEntity(db, sku); err == nil {
result, err2 := GetSkuNames("", utils.Params2Map("skuID", sku.ID), 0, 0)
if err = err2; err == nil {
if result.TotalCount == 1 {
outSkuNameExt = result.SkuNames[0]
err = CurVendorSync.SyncSku(db, outSkuNameExt.SkuName.ID, sku.ID, false, userName)
} else {
err = ErrEntityNotExist
}
}
}
return outSkuNameExt, err
}
func UpdateSku(skuID int, payload map[string]interface{}, userName string) (num int64, err error) {
sku := &model.Sku{}
sku.ID = skuID
valid := dao.NormalMakeMapByStructObject(payload, sku, userName)
if len(valid) > 0 {
valid[model.FieldJdSyncStatus] = model.SyncFlagModifiedMask
db := dao.GetDB()
if num, err = dao.UpdateEntityByKV(db, sku, valid, nil); err == nil {
if num == 1 {
err = CurVendorSync.SyncSku(db, -1, sku.ID, false, userName)
} else {
err = ErrEntityNotExist
}
}
}
return num, err
}
func DeleteSku(skuID int, userName string) (num int64, err error) {
db := dao.GetDB()
sku := &model.Sku{}
sku.ID = skuID
if num, err = dao.DeleteEntityLogically(db, sku, nil, userName, nil); err == nil {
if num == 1 {
err = CurVendorSync.SyncSku(db, -1, sku.ID, false, userName)
} else {
err = ErrEntityNotExist
}
}
return num, err
}
func AddSkuNamePlace(nameID, placeCode int, userName string) (outPlaceBind *model.SkuNamePlaceBind, err error) {
db := dao.GetDB()
placeBind := &model.SkuNamePlaceBind{
NameID: nameID,
PlaceCode: placeCode,
}
dao.WrapAddIDCULEntity(placeBind, userName)
if err = dao.CreateEntity(db, placeBind); err == nil {
err = CurVendorSync.SyncSku(db, nameID, -1, false, userName)
}
return placeBind, err
}
func DeleteSkuNamePlace(nameID, placeCode int, userName string) (num int64, err error) {
db := dao.GetDB()
placeBind := &model.SkuNamePlaceBind{}
placeBind.NameID = nameID
placeBind.PlaceCode = placeCode
if num, err = dao.DeleteEntity(db, placeBind, model.FieldNameID, model.FieldPlaceCode); err == nil {
if num == 1 {
err = CurVendorSync.SyncSku(db, nameID, -1, false, userName)
} else {
err = ErrEntityNotExist
}
}
return num, err
}