package dao import ( "errors" "fmt" "strings" "time" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/globals" ) type StoreSkuAndAct struct { *model.StoreSkuBind ActMap map[int]*model.StoreSkuAct } var ( dataResFieldMap = map[int]string{ model.VendorIDMTWM: "mtwm_url", model.VendorIDEBAI: "ebai_url", } salePriceLimit = 100 ) type SkuStoreCatInfo struct { VendorID int `orm:"column(vendor_id)" json:"vendorID"` VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 MapID int `orm:"column(map_id)"` // 这个主要用于判断是否有store_sku_category_map model.SkuCategory VendorCatID string `orm:"column(vendor_cat_id)"` CatSyncStatus int8 ParentMapID int `orm:"column(parent_map_id)"` // 这个主要用于判断是否有父store_sku_category_map ParentCatName string ParentVendorCatID string `orm:"column(parent_vendor_cat_id)"` ParentCatSyncStatus int8 } type StoreSkuSyncInfo struct { VendorID int `orm:"column(vendor_id)" json:"vendorID"` VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 // 平台无关的store sku信息 BindID int `orm:"column(bind_id)"` // 换名的原因是与Sku.ID同名区别 StoreID int `orm:"column(store_id)"` SkuID int `orm:"column(sku_id)"` // 这个与Sku.ID的区别是SkuID是必然存在的 BoxFee int64 Price int64 UnitPrice int64 // 平台相关的store sku信息 StoreSkuStatus int SkuSyncStatus int8 VendorSkuID string `orm:"column(vendor_sku_id)"` BindDeletedAt time.Time `orm:"type(datetime)" json:"bindDeletedAt"` model.Sku // sku_name Prefix string ExPrefix string ExPrefixBegin *time.Time ExPrefixEnd *time.Time // NameID int `orm:"column(name_id)"` VendorNameID string `orm:"column(vendor_name_id)"` // 暂时无用 Name string Unit string Upc string IsGlobal int8 `orm:"default(1)" json:"isGlobal"` // 是否是全部(全国)可见,如果否的话,可见性由SkuPlace决定 NameStatus int SellCities []string // 平台相关的图片信息 Img string Img2 string DescImg string VendorVendorCatID int64 `orm:"column(vendor_vendor_cat_id)"` // 平台商品分类(叶子结点) // sku的商家分类信息 SkuCatSyncStatus int8 SkuVendorCatID string `orm:"column(sku_vendor_cat_id)"` // sku_name的商家分类信息 CatSyncStatus int8 VendorCatID string `orm:"column(vendor_cat_id)"` VendorPrice int64 LockTime *time.Time MergedStatus int SkuName string StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围 StatusSaleEnd int16 `json:"statusSaleEnd"` JdSyncStatus int8 `orm:"default(2)"` MtwmSyncStatus int8 `orm:"default(2)"` EbaiSyncStatus int8 `orm:"default(2)"` } type MissingStoreSkuInfo struct { StoreID int `orm:"column(store_id)"` NameID int `orm:"column(name_id)"` SkuID int `orm:"column(sku_id)"` SpecQuality float32 SpecUnit string Unit string RefPrice int } type StoreSkuBindWithVendorInfo struct { model.StoreSkuBind VendorStoreID string `orm:"column(vendor_store_id)"` VendorSkuID string `orm:"column(vendor_sku_id)"` } type StoreSkuNameInfo struct { StoreID int `orm:"column(store_id)"` NameID int `orm:"column(name_id)"` UnitPrice int64 } // GetStoreSkus用 type StoreSkuNameExt struct { StoreID int `orm:"column(store_id)" json:"storeID"` StoreName string `json:"storeName"` SkuID int `orm:"column(sku_id)" json:"skuID"` model.SkuName PayPercentage int `json:"-"` UnitPrice int `json:"unitPrice"` Skus []*StoreSkuExt `orm:"-" json:"skus,omitempty"` SkusStr string `json:"-"` PendingOpType int8 `json:"pendingOpType"` // 取值同 StoreOpRequest.Type PendingUnitPrice int `json:"pendingUnitPrice"` // 这个是待审核的价格申请 Status int RealMidUnitPrice int `json:"realMidUnitPrice"` } // GetStoreSkus用 type StoreSkuNamesInfo struct { TotalCount int `json:"totalCount"` SkuNames []*StoreSkuNameExt `json:"skuNames"` } type StoreSkuExt struct { NameID int `orm:"column(name_id)" json:"nameID"` SkuID int `orm:"column(sku_id)" json:"id"` Comment string `orm:"size(255)" json:"comment"` SkuCategoryID int `orm:"column(sku_category_id)" json:"categoryID"` SkuSpecQuality float32 `json:"specQuality"` SkuSpecUnit string `orm:"size(8)" json:"specUnit"` // 质量或容量 Weight int `json:"weight"` // 重量/质量,单位为克,当相应的SkuName的SpecUnit为g或kg时,必须等于SpecQuality JdID string `orm:"column(sku_jd_id);null;index" json:"jdID"` SkuStatus int `json:"status"` BindCreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` BindUpdatedAt time.Time `orm:"auto_now;type(datetime)" json:"updatedAt"` BindLastOperator string `orm:"size(32)" json:"lastOperator"` // 最后操作员 BindDeletedAt time.Time `orm:"type(datetime)" json:"deletedAt"` SubStoreID int `orm:"column(sub_store_id)" json:"subStoreID"` BindPrice int `json:"price"` // 单位为分,不用int64的原因是这里不需要累加 UnitPrice int `json:"unitPrice"` // 这个是一斤的门店商品价,放在这里的原因是避免额外增加一张store sku_name表,逻辑上要保证同一SKU NAME中的所有SKU这个字段的数据一致 StoreSkuStatus int `json:"storeSkuStatus"` EbaiID string `orm:"column(ebai_id);index" json:"ebaiID"` MtwmID string `orm:"column(mtwm_id)" json:"mtwmID"` // 这个也不是必须的,只是为了DAO取数据语句一致 // WscID string `orm:"column(wsc_id);index" json:"wscID"` // 表示微盟skuId // WscID2 string `orm:"column(wsc_id2);index" json:"wscID2"` // 表示微盟goodsId JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` EbaiSyncStatus int8 `orm:"default(2)" json:"ebaiSyncStatus"` MtwmSyncStatus int8 `orm:"default(2)" json:"mtwmSyncStatus"` // WscSyncStatus int8 `orm:"default(2)" json:"wscSyncStatus"` JdPrice int `json:"jdPrice"` EbaiPrice int `json:"ebaiPrice"` MtwmPrice int `json:"mtwmPrice"` JxPrice int `json:"jxPrice"` JdLockTime *time.Time `orm:"null" json:"jdLockTime,omitempty"` EbaiLockTime *time.Time `orm:"null" json:"ebaiLockTime,omitempty"` MtwmLockTime *time.Time `orm:"null" json:"mtwmLockTime,omitempty"` JxLockTime *time.Time `orm:"null" json:"jxLockTime,omitempty"` AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"` ActPrice int `json:"actPrice"` ActID int `orm:"column(act_id)" json:"actID"` ActType int `orm:"column(act_type)" json:"actType"` EarningPrice int `json:"earningPrice"` EarningActID int `orm:"column(earning_act_id)" json:"earningActID"` // RealEarningPrice int `json:"realEarningPrice"` StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围 StatusSaleEnd int16 `json:"statusSaleEnd"` Count int `json:"count"` Times int `json:"times"` } type SkuNameAndPlace struct { model.SkuName UnitPrice int `json:"unitPrice"` CityCode int `json:"cityCode"` CityName string `json:"cityName"` Sequence int `json:"sequence"` Count int `json:"count"` Type int `json:"type"` Skus []*model.SkuAndName `json:"skus"` } type StoreSkuPriceAndWeight struct { VendorSkuID string `orm:"column(vendor_sku_id)"` SkuID int `orm:"column(sku_id)"` Weight int Price int } // todo 应该通过需要同步的skuid来驱动同步分类,而不是当前这种分开的逻辑 // 单门店模式厂商适用 // 从store_sku_bind中,得到所有依赖的商家分类信息 func GetSkusCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int) (cats []*SkuStoreCatInfo, err error) { sql := ` SELECT DISTINCT t4.*, t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status cat_sync_status, t4p.name parent_cat_name, t5p.id parent_map_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status FROM store_sku_bind t1 JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? ` if level == 2 { sql += ` JOIN sku_category t4 ON (t3.category_id = t4.id OR t2.category_id = t4.id) AND t4.level = 2 AND t4.deleted_at = ? ` } else { sql += ` LEFT JOIN sku_category t4c ON (t3.category_id = t4c.id OR t2.category_id = t4c.id) JOIN sku_category t4 ON (t4.id = t4c.parent_id OR (t3.category_id = t4.id OR t2.category_id = t4.id)) AND t4.level = 1 AND t4.deleted_at = ? ` } sql += ` LEFT JOIN store_sku_category_map t5 ON t4.id = t5.category_id AND t5.store_id = t1.store_id AND t5.deleted_at = ? LEFT JOIN sku_category t4p ON t4.parent_id = t4p.id LEFT JOIN store_sku_category_map t5p ON t4p.id = t5p.category_id AND t5p.store_id = t1.store_id AND t5p.deleted_at = ? WHERE t1.deleted_at = ? AND t1.%s_sync_status & ? = 0 AND t1.store_id = ? AND ((t1.status = ? AND t2.status = ? AND t3.status = ?) OR (t1.%s_sync_status & ? = 0)) ` sqlParams := []interface{}{ utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, model.SyncFlagDeletedMask, storeID, model.SkuStatusNormal, model.SkuStatusNormal, model.SkuStatusNormal, model.SyncFlagNewMask, } if len(skuIDs) > 0 { sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" sqlParams = append(sqlParams, skuIDs) } fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) sql = fmt.Sprintf(sql, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix) if err = GetRows(db, &cats, sql, sqlParams...); err != nil { return nil, err } return cats, err } // 单门店模式厂商适用 // 单纯的从已经创建的store_sku_category_map中,得到相关的同步信息 func GetStoreCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int, mustDirty bool) (cats []*SkuStoreCatInfo, err error) { fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) sql := ` SELECT t4.*, t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status cat_sync_status, t4p.name parent_cat_name, t5p.id parent_map_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status FROM store_sku_category_map t5 JOIN sku_category t4 ON t5.category_id = t4.id AND t4.deleted_at = ? ` sqlParams := []interface{}{ utils.DefaultTimeValue, } fieldPrefixParams := []interface{}{fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix} if len(skuIDs) > 0 { sql += ` JOIN ( SELECT DISTINCT b.category_id FROM sku a JOIN sku_name b ON a.name_id = b.id AND b.deleted_at = ? WHERE a.id IN (` + GenQuestionMarks(len(skuIDs)) + `) AND a.deleted_at = ? ) t6 ON t6.category_id = t4.id ` sqlParams = append(sqlParams, utils.DefaultTimeValue, skuIDs, utils.DefaultTimeValue) } sql += ` LEFT JOIN sku_category t4p ON t4.parent_id = t4p.id LEFT JOIN store_sku_category_map t5p ON t4p.id = t5p.category_id AND t5.store_id = t5p.store_id AND t5p.deleted_at = ? WHERE t5.store_id = ? AND t5.deleted_at = ?` sqlParams = append(sqlParams, utils.DefaultTimeValue, storeID, utils.DefaultTimeValue) if mustDirty { sql += " AND t5.%s_sync_status <> 0" fieldPrefixParams = append(fieldPrefixParams, fieldPrefix) } if level > 0 { sql += " AND t4.level = ?" sqlParams = append(sqlParams, level) } if err = GetRows(db, &cats, fmt.Sprintf(sql, fieldPrefixParams...), sqlParams...); err != nil { return nil, err } return cats, err } func GetDirtyStoreCategories(db *DaoDB, vendorID, storeID int, level int, skuIDs []int) (cats []*SkuStoreCatInfo, err error) { return GetStoreCategories(db, vendorID, storeID, skuIDs, level, true) } // 以store_sku_bind为基础来做同步,正常情况下使用 // 单多门店模式厂商通用 func GetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty bool) (skus []*StoreSkuSyncInfo, err error) { if vendorID < 0 { panic("vendorID<0") } isSingleStorePF := model.MultiStoresVendorMap[vendorID] != 1 fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) skuVendorIDField := fmt.Sprintf("t1.%s_id", fieldPrefix) if !isSingleStorePF { skuVendorIDField = "t2m.vendor_thing_id" } sql := ` SELECT t14.vendor_id, t14.vendor_org_code, t1.id bind_id, t1.sku_id, t1.price, t1.unit_price, t1.status store_sku_status, %s vendor_sku_id, t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price, t1.%s_lock_time lock_time, t1.store_id, t1.deleted_at bind_deleted_at,t1.status_sale_begin,t1.status_sale_end, t2.*, t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, t3.status name_status, t3.ex_prefix, t3.ex_prefix_begin, t3.ex_prefix_end, IF(t11.%s <> '', t11.%s, t3.img) img, IF(t12.%s <> '', t12.%s, t3.img2) img2, t13.%s desc_img, t4.%s_category_id vendor_vendor_cat_id` fmtParams := []interface{}{ skuVendorIDField, fieldPrefix, fieldPrefix, fieldPrefix, GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), fieldPrefix, } if isSingleStorePF { sql += `, t5.%s_sync_status cat_sync_status, t5.%s_id vendor_cat_id, t5sku.%s_sync_status sku_cat_sync_status, t5sku.%s_id sku_vendor_cat_id` fmtParams = append(fmtParams, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix) } else { sql += `, t4m.vendor_thing_id vendor_cat_id, t5skum.vendor_thing_id sku_vendor_cat_id` } sql += ` FROM store_sku_bind t1 JOIN store_map t14 ON t14.store_id = t1.store_id AND t14.vendor_id = ? AND t14.deleted_at = ? LEFT JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ?/* AND t2.status = ?*/ LEFT JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ?/* AND t3.status = ?*/ LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ? LEFT JOIN data_resource t11 ON t11.main_url = t3.img LEFT JOIN data_resource t12 ON t12.main_url = t3.img2 LEFT JOIN data_resource t13 ON t13.main_url = t3.desc_img ` sqlParams := []interface{}{ vendorID, utils.DefaultTimeValue, utils.DefaultTimeValue, // model.SkuStatusNormal, utils.DefaultTimeValue, // model.SkuStatusNormal, utils.DefaultTimeValue, } if isSingleStorePF { sql += ` LEFT JOIN store_sku_category_map t5 ON t4.id = t5.category_id AND t5.store_id = t1.store_id AND t5.deleted_at = ? LEFT JOIN store_sku_category_map t5sku ON t2.category_id = t5sku.category_id AND t5sku.store_id = t1.store_id AND t5sku.deleted_at = ?` sqlParams = append(sqlParams, utils.DefaultTimeValue, utils.DefaultTimeValue) } else { sql += ` LEFT JOIN sku_category t5sku ON t5sku.id = t2.category_id JOIN thing_map t2m ON t2m.thing_id = t1.sku_id AND t2m.vendor_org_code = t14.vendor_org_code AND t2m.thing_type = ? AND t2m.vendor_id = ? AND t2m.deleted_at = ? LEFT JOIN thing_map t4m ON t4m.thing_id = t3.category_id AND t4m.vendor_org_code = t14.vendor_org_code AND t4m.thing_type = ? AND t4m.vendor_id = ? AND t4m.deleted_at = ? LEFT JOIN thing_map t5skum ON t5skum.thing_id = t5sku.id AND t5skum.vendor_org_code = t14.vendor_org_code AND t5skum.thing_type = ? AND t5skum.vendor_id = ? AND t5skum.deleted_at = ? ` sqlParams = append(sqlParams, model.ThingTypeSku, vendorID, utils.DefaultTimeValue, model.ThingTypeCategory, vendorID, utils.DefaultTimeValue, model.ThingTypeCategory, vendorID, utils.DefaultTimeValue) } sql += " WHERE 1 = 1" if storeID > 0 { sql += " AND t1.store_id = ?" sqlParams = append(sqlParams, storeID) } if mustDirty { sql += " AND (t1.%s_sync_status <> 0 OR (%s <> %s AND t3.id IS NULL))" fmtParams = append(fmtParams, fieldPrefix, skuVendorIDField) if isSingleStorePF { fmtParams = append(fmtParams, "0") } else { fmtParams = append(fmtParams, "''") } } else { sql += " AND t1.deleted_at = ?" sqlParams = append(sqlParams, utils.DefaultTimeValue) } if len(skuIDs) > 0 { sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" sqlParams = append(sqlParams, skuIDs) } // 多门店平台没有成功创建的商品,不直接过滤,让上层同步时报错 // if !isSingleStorePF { // sql += " AND t2.%s_id <> 0" // fmtParams = append(fmtParams, fieldPrefix) // } sql = fmt.Sprintf(sql, fmtParams...) sql += " ORDER BY t1.price" // globals.SugarLogger.Debug(sql) if err = GetRows(db, &skus, sql, sqlParams...); err != nil { return nil, err } return skus, err } func GetStoreSkus(db *DaoDB, vendorID, storeID int, skuIDs []int) (skus []*StoreSkuSyncInfo, err error) { return GetStoreSkus2(db, vendorID, storeID, skuIDs, true) } // 以sku为基础来做全同步, // 多门店模式厂商适用 func GetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSyncInfo, err error) { globals.SugarLogger.Debugf("GetFullStoreSkus, storeID:%d, vendorID:%d", storeID, vendorID) // 对于多门店平台,商品库删除后,不需要操作门店商品,所以sku_name用JOIN, sku与sku_name也可以直接排除下架的 sql := ` SELECT sm.vendor_id, sm.vendor_org_code, t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status, t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price, t1.%s_lock_time lock_time, t1.store_id, t1.deleted_at bind_deleted_at, t2.*, t2.id sku_id, t2m.vendor_thing_id vendor_sku_id, t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, t3.status name_status, t3.ex_prefix, t3.ex_prefix_begin, t3.ex_prefix_end, IF(t11.%s <> '', t11.%s, t3.img) img, IF(t12.%s <> '', t12.%s, t3.img2) img2, t13.%s desc_img, t4.%s_category_id vendor_vendor_cat_id, t4m.sync_status cat_sync_status, t4m.vendor_thing_id vendor_cat_id, t5skum.sync_status sku_cat_sync_status, t5skum.vendor_thing_id sku_vendor_cat_id FROM sku t2 JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ?/* AND t3.status = ?*/ JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ? JOIN store_map sm ON sm.vendor_id = ? AND sm.store_id = ? AND sm.deleted_at = ? JOIN thing_map t2m ON t2m.thing_id = t2.id AND t2m.vendor_org_code = sm.vendor_org_code AND t2m.thing_type = ? AND t2m.vendor_id = ? AND t2m.deleted_at = ? JOIN thing_map t4m ON t4m.thing_id = t3.category_id AND t4m.vendor_org_code = sm.vendor_org_code AND t4m.thing_type = ? AND t4m.vendor_id = ? AND t4m.deleted_at = ? LEFT JOIN store_sku_bind t1 ON sm.store_id = t1.store_id AND t1.sku_id = t2.id AND t1.deleted_at = ? LEFT JOIN sku_category t5sku ON t2.category_id = t5sku.id LEFT JOIN thing_map t5skum ON t5skum.thing_id = t2.category_id AND t5skum.vendor_org_code = sm.vendor_org_code AND t5skum.thing_type = ? AND t5skum.vendor_id = ? AND t5skum.deleted_at = ? LEFT JOIN data_resource t11 ON t11.main_url = t3.img LEFT JOIN data_resource t12 ON t12.main_url = t3.img2 LEFT JOIN data_resource t13 ON t13.main_url = t3.desc_img WHERE t2.deleted_at = ?/* AND t2.status = ?*/ AND t2m.vendor_thing_id <> '' ORDER BY t1.price DESC` sqlParams := []interface{}{ utils.DefaultTimeValue, // model.SkuStatusNormal, utils.DefaultTimeValue, vendorID, storeID, utils.DefaultTimeValue, model.ThingTypeSku, vendorID, utils.DefaultTimeValue, model.ThingTypeCategory, vendorID, utils.DefaultTimeValue, utils.DefaultTimeValue, model.ThingTypeCategory, vendorID, utils.DefaultTimeValue, utils.DefaultTimeValue, // model.SkuStatusNormal, } fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) sql = fmt.Sprintf(sql, fieldPrefix, fieldPrefix, fieldPrefix, GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), fieldPrefix) // globals.SugarLogger.Debug(sql) // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) if err = GetRows(db, &skus, sql, sqlParams...); err != nil { return nil, err } return skus, err } func GetStoreSkuPriceAndWeight(db *DaoDB, vendorStoreID string, vendorID int, vendorSkuIDs []string) (l []*StoreSkuPriceAndWeight, err error) { var vendorSkuIDField, sqlThingMap string var thingMapParams []interface{} if vendorID == model.VendorIDJX { vendorSkuIDField = "t1.id" } else if model.MultiStoresVendorMap[vendorID] != 0 { sqlThingMap = ` JOIN thing_map t4 ON t4.thing_type = ? AND t4.thing_id = t1.id AND t4.deleted_at = ? AND t4.vendor_id = t3.vendor_id AND t4.vendor_org_code = t3.vendor_org_code` thingMapParams = []interface{}{ model.ThingTypeSku, utils.DefaultTimeValue, } vendorSkuIDField = "t4.vendor_thing_id" } else { vendorSkuIDField = fmt.Sprintf("t2.%s_id", ConvertDBFieldPrefix(model.VendorNames[vendorID])) } sql := fmt.Sprintf(` SELECT %s vendor_sku_id, t1.id sku_id, t2.price, t1.weight FROM sku t1 JOIN store_sku_bind t2 ON t2.sku_id = t1.id AND t2.deleted_at = ? JOIN store_map t3 ON t3.store_id = t2.store_id AND t3.vendor_id = ? AND t3.vendor_store_id = ? AND t3.deleted_at = ? %s WHERE %s IN (`+GenQuestionMarks(len(vendorSkuIDs))+`)`, vendorSkuIDField, sqlThingMap, vendorSkuIDField) sqlParams := []interface{}{ utils.DefaultTimeValue, vendorID, vendorStoreID, utils.DefaultTimeValue, } sqlParams = append(sqlParams, thingMapParams...) if vendorID == model.VendorIDJX { sqlParams = append(sqlParams, utils.StringSlice2Int(vendorSkuIDs)) } else { sqlParams = append(sqlParams, vendorSkuIDs) } // globals.SugarLogger.Debugf(sql) err = GetRows(db, &l, sql, sqlParams...) return l, err } // 这个函数之前是要设置没有删除或同步标志不为0的,会导致将同步标志不为0且删除了的把标志去掉,现在改为只设置没有删除的 func SetStoreSkuSyncStatus(db *DaoDB, vendorID int, storeIDs []int, skuIDs []int, syncStatus int) (num int64, err error) { globals.SugarLogger.Debugf("SetStoreSkuSyncStatus, storeIDs:%v, vendorID:%d", storeIDs, vendorID) isSingleStorePF := model.MultiStoresVendorMap[vendorID] != 1 fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) sql := ` UPDATE store_sku_bind t1 SET t1.%s_sync_status = t1.%s_sync_status | ? ` fmtParams := []interface{}{ fieldPrefix, fieldPrefix, } sqlParams := []interface{}{ syncStatus, } if isSingleStorePF && (syncStatus&model.SyncFlagNewMask) != 0 { sql += `, t1.%s_id = 0 ` fmtParams = append(fmtParams, fieldPrefix) } sql += " WHERE t1.deleted_at = ? AND t1.%s_sync_status & ? = 0" fmtParams = append(fmtParams, fieldPrefix) sqlParams = append(sqlParams, utils.DefaultTimeValue, model.SyncFlagDeletedMask) if len(storeIDs) > 0 { sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } if len(skuIDs) > 0 { sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" sqlParams = append(sqlParams, skuIDs) } sql = fmt.Sprintf(sql, fmtParams...) return ExecuteSQL(db, sql, sqlParams...) } func SetStoreCategorySyncStatus(db *DaoDB, vendorID int, storeIDs []int, catIDs []int, syncStatus int) (num int64, err error) { globals.SugarLogger.Debugf("SetStoreCategorySyncStatus, storeIDs:%v, vendorID:%d", storeIDs, vendorID) isSingleStorePF := model.MultiStoresVendorMap[vendorID] != 1 fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) sql := ` UPDATE store_sku_category_map t1 SET t1.%s_sync_status = IF(t1.deleted_at = ?, t1.%s_sync_status | ?, 0) ` fmtParams := []interface{}{ fieldPrefix, fieldPrefix, } sqlParams := []interface{}{ utils.DefaultTimeValue, syncStatus, } if isSingleStorePF && (syncStatus&model.SyncFlagNewMask) != 0 { sql += `, t1.%s_id = 0 ` fmtParams = append(fmtParams, fieldPrefix) } sql += " WHERE (t1.deleted_at = ? OR t1.%s_sync_status <> 0)" fmtParams = append(fmtParams, fieldPrefix) sqlParams = append(sqlParams, utils.DefaultTimeValue) if len(storeIDs) > 0 { sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } if len(catIDs) > 0 { sql += " AND t1.category_id IN (" + GenQuestionMarks(len(catIDs)) + ")" sqlParams = append(sqlParams, catIDs) } sql = fmt.Sprintf(sql, fmtParams...) return ExecuteSQL(db, sql, sqlParams...) } // func GetImgFieldName(vendorID int) (fieldName string) { // fieldName = imgFieldMap[vendorID] // if fieldName == "" { // fieldName = "img" // } // return fieldName // } func GetDataResFieldName(vendorID int) (fieldName string) { fieldName = dataResFieldMap[vendorID] if fieldName == "" { fieldName = "main_url" } return fieldName } // func GetDescImgFieldName(vendorID int) (fieldName string) { // fieldName = descImgFieldMap[vendorID] // if fieldName == "" { // fieldName = "desc_img" // } // return fieldName // } func GetStoresSkusInfo(db *DaoDB, storeIDs, skuIDs []int) (storeSkuList []*model.StoreSkuBind, err error) { sql := ` SELECT * FROM store_sku_bind t1 WHERE t1.deleted_at = ? ` sqlParams := []interface{}{ utils.DefaultTimeValue, } if len(storeIDs) > 0 { sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } if len(skuIDs) > 0 { sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" sqlParams = append(sqlParams, skuIDs) } err = GetRows(db, &storeSkuList, sql, sqlParams...) return storeSkuList, err } // vendorID, vendorStoreIDs和vendorSkuIDs都是必须参数 func GetStoresSkusInfoByVendorInfo(db *DaoDB, vendorID int, vendorStoreIDs, vendorSkuIDs []string) (storeSkuList []*StoreSkuBindWithVendorInfo, err error) { if len(vendorStoreIDs) == 0 || len(vendorSkuIDs) == 0 { return nil, nil } sql := ` SELECT t1.*, %s.%s_id vendor_sku_id, t2.vendor_store_id FROM store_sku_bind t1 JOIN store_map t2 ON t2.store_id = t1.store_id AND t2.vendor_id = ? AND t2.deleted_at = ? JOIN sku t3 ON t3.id = t1.sku_id WHERE t1.deleted_at = ? AND t2.vendor_store_id IN (` + GenQuestionMarks(len(vendorStoreIDs)) + `) AND %s.%s_id IN (` + GenQuestionMarks(len(vendorSkuIDs)) + `)` sqlParams := []interface{}{ vendorID, utils.DefaultTimeValue, utils.DefaultTimeValue, vendorStoreIDs, vendorSkuIDs, } isSingleStorePF := model.MultiStoresVendorMap[vendorID] != 1 tableName := "t1" if !isSingleStorePF { tableName = "t3" } fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) sql = fmt.Sprintf(sql, tableName, fieldPrefix, tableName, fieldPrefix) err = GetRows(db, &storeSkuList, sql, sqlParams...) return storeSkuList, err } func GetMissingStoreSkuFromOrder(db *DaoDB, storeIDs []int, fromTime time.Time) (storeSkuList []*MissingStoreSkuInfo, err error) { if time.Now().Sub(fromTime) > 24*time.Hour*60 { return nil, fmt.Errorf("GetMissingStoreSkuFromOrder,时间超过60天") } sql := ` SELECT IF(t2.jx_store_id <> 0, t2.jx_store_id, t2.store_id) store_id, t4.name_id, t1.sku_id, t4.spec_quality, t4.spec_unit, t5.unit, COUNT(*) ct, CAST(AVG(IF(t1.vendor_price <> 0, t1.vendor_price, t1.sale_price)) AS SIGNED) ref_price FROM order_sku t1 JOIN goods_order t2 ON t2.vendor_order_id = t1.vendor_order_id LEFT JOIN store_sku_bind t3 ON t3.store_id = IF(t2.jx_store_id <> 0, t2.jx_store_id, t2.store_id) AND t3.sku_id = t1.sku_id AND t3.deleted_at = ? JOIN sku t4 ON t4.id = t1.sku_id JOIN sku_name t5 ON t5.id = t4.name_id WHERE t2.status = ? AND IF(t2.jx_store_id <> 0, t2.jx_store_id, t2.store_id) > 0 AND t1.sku_id > 0 AND t1.shop_price = 0 AND t1.order_created_at > ? AND t3.id IS NULL ` sqlParams := []interface{}{ utils.DefaultTimeValue, model.OrderStatusFinished, fromTime, } if len(storeIDs) > 0 { sql += " AND IF(t2.jx_store_id <> 0, t2.jx_store_id, t2.store_id) IN (" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } sql += ` GROUP BY 1,2,3,4,5,6 ORDER BY 1,2,3,4,5,6 ` err = GetRows(db, &storeSkuList, sql, sqlParams...) return storeSkuList, err } func GetAutoSaleStoreSku(db *DaoDB, storeIDs []int) (storeSkuList []*model.StoreSkuBind, err error) { sql := ` SELECT * FROM store_sku_bind t1 WHERE t1.deleted_at = ? AND t1.auto_sale_at <> ?` sqlParams := []interface{}{ utils.DefaultTimeValue, utils.DefaultTimeValue, } if len(storeIDs) > 0 { sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } err = GetRows(db, &storeSkuList, sql, sqlParams...) return storeSkuList, err } func GetExistingStoreSkuNameInfo(db *DaoDB, storeIDs, skuNameIDs []int) (storeSkuNameList []*StoreSkuNameInfo, err error) { if len(storeIDs) == 0 || len(skuNameIDs) == 0 { return nil, nil } sql := ` SELECT t1.store_id, t2.name_id, MAX(t1.unit_price) unit_price FROM store_sku_bind t1 JOIN sku t2 ON t2.id = t1.sku_id WHERE t1.deleted_at = ? AND t1.store_id IN (` + GenQuestionMarks(len(storeIDs)) + `) AND t2.name_id IN (` + GenQuestionMarks(len(skuNameIDs)) + `) GROUP BY 1, 2` sqlParams := []interface{}{ utils.DefaultTimeValue, storeIDs, skuNameIDs, } err = GetRows(db, &storeSkuNameList, sql, sqlParams...) return storeSkuNameList, err } func (s *StoreSkuSyncInfo) GetSeq() int { if s.Seq > 0 { return s.Seq } return int(s.VendorPrice) } func GetStoresSkusInfoBySaleTime(db *DaoDB, storeID int) (storeSkuBindList []*model.StoreSkuBind, err error) { sql := ` SELECT t1.* FROM store_sku_bind t1 WHERE t1.status_sale_begin <> 0 AND t1.status_sale_end <> 0 AND t1.status = ? AND t1.deleted_at = ? ` sqlParams := []interface{}{ model.SkuStatusNormal, utils.DefaultTimeValue, } if storeID > 0 { sql += ` AND t1.store_id = ?` sqlParams = append(sqlParams, storeID) } err = GetRows(db, &storeSkuBindList, sql, sqlParams...) return storeSkuBindList, err } func UpdateStoreSkuBindSyncStatusForSaleStatus(db *DaoDB, vendorIDs []int, storeID int) (num int64, err error) { sql := ` UPDATE store_sku_bind SET ` fmtParams := []interface{}{} sqlParams := []interface{}{} if len(vendorIDs) > 0 { for _, v := range vendorIDs { fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[v]) sql += ` %s_sync_status = ?,` fmtParams = append(fmtParams, fieldPrefix) sqlParams = append(sqlParams, model.SyncFlagSaleMask) } } else { return 0, errors.New("取平台ID名有错误!partner.GetPurchasePlatformVendorIDs()") } sql = sql[0:strings.LastIndex(sql, ",")] sql = fmt.Sprintf(sql, fmtParams...) sql += ` WHERE status = ? AND deleted_at = ? AND status_sale_begin <> 0 AND status_sale_end <> 0 ` sqlParams = append(sqlParams, model.StoreSkuBindStatusNormal, utils.DefaultTimeValue) if storeID > 0 { sql += ` AND store_id = ?` sqlParams = append(sqlParams, storeID) } return ExecuteSQL(db, sql, sqlParams...) } func UpdateStoreSkuBindSyncStatusForExPrefix(db *DaoDB, vendorIDs []int) (num int64, err error) { sql := ` UPDATE store_sku_bind a JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ? JOIN sku_name c ON c.id = b.name_id AND c.deleted_at = ? SET ` fmtParams := []interface{}{} sqlParams := []interface{}{ utils.DefaultTimeValue, utils.DefaultTimeValue, } if len(vendorIDs) > 0 { for _, v := range vendorIDs { fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[v]) sql += ` %s_sync_status = %s_sync_status | ?,` fmtParams = append(fmtParams, fieldPrefix, fieldPrefix) sqlParams = append(sqlParams, model.SyncFlagModifiedMask) } } else { return 0, errors.New("取平台ID名有错误!partner.GetPurchasePlatformVendorIDs()") } sql = sql[0:strings.LastIndex(sql, ",")] sql = fmt.Sprintf(sql, fmtParams...) sql += ` WHERE a.deleted_at = ? AND c.ex_prefix != "" AND (c.ex_prefix_begin = DATE_FORMAT(DATE_ADD(NOW(),INTERVAL '6' HOUR),'%Y-%m-%d 00:00:00') OR c.ex_prefix_end = DATE_FORMAT(NOW(),'%Y-%m-%d 00:00:00')) ` sqlParams = append(sqlParams, utils.DefaultTimeValue) return ExecuteSQL(db, sql, sqlParams...) } func UpdateSkuSyncStatusForExPrefix(db *DaoDB, vendorIDs []int) (num int64, err error) { sql := ` UPDATE thing_map t1 JOIN sku t2 ON t2.id = t1.thing_id AND t2.deleted_at = ? JOIN sku_name t3 ON t3.id = t2.name_id AND t3.deleted_at = ? AND t3.ex_prefix <> '' AND (t3.ex_prefix_begin = DATE_FORMAT(DATE_ADD(NOW(),INTERVAL '6' HOUR),'%Y-%m-%d 00:00:00') OR t3.ex_prefix_end = DATE_FORMAT(NOW(),'%Y-%m-%d 00:00:00')) SET t1.sync_status = t1.sync_status | ? WHERE t1.deleted_at = ? AND t1.thing_type = ? AND t1.sync_status & ? <> 0 ` sqlParams := []interface{}{ utils.DefaultTimeValue, utils.DefaultTimeValue, model.SyncFlagModifiedMask, utils.DefaultTimeValue, model.ThingTypeSku, model.SyncFlagDeletedMask, } if len(vendorIDs) > 0 { sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" sqlParams = append(sqlParams, vendorIDs) } return ExecuteSQL(db, sql, sqlParams...) } func DeleteSkuNameExPrefixOverdue(db *DaoDB) (num int64, err error) { sql := ` UPDATE sku_name SET ex_prefix_begin = null,ex_prefix_end = null WHERE deleted_at = ? AND DATE_FORMAT(DATE_ADD(NOW(),INTERVAL '6' HOUR),'%Y-%m-%d 00:00:00') >= ex_prefix_end ` sqlParams := []interface{}{utils.DefaultTimeValue} return ExecuteSQL(db, sql, sqlParams...) } func GetStoreSkusByNameIDs(db *DaoDB, storeIDs []int, nameID int) (skuList []*StoreSkuSyncInfo, err error) { sql := ` SELECT a.*,c.unit,c.name FROM store_sku_bind a JOIN sku b ON a.sku_id = b.id JOIN sku_name c ON b.name_id = c.id WHERE b.name_id = ? AND a.deleted_at = ? ` sqlParams := []interface{}{ nameID, utils.DefaultTimeValue, } if len(storeIDs) > 0 { sql += " AND a.store_id in (" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } sql += " AND a.status != ?" sqlParams = append(sqlParams, model.SkuStatusDeleted) err = GetRows(db, &skuList, sql, sqlParams...) return skuList, err } func GetTopSkusByStoreIDs(db *DaoDB, storeIDs []int) (storeSkuNameExt []*StoreSkuNameExt, err error) { sql := ` SELECT 1 s, t1.count, t2.id sku_id, t3.*, t1.store_id, t1.store_name FROM( SELECT SUM(b.count) count,c.id,a.store_id,d.name store_name FROM goods_order a JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id JOIN sku c ON b.sku_id = c.id AND c.deleted_at = ? JOIN sku_name t1 ON t1.id = c.name_id AND t1.deleted_at = ? STRAIGHT_JOIN store_sku_bind t4 ON t4.store_id = IF(a.jx_store_id = 0,a.store_id,a.jx_store_id) AND t4.sku_id = b.sku_id AND t4.status = ? AND t4.deleted_at = ? JOIN store d ON d.id = a.store_id WHERE 1=1 AND a.order_created_at BETWEEN ? and NOW() ` sqlParams := []interface{}{ utils.DefaultTimeValue, utils.DefaultTimeValue, model.SkuStatusNormal, utils.DefaultTimeValue, time.Now().AddDate(0, -1, 0), } if len(storeIDs) > 0 { sql += " AND a.store_id IN(" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } sql += ` AND b.sale_price > ? GROUP BY 2,3,4)t1 JOIN sku t2 ON t2.id = t1.id JOIN sku_name t3 ON t3.id = t2.name_id UNION ALL SELECT 2 s, 0 count, a.sku_id, g.*, a.store_id, e.name store_name FROM store_sku_bind a LEFT JOIN act_store_sku b ON a.store_id = b.store_id AND b.sku_id = a.sku_id LEFT JOIN act_map c ON c.act_id = b.act_id LEFT JOIN act d ON d.id = c.act_id JOIN store e ON e.id = a.store_id JOIN sku f ON a.sku_id = f.id AND f.deleted_at = ? JOIN sku_name g ON g.id = f.name_id AND g.deleted_at = ? WHERE 1=1 ` sqlParams = append(sqlParams, salePriceLimit, utils.DefaultTimeValue, utils.DefaultTimeValue) if len(storeIDs) > 0 { sql += " AND a.store_id IN(" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } sql += ` AND NOW() BETWEEN d.begin_at AND d.end_at AND a.status = ? AND a.deleted_at = ? AND (d.type = ? OR d.type = ?) ORDER BY 1,2 DESC LIMIT ? ` sqlParams = append(sqlParams, model.StoreSkuBindStatusNormal, utils.DefaultTimeValue, model.ActSkuDirectDown, model.ActSkuSecKill, 30) err = GetRows(db, &storeSkuNameExt, sql, sqlParams...) var skuNamesInfo = &StoreSkuNamesInfo{ SkuNames: storeSkuNameExt, } for _, v := range storeSkuNameExt { var skus []*StoreSkuExt sql2 := ` SELECT a.id sku_id,a.*,t4.created_at bind_created_at, t4.updated_at bind_updated_at, t4.last_operator bind_last_operator, t4.deleted_at bind_deleted_at, t4.sub_store_id, t4.price bind_price, IF(t4.unit_price IS NOT NULL, t4.unit_price, t1.price) unit_price, t4.status store_sku_status, t4.auto_sale_at, t4.ebai_id, t4.mtwm_id, t4.ebai_sync_status, t4.mtwm_sync_status, t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price, a.spec_quality sku_spec_quality, a.spec_unit sku_spec_unit FROM sku a JOIN sku_name t1 ON a.name_id = t1.id AND t1.deleted_at = ? JOIN store_sku_bind t4 ON t4.sku_id = a.id AND t4.deleted_at = ? WHERE a.id = ? AND a.deleted_at = ? ` sqlParams2 := []interface{}{ utils.DefaultTimeValue, utils.DefaultTimeValue, v.SkuID, utils.DefaultTimeValue, } if len(storeIDs) > 0 { sql2 += " AND t4.store_id IN(" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams2 = append(sqlParams2, storeIDs) } err = GetRows(db, &skus, sql2, sqlParams2...) v.Skus = skus err = UpdateActPrice4StoreSkuNameNew(db, storeIDs, []int{v.SkuID}, skuNamesInfo, -1) } return storeSkuNameExt, err } func GetTopSkusByCityCode(db *DaoDB, cityCode int, orderCreate time.Time) (skuNameAndPlace []*SkuNameAndPlace, err error) { sql := ` SELECT SUM(b.count) count, e.name city_name, d.city_code, f.* FROM goods_order a JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id JOIN sku c ON b.sku_id = c.id AND c.deleted_at = ? JOIN sku_name f ON f.id = c.name_id JOIN store d ON d.id = IF(a.jx_store_id = 0,a.store_id,a.jx_store_id) AND d.deleted_at = ? AND d.city_code = ? JOIN place e ON e.code = d.city_code WHERE 1=1 AND b.sale_price > ? AND a.order_created_at BETWEEN ? and NOW() GROUP BY 2,3,4 ORDER BY count DESC ` sqlParams := []interface{}{ utils.DefaultTimeValue, utils.DefaultTimeValue, cityCode, salePriceLimit, orderCreate, } err = GetRows(db, &skuNameAndPlace, sql, sqlParams...) return skuNameAndPlace, err } func GetTopCategoriesByStoreIDs(db *DaoDB, storeIDs []int, limit int) (skuCategory []*model.SkuCategory, err error) { sql := ` SELECT DISTINCT t5.* FROM( SELECT d.* FROM ( SELECT t3.*,t1.count FROM( SELECT SUM(b.count) count,d.category_id FROM goods_order a JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id JOIN sku c ON b.sku_id = c.id AND c.deleted_at = ? JOIN sku_name d ON d.id = c.name_id AND d.deleted_at = ? JOIN store e ON e.id = IF(a.jx_store_id = 0,a.store_id,a.jx_store_id) AND e.status != -2 JOIN (SELECT city_code FROM store WHERE 1=1 ` sqlParams := []interface{}{ utils.DefaultTimeValue, utils.DefaultTimeValue, } if len(storeIDs) > 0 { sql += " AND id IN(" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } sql += ` )t6 ON t6.city_code = e.city_code WHERE 1=1 AND a.order_created_at BETWEEN ? and NOW() AND b.sale_price > ? GROUP BY d.category_id)t1 JOIN sku_category t3 ON t1.category_id = t3.id AND t3.level = ? AND t3.deleted_at = ? ORDER BY t1.count DESC)t4 JOIN sku_category d ON d.id = t4.parent_id AND d.level = ? Order by t4.count DESC)t5 LIMIT ? ` sqlParams = append(sqlParams, time.Now().AddDate(0, -1, 0), salePriceLimit, 2, utils.DefaultTimeValue, 1, limit) err = GetRows(db, &skuCategory, sql, sqlParams...) return skuCategory, err } func GetStoreSkuCategories(db *DaoDB, storeID, parentID int) (catList []*model.SkuCategory, err error) { sql := ` SELECT t1.* FROM sku_category t1 JOIN ( SELECT DISTINCT t3.category_id FROM store_sku_bind t1 JOIN sku t2 ON t2.id = t1.sku_id AND t2.deleted_at = ? AND t2.status = ? JOIN sku_name t3 ON t3.id = t2.name_id AND t3.deleted_at = ? AND t3.status = ? WHERE t1.deleted_at = ? AND t1.status = ? AND t1.store_id = ? ) t2 ON t2.category_id = t1.id WHERE t1.deleted_at = ?` sqlParams := []interface{}{ utils.DefaultTimeValue, model.SkuStatusNormal, utils.DefaultTimeValue, model.SkuStatusNormal, utils.DefaultTimeValue, model.SkuStatusNormal, storeID, utils.DefaultTimeValue, } if parentID >= 0 { sql += " AND t1.parent_id = ?" sqlParams = append(sqlParams, parentID) } sql += " ORDER BY t1.level, t1.seq" if err = GetRows(db, &catList, sql, sqlParams...); err == nil && len(catList) > 0 { parentIDMap := make(map[int]int) for _, v := range catList { parentIDMap[v.ParentID] = 1 } paretnCats, err2 := GetCategories(db, -1, 0, jxutils.IntMap2List(parentIDMap)) if err = err2; err == nil { catList = append(catList, paretnCats...) } else { catList = nil } } return catList, err } func GetStoreSkuNamePrice(db *DaoDB) (storeSkuNamePriceList []*model.StoreSkuNamePrice, err error) { sql := ` SELECT * FROM store_sku_name_price WHERE deleted_at = ? ` sqlParams := []interface{}{ utils.DefaultTimeValue, } err = GetRows(db, &storeSkuNamePriceList, sql, sqlParams...) if err != nil { return nil, err } return storeSkuNamePriceList, err } func SetStoreSkuBindVendorPrice(storeSkuBind *model.StoreSkuBind, vendorID int, vendorPrice int, lockTime time.Time) { pLockTime := utils.Time2Pointer(lockTime) switch vendorID { case model.VendorIDJD: storeSkuBind.JdPrice = vendorPrice storeSkuBind.JdLockTime = pLockTime case model.VendorIDMTWM: storeSkuBind.MtwmPrice = vendorPrice storeSkuBind.MtwmLockTime = pLockTime case model.VendorIDEBAI: storeSkuBind.EbaiPrice = vendorPrice storeSkuBind.EbaiLockTime = pLockTime case model.VendorIDJX: storeSkuBind.JxPrice = vendorPrice storeSkuBind.JxLockTime = pLockTime } } func GetStoreSkuBindVendorPrice(storeSkuBind *model.StoreSkuBind, vendorID int) (vendorPrice int) { switch vendorID { case model.VendorIDJD: vendorPrice = storeSkuBind.JdPrice case model.VendorIDMTWM: vendorPrice = storeSkuBind.MtwmPrice case model.VendorIDEBAI: vendorPrice = storeSkuBind.EbaiPrice case model.VendorIDJX: vendorPrice = storeSkuBind.JxPrice } return vendorPrice } func SetStoreSkuBindSyncStatus(storeSkuBind *model.StoreSkuBind, vendorID int, syncStatus int8) { switch vendorID { case model.VendorIDJD: storeSkuBind.JdSyncStatus = syncStatus case model.VendorIDMTWM: storeSkuBind.MtwmSyncStatus = syncStatus case model.VendorIDEBAI: storeSkuBind.EbaiSyncStatus = syncStatus } } func GetStoreSkuBindSyncStatus(storeSkuBind *model.StoreSkuBind, vendorID int) (syncStatus int8) { switch vendorID { case model.VendorIDJD: syncStatus = storeSkuBind.JdSyncStatus case model.VendorIDMTWM: syncStatus = storeSkuBind.MtwmSyncStatus case model.VendorIDEBAI: syncStatus = storeSkuBind.EbaiSyncStatus } return syncStatus } func SetStoreCatMapSyncStatus(storeCatMap *model.StoreSkuCategoryMap, vendorID int, syncStatus int8) { switch vendorID { case model.VendorIDMTWM: storeCatMap.MtwmSyncStatus = syncStatus case model.VendorIDEBAI: storeCatMap.EbaiSyncStatus = syncStatus } } // skuIDs为空,会导致性能极低,所以要skuIDs必须有值 func UpdateActPrice4StoreSkuNameNew(db *DaoDB, storeIDs, skuIDs []int, skuNamesInfo *StoreSkuNamesInfo, actVendorID int) (err error) { if len(skuIDs) == 0 { return nil } var vendorIDs []int if actVendorID >= 0 { vendorIDs = []int{actVendorID} } actStoreSkuList, err := GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, model.ActTypeAll, storeIDs, skuIDs, time.Now(), time.Now()) if err != nil { globals.SugarLogger.Errorf("updateActPrice4StoreSkuNameNew can not get sku promotion info for error:%v", err) return err } actStoreSkuMap4Act := jxutils.NewActStoreSkuMap(actStoreSkuList, true) actStoreSkuMap4EarningPrice := jxutils.NewActStoreSkuMap(actStoreSkuList, false) for _, skuName := range skuNamesInfo.SkuNames { if len(skuName.Skus) > 0 { for _, v := range skuName.Skus { if actStoreSku := actStoreSkuMap4Act.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil { v.ActPrice = int(actStoreSku.ActualActPrice) v.ActID = actStoreSku.ActID v.ActType = actStoreSku.Type v.EarningPrice = int(jxutils.CaculateSkuEarningPrice(int64(v.ActPrice), int64(v.ActPrice), skuName.PayPercentage)) } if actStoreSku := actStoreSkuMap4EarningPrice.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil { v.EarningPrice = int(actStoreSku.EarningPrice) v.EarningActID = actStoreSku.ActID } else { earningPrice := int(jxutils.CaculateSkuEarningPrice(int64(v.BindPrice), int64(v.BindPrice), skuName.PayPercentage)) if v.EarningPrice == 0 || earningPrice < v.EarningPrice { v.EarningPrice = earningPrice } } } } else { skuName.UnitPrice = skuName.Price } } return err } func GetDeletedStoreSkuBind(db *DaoDB, storeID, skuID int) (storeSkuBind *model.StoreSkuBind) { sql := ` SELECT a.* FROM store_sku_bind a WHERE a.store_id = ? AND a.sku_id = ? ORDER BY a.deleted_at DESC` sqlParams := []interface{}{ storeID, skuID, } if err := GetRow(db, &storeSkuBind, sql, sqlParams...); err != nil { storeSkuBind = nil } return storeSkuBind } func GetStoreSkuBindByNameID(db *DaoDB, storeID, nameID, status int) (storeSkuBind []*model.StoreSkuBind, err error) { sql := ` SELECT c.* FROM sku a JOIN store_sku_bind c ON c.sku_id = a.id WHERE c.store_id = ? AND a.name_id = ? AND c.deleted_at = ? AND a.deleted_at = ? AND c.status = ? ` sqlParams := []interface{}{ storeID, nameID, utils.DefaultTimeValue, utils.DefaultTimeValue, status, } err = GetRows(db, &storeSkuBind, sql, sqlParams...) return storeSkuBind, err } func GetPriceReferPrice(db *DaoDB, cityCode int, skuID int, snapDate time.Time) (result *PriceReferSnapshotExt, err error) { var ( pRefer *PriceReferSnapshotExt priceRefer = &PriceReferSnapshotExt{} ) sql := ` SELECT a.max_unit_price, a.min_unit_price, a.avg_unit_price, a.mid_unit_price, a.sku_id id, b.spec_quality, c.unit, b.spec_unit FROM price_refer_snapshot a JOIN sku b ON a.sku_id = b.id JOIN sku_name c ON c.id = b.name_id WHERE 1=1 AND a.snapshot_at = ? AND a.city_code = ? ` sqlParams := []interface{}{ snapDate, cityCode, } if skuID > 0 { sql += " AND a.sku_id = ?" sqlParams = append(sqlParams, skuID) } err = GetRow(db, &pRefer, sql, sqlParams...) if err != nil { return nil, err } if pRefer != nil { var ( specQuality float64 ) if pRefer.Unit == model.SpecialUnit { if pRefer.SpecUnit == model.SpecUnitNames[1] || pRefer.SpecUnit == model.SpecUnitNames[2] { specQuality = float64(pRefer.SpecQuality) * 1000 } else { specQuality = float64(pRefer.SpecQuality) } priceRefer.MaxPrice = int(utils.Float64TwoInt64(specQuality / utils.Int2Float64(model.SpecialSpecQuality) * utils.Int2Float64(pRefer.MaxUnitPrice))) priceRefer.MinPrice = int(utils.Float64TwoInt64(specQuality / utils.Int2Float64(model.SpecialSpecQuality) * utils.Int2Float64(pRefer.MinUnitPrice))) priceRefer.AvgPrice = int(utils.Float64TwoInt64(specQuality / utils.Int2Float64(model.SpecialSpecQuality) * utils.Int2Float64(pRefer.AvgUnitPrice))) priceRefer.MidPrice = int(utils.Float64TwoInt64(specQuality / utils.Int2Float64(model.SpecialSpecQuality) * utils.Int2Float64(pRefer.MidUnitPrice))) } else { priceRefer.MaxPrice = pRefer.MaxUnitPrice priceRefer.MinPrice = pRefer.MinUnitPrice priceRefer.AvgPrice = pRefer.AvgUnitPrice priceRefer.MidPrice = pRefer.MidUnitPrice } } return priceRefer, err } func GetStoreSkusAndSkuName(db *DaoDB, storeIDs, skuIDs, nameIDs []int) (storeSkuSyncInfo []*StoreSkuSyncInfo, err error) { sql := ` SELECT a.id bind_id, a.store_id, a.jd_sync_status, a.mtwm_sync_status, a.ebai_sync_status, a.unit_price, a.price, c.id name_id, c.unit, b.* FROM store_sku_bind a JOIN sku b ON b.id = a.sku_id AND b.deleted_at = ? JOIN sku_name c ON c.id = b.name_id AND c.deleted_at = ? WHERE a.deleted_at = ? ` sqlParams := []interface{}{ utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, } if len(storeIDs) > 0 { sql += " AND a.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } if len(skuIDs) > 0 { sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" sqlParams = append(sqlParams, skuIDs) } if len(nameIDs) > 0 { sql += " AND b.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")" sqlParams = append(sqlParams, nameIDs) } err = GetRows(db, &storeSkuSyncInfo, sql, sqlParams...) return storeSkuSyncInfo, err }