Files
jx-callback/business/jxstore/cms/store_sku.go
2018-09-20 10:35:55 +08:00

353 lines
10 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 (
"math"
"strconv"
"strings"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
)
// GetStoreSkus用
type StoreSkuNameExt struct {
model.SkuName
UnitPrice int `json:"unitPrice"`
Skus []map[string]interface{} `orm:"-" json:"skus"`
SkusStr string `json:"-"`
}
// GetStoreSkus用
type StoreSkuNamesInfo struct {
TotalCount int `json:"totalCount"`
SkuNames []*StoreSkuNameExt `json:"skuNames"`
}
// UpdateStoreSku用API调用时
type StoreSkuBindSkuInfo struct {
SubStoreID int `json:"subStoreID"`
SkuID int `json:"skuID"`
IsFocus int `json:"isFocus"` // -1不关注0忽略1关注
IsSale int `json:"isSale"` // -1不可售0忽略1可售
ElmID int64 `json:"elmID"`
EbaiID int64 `json:"ebaiID"`
}
// UpdateStoreSku用API调用时
type StoreSkuBindInfo struct {
NameID int `json:"nameID"`
UnitPrice int `json:"unitPrice"`
Skus []*StoreSkuBindSkuInfo `json:"skus"`
}
type tStoreSkuBindAndSpec struct {
model.StoreSkuBind
SpecQuality float32
SpecUnit string
}
func GetStoreSkus(storeID int, isFocused bool, keyword string, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *StoreSkuNamesInfo, err error) {
db := dao.GetDB()
sql := `
FROM sku_name t1
JOIN sku t2 ON t1.id = t2.name_id AND t2.deleted_at = '1970-01-01 00:00:00'
LEFT JOIN store_sku_bind t4 ON t4.sku_id = t2.id AND t4.deleted_at = '1970-01-01 00:00:00' AND t4.store_id = ?
WHERE t1.deleted_at = '1970-01-01 00:00:00'
`
if isFocused {
sql += " AND t4.sku_id IS NOT NULL"
} else {
sql += " AND t4.sku_id IS NULL"
}
sqlParams := []interface{}{
storeID,
}
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 t4.id = ?"
sqlParams = append(sqlParams, 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 params["skuID"] != nil {
skuID, ok := params["skuID"].(int)
if ok {
sql += " AND t2.id = ?"
sqlParams = append(sqlParams, skuID)
} else {
skuIDs := params["skuID"].([]interface{})
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 <= ? AND t4.status >= ? AND t4.status <= ?"
sqlParams = append(sqlParams, fromStatus, toStatus, fromStatus, toStatus)
}
sql += `
GROUP BY
t1.id,
t1.created_at,
t1.updated_at,
t1.last_operator,
t1.deleted_at,
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.deleted_at,
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(t4.created_at," ","T"),"+08:00"), '","updatedAt":"', CONCAT(REPLACE(t4.updated_at," ","T"),"+08:00"),
'","lastOperator":"', t4.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, ',"subStoreID":', IF(t4.sub_store_id IS NULL, 0, t4.sub_store_id),
',"price":', IF(t4.price IS NULL, 0, t4.price), ',"unitPrice":', IF(t4.unit_price IS NULL, 0, t4.unit_price),
',"storeSkuStatus":', IF(t4.status IS NULL, 0, t4.status), "}")), "]") skus_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 = &StoreSkuNamesInfo{}
// globals.SugarLogger.Debug(sqlData)
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
dao.Rollback(db)
panic(r)
}
}()
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 len(skuName.Skus) > 0 {
skuName.UnitPrice = int(utils.MustInterface2Int64(skuName.Skus[0]["unitPrice"]))
for _, v := range skuName.Skus {
delete(v, "unitPrice")
}
}
}
}
}
}
dao.Commit(db)
return skuNamesInfo, err
}
func UpdateStoreSku(storeID int, skuBindInfo *StoreSkuBindInfo, userName string) (num int64, err error) {
db := dao.GetDB()
skuBinds := skuBindInfo.Skus
var existBinds []*tStoreSkuBindAndSpec
addNum, delNum, updateNum := 0, 0, 0
if err = dao.GetRows(db, &existBinds, `
SELECT t1.*, t2.spec_quality, t2.spec_unit
FROM store_sku_bind t1
JOIN sku t2 ON t1.sku_id = t2.id
WHERE store_id = ?
AND t2.name_id = ?`, storeID, skuBindInfo.NameID); err == nil {
skuIDs := make([]int, len(existBinds))
for k, v := range existBinds {
skuIDs[k] = v.SkuID
}
existBindsMap := make(map[int]*model.StoreSkuBind, len(existBinds))
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
dao.Rollback(db)
panic(r)
}
}()
unitPrice := 0
if skuBindInfo.UnitPrice != 0 {
unitPrice = skuBindInfo.UnitPrice
} else {
unitPrice = existBinds[0].UnitPrice
}
for _, v := range existBinds {
if skuBindInfo.UnitPrice != 0 {
v.UnitPrice = unitPrice
v.Price = calStoreSkuPrice(unitPrice, v.SpecQuality, v.SpecUnit)
v.JdSyncStatus |= model.SyncFlagPriceMask
v.ElmSyncStatus |= model.SyncFlagPriceMask
v.EbaiSyncStatus |= model.SyncFlagPriceMask
dao.WrapUpdateULEntity(v, userName)
if _, err2 := dao.UpdateEntity(db, &v.StoreSkuBind); err2 != nil {
dao.Rollback(db)
return 0, err2
}
}
existBindsMap[v.SkuID] = &v.StoreSkuBind
}
for _, v := range skuBinds {
skuBind, ok := existBindsMap[v.SkuID]
if !ok {
if v.IsFocus == 1 {
sku := &model.Sku{}
sku.ID = v.SkuID
if err2 := dao.GetEntity(db, sku); err2 != nil {
dao.Rollback(db)
return 0, err2
}
skuBind = &model.StoreSkuBind{
StoreID: storeID,
SkuID: v.SkuID,
SubStoreID: v.SubStoreID, // todo 这个应该从用户信息中自动获得
UnitPrice: unitPrice,
Price: calStoreSkuPrice(unitPrice, sku.SpecQuality, sku.SpecUnit),
Status: model.StoreSkuBindStatusDontSale,
}
dao.WrapAddIDCULDEntity(skuBind, userName)
}
} else {
if v.IsFocus != -1 {
dao.WrapUpdateULEntity(skuBind, userName)
}
}
if skuBind != nil {
if v.IsSale != 0 {
if v.IsSale == 1 {
skuBind.Status = model.StoreSkuBindStatusNormal
} else {
skuBind.Status = model.StoreSkuBindStatusDontSale
}
skuBind.JdSyncStatus |= model.SyncFlagSaleMask
skuBind.ElmSyncStatus |= model.SyncFlagSaleMask
skuBind.EbaiSyncStatus |= model.SyncFlagSaleMask
}
if ok {
if v.IsFocus == -1 {
delNum++
_, err = dao.DeleteEntityLogically(db, skuBind, map[string]interface{}{
model.FieldStatus: model.StoreSkuBindStatusDeleted,
model.FieldJdSyncStatus: model.SyncFlagDeletedMask,
model.FieldElmSyncStatus: model.SyncFlagDeletedMask,
model.FieldEbaiSyncStatus: model.SyncFlagDeletedMask,
}, userName, nil)
} else {
// todo 如果修改ebai与elm ID怎么处理呢
if v.IsFocus == 1 {
skuBind.DeletedAt = utils.DefaultTimeValue
}
updateNum++
skuBind.JdSyncStatus |= model.SyncFlagModifiedMask
skuBind.ElmSyncStatus |= model.SyncFlagModifiedMask
skuBind.EbaiSyncStatus |= model.SyncFlagModifiedMask
_, err = dao.UpdateEntity(db, skuBind)
}
} else {
if v.EbaiID != 0 {
skuBind.EbaiID = v.EbaiID
}
if v.ElmID != 0 {
skuBind.ElmID = v.ElmID
}
addNum++
skuBind.JdSyncStatus = model.SyncFlagNewMask
skuBind.ElmSyncStatus = model.SyncFlagNewMask
skuBind.EbaiSyncStatus = model.SyncFlagNewMask
err = dao.CreateEntity(db, skuBind)
}
}
if err != nil {
dao.Rollback(db)
return 0, err
}
}
if skuBindInfo.UnitPrice != 0 {
num = int64(addNum + len(existBinds))
} else {
num = int64(addNum + delNum + updateNum)
}
dao.Commit(db)
err = CurVendorSync.SyncStoreSku(db, storeID, skuIDs, false, userName)
}
return num, err
}
// 计算SKU价格unitPrice为一斤的单价specQuality为质量单位为克
func calStoreSkuPrice(unitPrice int, specQuality float32, specUnit string) int {
if strings.ToLower(specUnit) == "kg" {
specQuality *= 1000
}
return int(math.Round(float64(float32(unitPrice) * specQuality / 500)))
}