Files
jx-callback/business/jxstore/cms/store_sku_check.go
2020-06-30 08:39:41 +08:00

1426 lines
55 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 (
"fmt"
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
"git.rosy.net.cn/jx-callback/globals/api"
"github.com/astaxie/beego"
"strconv"
"strings"
"sync"
"time"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/jxutils/excel"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api/apimanager"
)
const (
canWriteTolocal = false
needStatistic = false
isFilterToBeCreateAndNotSale = true
parallelCount = 5
fileExt = ".xlsx"
)
//错误类型
const (
DatAanalyse1 = "京西门店未关注,应删除对应的平台门店商品"
DatAanalyse2 = "平台商品库未创建成功(可能无经营许可等) "
DatAanalyse3 = "商品名不同 "
DatAanalyse4 = "商品可售状态不同 "
DatAanalyse5 = "京西商品库没有,平台商品库有 "
DatAanalyse6 = "京西商品库有,平台商品库没有"
DatAanalyse7 = "同步状态异常"
DatAanalyse8 = "平台门店未关注或平台门店商品库存为0应添加对应的平台门店商品"
DatAanalyse9 = "平台门店价格与京西商品库价格不一致"
DatAanalyse10 = "平台商品的VendorSkuID与京西的VendorSkuID不一致"
)
var (
diffFileName = map[bool]string{
true: "export/JXCSAndVendorSkuDiff",
false: "export/JXGYAndVendorSkuDiff",
}
vendorNameList = map[int]string{
model.VendorIDMTWM: model.VendorChineseNames[model.VendorIDMTWM],
model.VendorIDEBAI: model.VendorChineseNames[model.VendorIDEBAI],
model.VendorIDJD: model.VendorChineseNames[model.VendorIDJD],
}
titleList = []string{
"京西门店ID",
"平台门店ID",
"门店名",
"SkuID",
"京西美团外卖ID",
"京西饿百ID",
"同步状态",
"待创建",
"待删除",
"京西商品名",
"平台商品名",
"京西可售状态",
"平台可售状态",
"京西价格",
"平台价格",
"数据分析",
}
deoptTitleList = []string{
"SkuID",
"京西商品名",
"平台商品名",
"京西可售状态",
"平台可售状态",
"数据分析",
}
statisticTitleList = []string{
"京西和平台商品状态",
"待创建",
"京西可售状态",
"数量",
"占比",
}
statisticDataList = [][]string{
{"京西有,平台无", "是", "下架"},
{"京西有,平台无", "是", "上架"},
{"京西有,平台无", "否", "下架"},
{"京西有,平台无", "否", "上架"},
{"京西无,平台有", "N/A", "N/A"},
{"京西有,平台有", "是", "下架"},
{"京西有,平台有", "是", "上架"},
{"京西有,平台有", "否", "下架"},
{"京西有,平台有", "否", "上架"},
}
diffData DiffDataLock
depotDiffData DeoptDiffDataLock
multiStoreAllSkuInfoMap map[int]map[string]map[int]*partner.SkuNameInfo
multiStoreAllSkuInfoList map[int]map[string][]*partner.StoreSkuInfo
skuNameInfoList []*partner.SkuNameInfo
filterVendorDepotUnSaleSkuIds []int
filterJxDepotUnSaleSkuIds []int
)
type DiffDataLock struct {
diffDataMap map[int][]DiffData
locker sync.RWMutex
}
type DeoptDiffDataLock struct {
diffDataMap map[int][]DepotDiffData
locker sync.RWMutex
}
type DepotDiffData struct {
SkuID string `json:"SkuID"`
JxSkuName string `json:"京西商品名"`
VendorSkuName string `json:"平台商品名"`
JxStatus string `json:"京西可售状态"`
VendorStatus string `json:"平台可售状态"`
DatAanalyse string `json:"数据分析"`
}
type DiffData struct {
JxStoreID string `json:"京西门店ID"`
VendorStoreID string `json:"平台门店ID"`
VendorStoreName string `json:"门店名"`
SkuID string `json:"SkuID"`
MtwmID string `json:"京西美团外卖ID"`
EbaiID string `json:"京西饿百ID"`
SyncStatus string `json:"同步状态"`
ToBeCreate string `json:"待创建"`
ToBeDel string `json:"待删除"`
JxSkuName string `json:"京西商品名"`
VendorSkuName string `json:"平台商品名"`
JxStatus string `json:"京西可售状态"`
VendorStatus string `json:"平台可售状态"`
JxSkuPrice string `json:"京西价格"` /*哇,不能小写,不然会搞事情*/
VendorPrice string `json:"平台价格"`
DatAanalyse string `json:"数据分析"`
}
type StatisticData struct {
JxVendorStatus string `json:"京西和平台商品状态"`
ToBeCreate string `json:"待创建"`
JxSaleStatus string `json:"京西可售状态"`
Count string `json:"数量"`
Percent string `json:"占比"`
}
func (d *DeoptDiffDataLock) AppendData2(vendorID int, depotDiffData DepotDiffData) {
d.locker.Lock()
defer d.locker.Unlock()
d.diffDataMap[vendorID] = append(d.diffDataMap[vendorID], depotDiffData)
}
func (d *DeoptDiffDataLock) InitData2() {
d.diffDataMap = make(map[int][]DepotDiffData)
}
func (d *DiffDataLock) AppendData(vendorID int, diffData DiffData) {
d.locker.Lock()
defer d.locker.Unlock()
d.diffDataMap[vendorID] = append(d.diffDataMap[vendorID], diffData)
}
func (d *DiffDataLock) InitData() {
d.diffDataMap = make(map[int][]DiffData)
}
func InitMultiStoreData() {
multiStoreAllSkuInfoMap = make(map[int]map[string]map[int]*partner.SkuNameInfo)
multiStoreAllSkuInfoList = make(map[int]map[string][]*partner.StoreSkuInfo)
}
func GetMultiStoreAllSkuInfoMap(vendorID int, vendorOrgCode string) (retVal map[int]*partner.SkuNameInfo) {
if multiStoreAllSkuInfoMap[vendorID] != nil {
retVal = multiStoreAllSkuInfoMap[vendorID][vendorOrgCode]
}
return retVal
}
func GetMultiStoreAllSkuInfoList(vendorID int, vendorOrgCode string) (retVal []*partner.StoreSkuInfo) {
if multiStoreAllSkuInfoList[vendorID] != nil {
retVal = multiStoreAllSkuInfoList[vendorID][vendorOrgCode]
}
return retVal
}
//过滤掉平台下架的
func StoreSkuFullList2BareFilter(storeSkuFull []*partner.SkuNameInfo) (bareStoreSkuList []*partner.StoreSkuInfo) {
for _, v := range storeSkuFull {
for _, v2 := range v.SkuList {
if v2.Status > model.SkuStatusDontSale {
bareStoreSkuList = append(bareStoreSkuList, &v2.StoreSkuInfo)
}
}
}
return bareStoreSkuList
}
func GetMultiStoreAllSkuInfo(ctx *jxcontext.Context, vendorMap map[int]bool) {
InitMultiStoreData()
filterVendorDepotUnSaleSkuIds = filterVendorDepotUnSaleSkuIds[0:0]
for vendorID, _ := range vendorNameList {
//filter for vendorID
if len(vendorMap) > 0 {
if _, ok := vendorMap[vendorID]; !ok {
continue
}
}
if partner.IsMultiStore(vendorID) {
multiHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler)
for _, vendorOrgCode := range apimanager.CurAPIManager.GetAppOrgCodeList(vendorID) {
allSkuNameInfoList, err := multiHandler.GetSkus(ctx, vendorOrgCode, 0, "")
skuNameInfoList = allSkuNameInfoList
if err != nil {
baseapi.SugarLogger.Errorf("GetMultiStoreAllSkuInfo error:%v", err)
} else {
if multiStoreAllSkuInfoList[vendorID] != nil {
multiStoreAllSkuInfoList[vendorID][vendorOrgCode] = StoreSkuFullList2BareFilter(allSkuNameInfoList) //map[平台ID[]StoreSkuInfo1,StoreSkuInfo2...]
} else {
multiStoreAllSkuInfoList = make(map[int]map[string][]*partner.StoreSkuInfo)
multiStoreAllSkuInfoList[vendorID] = make(map[string][]*partner.StoreSkuInfo)
multiStoreAllSkuInfoList[vendorID][vendorOrgCode] = StoreSkuFullList2BareFilter(allSkuNameInfoList) //map[平台ID[]StoreSkuInfo1,StoreSkuInfo2...]
}
tempMap := make(map[int]*partner.SkuNameInfo)
for _, value := range allSkuNameInfoList {
for _, skuInfo := range value.SkuList {
//表示平台商品库未下架的
if skuInfo.Status > model.SkuStatusDontSale {
filterVendorDepotUnSaleSkuIds = append(filterVendorDepotUnSaleSkuIds, skuInfo.SkuID)
tempMap[skuInfo.SkuID] = value
}
}
}
multiStoreAllSkuInfoMap[vendorID] = make(map[string]map[int]*partner.SkuNameInfo)
multiStoreAllSkuInfoMap[vendorID][vendorOrgCode] = tempMap //map[平台ID][map[skuID1SkuNameInfo1skuID2SkuNameInfo2]...]
}
}
}
}
}
func GetFilterJxSkuInfoMap(jxSkuInfoList []*dao.StoreSkuNameExt) map[int]*dao.StoreSkuNameExt {
filterJxSkuInfoMap := make(map[int]*dao.StoreSkuNameExt)
for _, value := range jxSkuInfoList {
for _, skuInfo := range value.Skus {
filterJxSkuInfoMap[skuInfo.SkuID] = value
}
}
return filterJxSkuInfoMap
}
func GetFilterVendorSkuInfoMap(vendorSkuInfoList []*partner.SkuNameInfo) map[int]*partner.SkuNameInfo {
filterVendorSkuInfoMap := make(map[int]*partner.SkuNameInfo)
for _, value := range vendorSkuInfoList {
for _, skuInfo := range value.SkuList {
filterVendorSkuInfoMap[skuInfo.SkuID] = value
}
}
return filterVendorSkuInfoMap
}
func GetFilterJxSkuInfoMap2(jxSkuInfoList []*model.SkuAndName) map[int]*model.SkuAndName {
filterVendorSkuInfoMap := make(map[int]*model.SkuAndName)
for _, value := range jxSkuInfoList {
filterVendorSkuInfoMap[value.ID] = value
}
return filterVendorSkuInfoMap
}
func GetFilterMultiStoreSkuInfoMap(vendorID int, vendorOrgCode string, skuInfoList []*partner.StoreSkuInfo) map[int]*partner.SkuNameInfo {
allSkuInfoMap := GetMultiStoreAllSkuInfoMap(vendorID, vendorOrgCode)
filterSkuInfoMap := make(map[int]*partner.SkuNameInfo)
for _, value := range skuInfoList {
if value.Stock > 0 {
filterSkuInfoMap[value.SkuID] = allSkuInfoMap[value.SkuID]
}
}
return filterSkuInfoMap
}
func GetFilterStoreList(storeList []*StoreExt, vendorMap, storeIDMap map[int]bool) (outStoreList []*StoreExt) {
for _, storeInfo := range storeList {
storeID := storeInfo.ID
//filter for storeID
if len(storeIDMap) > 0 {
if _, ok := storeIDMap[storeID]; !ok {
continue
}
}
if storeInfo.StoreMaps != nil {
var tempStoreMaps []*model.StoreMap
for _, vendorStoreInfo := range storeInfo.StoreMaps {
vendorID := vendorStoreInfo.VendorID
isSyncStoreSku := int(vendorStoreInfo.IsSync)
if isSyncStoreSku == 0 {
continue
}
//filter for vendorID
if len(vendorMap) > 0 {
if _, ok := vendorMap[vendorID]; !ok {
continue
}
}
if _, ok := vendorNameList[vendorID]; !ok {
continue
}
tempStoreMaps = append(tempStoreMaps, vendorStoreInfo)
}
if len(tempStoreMaps) > 0 {
storeInfo.StoreMaps = tempStoreMaps
outStoreList = append(outStoreList, storeInfo)
}
}
}
return outStoreList
}
func GetSkuSaleStatusName(status int) string {
return model.SkuStatusName[status]
}
func GetBoolName(flag bool) string {
if flag {
return "是"
} else {
return "否"
}
}
func IsSkuCanSale(saleStatus int) bool {
return saleStatus == model.SkuStatusNormal
}
//京西平台和其他平台商品的对比
//storeIDStr 京西商家id vendorStoreID 平台商家id ,isJd 京东比较的标记 0不是1是
func CompareJxAndVendor(vendorID int, storeIDStr, vendorStoreID, storeName string, filterJxSkuInfoMap map[int]*dao.StoreSkuNameExt, filterVendorSkuInfoMap map[int]*partner.SkuNameInfo, isJd int) {
//utils.Writelog("进入 CompareJxAndVendor 方法")
for skuID, jxSkuInfo := range filterJxSkuInfoMap {
skuIDStr := utils.Int2Str(skuID)
/*写京西skuIDStr*/
//utils.Writelog("skuIDStr" + skuIDStr)
var jxSkuDetailName string
//多规格商品不用比较数量单位
if jxSkuInfo.IsSpu == 0 {
//jxSkuDetailName : 前缀 ([荐]) + 分类名(xxx水饺) + 数量单位(约..g/份) + 注释 (补充..)
jxSkuDetailName = jxutils.ComposeSkuNameOriginal(jxSkuInfo.SkuName.Prefix, jxSkuInfo.SkuName.Name, jxSkuInfo.Skus[0].Comment, jxSkuInfo.SkuName.Unit, jxSkuInfo.Skus[0].SkuSpecQuality, jxSkuInfo.Skus[0].SkuSpecUnit, 0)
} else {
//jxSkuDetailName : 前缀 ([荐]) + 分类名(xxx水饺) + 数量单位(约..g/份) + 注释 (补充..)
jxSkuDetailName = jxutils.ComposeSkuNameOriginal(jxSkuInfo.SkuName.Prefix, jxSkuInfo.SkuName.Name, jxSkuInfo.Skus[0].Comment, "", jxSkuInfo.Skus[0].SkuSpecQuality, "", 0)
}
//utils.Writelog("jxSkuDetailName:" + jxSkuDetailName)
//jxSkuSaleStatus : 商品状态 skustatus 优先级高于 StoreSkuStatus
jxSkuSaleStatus := jxutils.MergeSkuStatus(jxSkuInfo.Skus[0].SkuStatus, jxSkuInfo.Skus[0].StoreSkuStatus)
jxSkuSaleStatusName := GetSkuSaleStatusName(jxSkuSaleStatus + 3)
/*京西价格*/
jxSkuPrice := fmt.Sprintf("%.2f", float64(jxSkuInfo.Skus[0].JxPrice)/float64(100))
/*饿了吗编码*/
ebaiid := jxSkuInfo.Skus[0].EbaiID
/*美团编码*/
mtwmid := jxSkuInfo.Skus[0].MtwmID
//jxSkuPrice := strconv.Itoa(jxSkuInfo.Skus[0].JxPrice)
vendorSkuInfo := filterVendorSkuInfoMap[skuID]
var status int8
if vendorID == model.VendorIDMTWM {
status = jxSkuInfo.Skus[0].MtwmSyncStatus
} else if vendorID == model.VendorIDEBAI {
status = jxSkuInfo.Skus[0].EbaiSyncStatus
} else if vendorID == model.VendorIDJD {
status = jxSkuInfo.Skus[0].JdSyncStatus
}
syncStatus := utils.Int2Str(int(status))
toBeCreate := GetBoolName(model.IsSyncStatusNeedCreate(status))
toBeDel := GetBoolName(model.IsSyncStatusNeedDelete(status))
if vendorSkuInfo != nil {
vendorSkuDetailName := vendorSkuInfo.SkuList[0].SkuName
vendorSkuSaleStatusName := GetSkuSaleStatusName(vendorSkuInfo.SkuList[0].Status + 3)
/* 供货商价格 */
vendorPrice := fmt.Sprintf("%.2f", float64(vendorSkuInfo.SkuList[0].StoreSkuInfo.VendorPrice)/float64(100))
var IdMark bool
if isJd == 0 {
IdMark = skuIDStr != ebaiid && skuIDStr != mtwmid
} else {
IdMark = false
}
isSaleStatusDiff := jxSkuSaleStatusName != vendorSkuSaleStatusName
isNameDiff := jxSkuDetailName != vendorSkuDetailName
/*比较价格*/
isPriceDiff := vendorPrice != jxSkuPrice
//utils.Writelog("isSaleStatusDiff:" + strconv.FormatBool(isSaleStatusDiff))
//utils.Writelog("isNameDiff:" + strconv.FormatBool(isNameDiff))
if jxSkuDetailName != "" && vendorSkuDetailName != "" && strings.Contains(jxSkuDetailName, vendorSkuDetailName) {
isNameDiff = false
}
if isSaleStatusDiff || isNameDiff || isPriceDiff {
reason := ""
if isNameDiff {
reason += DatAanalyse3
}
if isSaleStatusDiff {
reason += DatAanalyse4
}
if isPriceDiff {
reason += DatAanalyse9
}
if IdMark {
reason += DatAanalyse10
}
if status != model.SkuStatusDontSale {
reason += DatAanalyse7
}
outPutData := DiffData{storeIDStr, vendorStoreID, storeName, skuIDStr, mtwmid, ebaiid, syncStatus, toBeCreate, toBeDel, jxSkuDetailName, vendorSkuDetailName, jxSkuSaleStatusName, vendorSkuSaleStatusName, jxSkuPrice, vendorPrice, reason}
diffData.AppendData(vendorID, outPutData)
}
if !isSaleStatusDiff && !isNameDiff {
if status != model.SkuStatusDontSale {
outPutData := DiffData{storeIDStr, vendorStoreID, storeName, skuIDStr, mtwmid, ebaiid, syncStatus, toBeCreate, toBeDel, jxSkuDetailName, vendorSkuDetailName, jxSkuSaleStatusName, vendorSkuSaleStatusName, jxSkuPrice, vendorPrice, DatAanalyse7}
diffData.AppendData(vendorID, outPutData)
}
}
} else {
if isFilterToBeCreateAndNotSale && model.IsSyncStatusNeedCreate(status) && !IsSkuCanSale(jxSkuSaleStatus) {
continue
}
reason := ""
if status == model.SkuStatusDontSale {
reason = DatAanalyse8
} else {
reason = DatAanalyse2
}
if status != model.SkuStatusDontSale {
reason += DatAanalyse7
}
outPutData := DiffData{storeIDStr, vendorStoreID, storeName, skuIDStr, mtwmid, ebaiid, syncStatus, toBeCreate, toBeDel, jxSkuDetailName, "", jxSkuSaleStatusName, "", jxSkuPrice, "", reason}
diffData.AppendData(vendorID, outPutData)
}
}
for skuID, vendorSkuInfo := range filterVendorSkuInfoMap {
if vendorSkuInfo != nil {
if len(vendorSkuInfo.SkuList) > 0 {
skuIDStr := utils.Int2Str(skuID)
vendorSkuDetailName := vendorSkuInfo.SkuList[0].SkuName
vendorSkuSaleStatusName := GetSkuSaleStatusName(vendorSkuInfo.SkuList[0].Status + 3)
/* 供货商价格 */
vendorPrice := fmt.Sprintf("%.2f", float64(vendorSkuInfo.SkuList[0].StoreSkuInfo.VendorPrice)/float64(100))
/* 供货商价格 */
jxSkuInfo := filterJxSkuInfoMap[skuID]
/*平台有,京西没有*/
if jxSkuInfo == nil {
outPutData := DiffData{storeIDStr, vendorStoreID, "", "", storeName, skuIDStr, "", "", "", "", vendorSkuDetailName, "", vendorSkuSaleStatusName, "", vendorPrice, DatAanalyse1}
diffData.AppendData(vendorID, outPutData)
}
} else {
globals.SugarLogger.Warnf("CompareJxAndVendor vendorSkuInfo.SkuList:%d is nil", skuID)
}
} else {
globals.SugarLogger.Warnf("CompareJxAndVendor skuID:%d is nil", skuID)
}
}
}
func FilterJxDepotUnSaleSkuID() {
db := dao.GetDB()
filterJxDepotUnSaleSkuIds = filterJxDepotUnSaleSkuIds[0:0]
skuList, _ := dao.GetSkus(db, filterVendorDepotUnSaleSkuIds, []int{}, []int{}, []int{}, nil)
filterJxSkuInfoMap2 := GetFilterJxSkuInfoMap2(skuList)
for skuid, jxSkuInfo := range filterJxSkuInfoMap2 {
//过滤掉平台库下架,且京西库下架的商品,为下面比较门店商品用
if jxSkuInfo.Status != model.SkuStatusDontSale {
filterJxDepotUnSaleSkuIds = append(filterJxDepotUnSaleSkuIds, skuid)
}
}
}
func CompareJxAndMultiVenderDepot(ctx *jxcontext.Context, vendorMap map[int]bool) {
db := dao.GetDB()
for vendorID, _ := range vendorNameList {
//filter for vendorID
if len(vendorMap) > 0 {
if _, ok := vendorMap[vendorID]; !ok {
continue
}
}
if partner.IsMultiStore(vendorID) {
FilterJxDepotUnSaleSkuID()
filterVendorSkuInfoMap := GetFilterVendorSkuInfoMap(skuNameInfoList)
skuNameInfoList = skuNameInfoList[0:0]
skuList, _ := dao.GetSkus(db, []int{}, []int{}, []int{}, []int{}, nil)
filterJxSkuInfoMap2 := GetFilterJxSkuInfoMap2(skuList)
for skuid, jxSkuInfo := range filterJxSkuInfoMap2 {
var jxSkuDetailName string
//多规格商品不用比较数量单位
if jxSkuInfo.IsSpu == 0 {
jxSkuDetailName = jxutils.ComposeSkuNameOriginal(jxSkuInfo.Prefix, jxSkuInfo.Name, jxSkuInfo.Comment, jxSkuInfo.Unit, jxSkuInfo.SpecQuality, jxSkuInfo.SpecUnit, 0)
} else {
jxSkuDetailName = jxutils.ComposeSkuNameOriginal(jxSkuInfo.Prefix, jxSkuInfo.Name, jxSkuInfo.Comment, "", jxSkuInfo.SpecQuality, "", 0)
}
vendorSkuInfoMap := filterVendorSkuInfoMap[skuid]
jxSkuSaleStatus := jxSkuInfo.Status
jxSkuSaleStatusName := GetSkuSaleStatusName(jxSkuSaleStatus)
skuIDStr := utils.Int2Str(skuid)
if vendorSkuInfoMap != nil {
vendorSkuSaleStatusName := GetSkuSaleStatusName(vendorSkuInfoMap.SkuList[0].Status)
vendorSkuDetailName := vendorSkuInfoMap.SkuList[0].SkuName
isSaleStatusDiff := jxSkuSaleStatusName != vendorSkuSaleStatusName
isNameDiff := strings.Compare(jxSkuDetailName, vendorSkuDetailName) != 0
if isNameDiff || isSaleStatusDiff {
reason := ""
if isNameDiff {
reason += DatAanalyse3
}
if isSaleStatusDiff {
reason += DatAanalyse4
}
outPutData := DepotDiffData{skuIDStr, jxSkuDetailName, vendorSkuDetailName, jxSkuSaleStatusName, vendorSkuSaleStatusName, reason}
depotDiffData.AppendData2(vendorID, outPutData)
}
} else {
outPutData := DepotDiffData{skuIDStr, jxSkuDetailName, "", jxSkuSaleStatusName, "", DatAanalyse6}
depotDiffData.AppendData2(vendorID, outPutData)
}
}
for skuID, vendorSkuInfo := range filterVendorSkuInfoMap {
if vendorSkuInfo != nil {
if len(vendorSkuInfo.SkuList) > 0 {
skuIDStr := utils.Int2Str(skuID)
vendorSkuDetailName := vendorSkuInfo.SkuList[0].SkuName
vendorSkuSaleStatusName := GetSkuSaleStatusName(vendorSkuInfo.SkuList[0].Status + 3)
jxSkuInfo := filterJxSkuInfoMap2[skuID]
if jxSkuInfo == nil {
outPutData := DepotDiffData{skuIDStr, "", vendorSkuDetailName, "", vendorSkuSaleStatusName, DatAanalyse5}
depotDiffData.AppendData2(vendorID, outPutData)
}
} else {
globals.SugarLogger.Warnf("CompareJxAndMultiVenderDepot vendorSkuInfo.SkuList:%d is nil", skuID)
}
} else {
globals.SugarLogger.Warnf("CompareJxAndMultiVenderDepot skuID:%d is nil", skuID)
}
}
}
}
}
func StoreOpenAll(ctx *jxcontext.Context) {
/* 美团配送的门店营业状态,如果是休息,则京西这边不发单,如果是营业,京西这边状态就是发单
美团配送的门店营业状态要通过网页扒取(应该是接了的代码里要找一下)*/
/*获取门店信息*/
//type DataList struct {
// OuterPoiId string `json:"outerPoiId"` //店ID
// PoiName string `json:"poiName"` //店名
// OpenType int `json:"openType"` //营业状态 1是营业 0是休息
//}
//type jdData struct {
// PageNum int `json:"pageNum"`
// PageSize int `json:"pageSize"`
// DataList []DataList `json:"dataList"`
//}
//type JdStore struct {
// Code int `json:"code"`
// Msg string `json:"msg"`
// Data1 jdData `json:"data"`
//}
//client := &http.Client{}
//var StoreInfoList []*JdStore
//complate := make(chan bool, 1)
//cookie := "_lxsdk_cuid=172c5ed322ac8-081f1f7ebdcbeb-f7d1d38-149c48-172c5ed322ac8; " +
// "_lxsdk=172c5ed322ac8-081f1f7ebdcbeb-f7d1d38-149c48-172c5ed322ac8; " +
// "uuid=fa1894be8819a84be4ef.1592458555.1.0.0; wm_order_channel=sjzxpc; " +
// "cssVersion=82f258e3; utm_source=60376; au_trace_key_net=default; " +
// "openh5_uuid=172c5ed322ac8-081f1f7ebdcbeb-f7d1d38-149c48-172c5ed322ac8; " +
// "bmm-uuid=dbdc11bf-fcfe-84a0-0586-97e3d7d23ec7; " +
// "token=-MfbU7noKEgDWuNA559DeG6LmYZ51CCiH8bYrH-eYuaugCOqJL7863lKoAWfx8HoydOzJE8r9gGM3QJ0IC3niA; " +
// "_lxsdk_s=172fa436aed-861-103-c9b%7C%7C7"
//go func() {
// num := 1
// for {
// /* cookie还需要修改*/
// /* context.TODO()*/
// url := "https://peisong.meituan.com/api/haikuiopen/haikui/open/partner/poi/search?pageSize=20&pageNum=" + strconv.Itoa(num) + ""
// req, _ := http.NewRequest("POST", url, nil)
// req.Header.Set("Cookie", cookie)
// req.Header.Set("Referer", "https://peisong.meituan.com/open/admin/accountList")
// res, _ := client.Do(req)
// //defer res.Body.Close()
// if res.Body != nil {
// StoreInfo := &JdStore{}
// body, _ := ioutil.ReadAll(res.Body)
// json.Unmarshal(body, StoreInfo)
// if len(StoreInfo.Data1.DataList) == 0 || StoreInfo.Data1.DataList == nil {
// complate <- true
// }
// StoreInfoList = append(StoreInfoList, StoreInfo)
// num++
// } else {
// complate <- true
// }
// }
//}()
//select {
//case <-complate:
// break
//}
///*StoreInfoList1 map[11691658]=1*/
//StoreInfoList1 := make(map[string]int)
//for _, store := range StoreInfoList {
// for _, data := range store.Data1.DataList {
// StoreInfoList1[data.OuterPoiId] = data.OpenType
// }
//}
StoreInfoList, err := api.MtpsAPI.GetStoreStatusAll()
StoreInfoList1 := make(map[string]int)
for _, store := range StoreInfoList {
for _, data := range store.DataList {
StoreInfoList1[data.OuterPoiID] = data.OpenType
}
}
/* fmt.Println(num)
fmt.Println(StoreInfoList)*/
db := dao.GetDB()
/*比较营业状态*/
StoreCourierList, err := dao.GetStoreCourierList(db, []int{}, -9, -9)
for _, StoreCourierList1 := range StoreCourierList {
/*如果京西店在美团上没有,那下面有专门方法处理*/
if _, ok := StoreInfoList1[StoreCourierList1.VendorStoreID]; ok {
/*京西配送状态为配送,美团营业状态是没有营业的*/
if StoreCourierList1.Status == 1 && StoreInfoList1[StoreCourierList1.VendorStoreID] == 0 {
sl := make(map[string]interface{})
sl["status"] = 0
sl["vendorStoreID"] = StoreCourierList1.VendorStoreID
UpdateStoreCourierMap(ctx, nil, StoreCourierList1.StoreID, StoreCourierList1.VendorID, sl, ctx.GetUserName())
/*京西配送状态为不配送,美团营业状态是营业的*/
} else if StoreCourierList1.Status != 1 && StoreInfoList1[StoreCourierList1.VendorStoreID] == 1 {
sl := make(map[string]interface{})
sl["status"] = 1
sl["vendorStoreID"] = StoreCourierList1.VendorStoreID
UpdateStoreCourierMap(ctx, nil, StoreCourierList1.StoreID, StoreCourierList1.VendorID, sl, ctx.GetUserName())
}
}
}
/* 美团配送的门店是否存在调用美团配送的api有可能接了查询京西门店对应的美团配送门店是否存在若不存在则要在京西这边解绑美团配送门店
怎么解绑可以在网页上门店管理那点一下看看调的什么接口,传的什么参数*/
/*获取所有门店信息*/
StoreLists, err := dao.GetStoreList(db, nil, nil, []int{}, nil, "")
if err != nil {
globals.SugarLogger.Debug(err.Error())
}
for _, StoreList := range StoreLists {
StoreCourierList, err := dao.GetStoreCourierList(db, []int{StoreList.ID}, model.StoreStatusAll, model.StoreStatusAll)
if err != nil {
globals.SugarLogger.Debug(err.Error())
}
for _, StoreCourierList1 := range StoreCourierList {
if StoreCourierList1.VendorID != model.VendorIDMTPS {
continue
}
if StoreCourierList1.Status == model.StoreStatusDisabled {
continue
}
/*京西不为空*/
if StoreCourierList1.VendorStoreID != "" {
/*调用API获取美团的商店信息*/
MTPSInfo, _ := api.MtpsAPI.ShopQuery(StoreCourierList1.VendorStoreID)
/*京西有,美团没有*/
if MTPSInfo == nil {
fmt.Println(strconv.Itoa(StoreCourierList1.StoreID) + " 被解绑")
if _, err := DeleteStoreCourierMap(ctx, db, StoreCourierList1.StoreID, StoreCourierList1.VendorID, ctx.GetUserName()); err != nil {
globals.SugarLogger.Debug(err.Error())
return
}
continue
}
/* 果园和菜市的门店ID可能有重复导致在美团配送上建的门店只有一方的门店是生效的可以根据ID在美团配送上查查到是果园的店那菜市的店则要重新绑定美团配送要换一个美团配送的门店ID。不然要重复
反之也要,可根据其他信息,比如门店名(传到平台上的规则都是一样的),坐标等判断是果园的还是菜市的*/
/*美团上坐标不为空,容错 PS用名字的话本身就没办法判断是菜市还是果园*/
if MTPSInfo.ShopLng != 0 && MTPSInfo.ShopLat != 0 {
if MTPSInfo.ShopLng == StoreList.Lng && MTPSInfo.ShopLat == StoreList.Lat {
/*平台上有且坐标相同不做处理*/
continue
} else {
/*平台上但是坐标不同,解绑*/
fmt.Println(strconv.Itoa(StoreCourierList1.StoreID) + " 被解绑")
if _, err := DeleteStoreCourierMap(ctx, db, StoreCourierList1.StoreID, StoreCourierList1.VendorID, ctx.GetUserName()); err != nil {
globals.SugarLogger.Debug(err.Error())
return
}
}
} else { //容错
/*美团平台上面没找到,解绑*/
fmt.Println(strconv.Itoa(StoreCourierList1.StoreID) + " 被解绑")
if _, err := DeleteStoreCourierMap(ctx, db, StoreCourierList1.StoreID, StoreCourierList1.VendorID, ctx.GetUserName()); err != nil {
globals.SugarLogger.Debug(err.Error())
return
}
//} else {
// 美团平台上有,京西没得,调用方法可能需要做一些修改
// context.TODO()
//}
}
}
}
}
}
//func StoreOpenAll(ctx *jxcontext.Context) {
//db := dao.GetDB()
///*获取所有门店信息*/
//StoreLists, err := dao.GetStoreList(db, nil, nil, []int{}, nil, "")
//if err != nil {
// globals.SugarLogger.Debugf("商店列表获取失败")
//}
///*距离结构体*/
//type Distance struct {
// StoreID string `json:"门店ID"`
// StoreStatus string `json:"门店状态"`
// StoreName string `json:"门店名"`
// Tel string `json:"电话"`
// City string `json:"城市"`
// Address string `json:"地址"`
// DistanceId string `json:"附近门店ID"`
// DistanceStatus string `json:"附近门店状态"`
// DistanceName string `json:"附近门店名"`
// DistanceAddress string `json:"附近门店地址"`
// DistanceValue string `json:"距离附近门店距离(m)"`
//}
//distanceStore := make(map[int][]Distance)
//var isCloud []string
//var CloudBool bool
//for _, StoreList := range StoreLists {
// /*循环内部声明1对多*/
// var a []Distance
// lng := jxutils.IntCoordinate2Standard(StoreList.Lng)
// lat := jxutils.IntCoordinate2Standard(StoreList.Lat)
// for _, StoreList1 := range StoreLists {
// if StoreList1.ID == StoreList.ID {
// continue
// }
// /*把s与提前存好的字段对比如果相同说明 A+B=B+A的情况直接跳过*/
// s := strconv.Itoa(StoreList1.ID) + strconv.Itoa(StoreList.ID)
// for _, x := range isCloud {
// if s == x {
// CloudBool = true
// break
// }
// }
// if CloudBool == true{
// CloudBool = false
// continue
// }
// lng1 := jxutils.IntCoordinate2Standard(StoreList1.Lng)
// lat1 := jxutils.IntCoordinate2Standard(StoreList1.Lat)
// if jxutils.EarthDistance(lng, lat, lng1, lat1) < 0.5 {
// //门店ID门店名电话城市地址附近门店ID附近门店名距离附近门店距离m)
// b := &Distance{
// strconv.Itoa(StoreList.ID),
// strconv.Itoa(StoreList.Status),
// StoreList.Name,
// StoreList.Tel1,
// strconv.Itoa(StoreList.CityCode),
// StoreList.Address,
// strconv.Itoa(StoreList1.ID),
// strconv.Itoa(StoreList1.Status),
// StoreList1.Name,
// StoreList1.Address,
// fmt.Sprintf("%.2f", jxutils.EarthDistance(lng, lat, lng1, lat1)*1000),
// }
// a = append(a, *b)
// distanceStore[StoreList.ID] = a
// isCloud = append(isCloud, strconv.Itoa(StoreList.ID)+strconv.Itoa(StoreList1.ID))
// }
// }
//}
//
////DistanceTitle := []string{
//// "门店ID",
//// "门店名",
//// "电话",
//// "城市",
//// "地址",
//// "附近门店ID",
//// "附近门店名",
//// "距离附近门店距离(m)",
////}
//fmt.Println(len(distanceStore))
//xlsx := excelize.NewFile()
//index := xlsx.NewSheet("Sheet1")
//xlsx.SetCellValue("Sheet1", "A1", "门店ID")
//xlsx.SetCellValue("Sheet1", "B1", "门店状态")
//xlsx.SetCellValue("Sheet1", "C1", "门店名")
//xlsx.SetCellValue("Sheet1", "D1", "电话")
//xlsx.SetCellValue("Sheet1", "E1", "城市")
//xlsx.SetCellValue("Sheet1", "F1", "地址")
//xlsx.SetCellValue("Sheet1", "G1", "附近门店ID")
//xlsx.SetCellValue("Sheet1", "H1", "附近门店状态")
//xlsx.SetCellValue("Sheet1", "I1", "附近门店名")
//xlsx.SetCellValue("Sheet1", "J1", "附近门店地址")
//xlsx.SetCellValue("Sheet1", "K1", "距离附近门店距离(M)")
//i := 2
//for _, value := range distanceStore {
// for _, value1 := range value {
// xlsx.SetCellValue("Sheet1", "A"+strconv.Itoa(i), value1.StoreID)
// xlsx.SetCellValue("Sheet1", "B"+strconv.Itoa(i), value1.StoreStatus)
// xlsx.SetCellValue("Sheet1", "C"+strconv.Itoa(i), value1.StoreName)
// xlsx.SetCellValue("Sheet1", "D"+strconv.Itoa(i), value1.Tel)
// xlsx.SetCellValue("Sheet1", "E"+strconv.Itoa(i), value1.City)
// xlsx.SetCellValue("Sheet1", "F"+strconv.Itoa(i), value1.Address)
// xlsx.SetCellValue("Sheet1", "G"+strconv.Itoa(i), value1.DistanceId)
// xlsx.SetCellValue("Sheet1", "H"+strconv.Itoa(i), value1.DistanceStatus)
// xlsx.SetCellValue("Sheet1", "I"+strconv.Itoa(i), value1.DistanceName)
// xlsx.SetCellValue("Sheet1", "J"+strconv.Itoa(i), value1.DistanceAddress)
// xlsx.SetCellValue("Sheet1", "K"+strconv.Itoa(i), value1.DistanceValue)
// i++
// }
//}
//// Set active sheet of the workbook.
//xlsx.SetActiveSheet(index)
//// Save xlsx file by the given path.
//err = xlsx.SaveAs("C:\\Users\\86159\\Desktop\\WorkForTemp\\距离小于500米门店信息.xlsx")
//if err != nil {
// fmt.Println(err)
//}
//var sheetList []*excel.Obj2ExcelSheetConfig
//sheetName := "附近500米门店信息"
//for _, value := range distanceStore {
// excelConf := &excel.Obj2ExcelSheetConfig{
// Title: sheetName,
// Data: value,
// CaptionList: DistanceTitle,
// }
// file,err := os.OpenFile("C:\\Users\\86159\\Desktop\\WorkForTemp\\haha.txt",os.O_APPEND|os.O_RDWR,6660)
// if err != nil{
// fmt.Println(err.Error())
// }
// file.WriteString(fmt.Sprintln(excelConf.Data))
// sheetList = append(sheetList, excelConf)
// baseapi.SugarLogger.Debugf("WriteToExcel:append:%s count:%d", sheetName, len(value))
//}
//if len(sheetList) > 0 {
// excelBin := excel.Obj2Excel(sheetList)
// sheetList = nil
// timeStr := utils.Int64ToStr(time.Now().Unix())
// diffFullFileName := "附近500米门店信息数据" + timeStr + fileExt
// baseapi.SugarLogger.Debugf("WriteToExcel:save %s success", diffFullFileName)
// //上传
// downloadURL, err := jxutils.UploadExportContent(excelBin, diffFullFileName)
// if err != nil {
// baseapi.SugarLogger.Errorf("WriteToExcel:upload %s failed error:%v", diffFullFileName, err)
// } else {
// baseapi.SugarLogger.Debugf("WriteToExcel:upload %s success, downloadURL: %s", diffFullFileName, downloadURL)
// /*************发送钉钉消息**************/
// //ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "", "异步任务完成", "附近500米门店信息数据上传成功Excel下载地址是 "+downloadURL)
// }
//} else {
// baseapi.SugarLogger.Debug("WriteToExcel:No diff data!!!")
//}
//}
//}func StoreOpenAll(ctx *jxcontext.Context) {
// db := dao.GetDB()
// StoreLists, err := dao.GetStoreList(db, nil, nil, []int{1}, nil, "")
// if err != nil {
// globals.SugarLogger.Debugf("商店列表获取失败")
// }
// var StoreMapLists []*model.StoreMap
// for _, StoreList := range StoreLists {
// if StoreMapLists, err = dao.GetStoresMapList(db, []int{0, 1, 3}, []int{StoreList.ID}, nil, 1, -1, "", ""); err != nil {
// globals.SugarLogger.Debugf("商店列表获取失败")
// }
// if len(StoreMapLists) > 0 {
// /*将map查询的结果全部放进数组*/
// for _, StoreMapList := range StoreMapLists {
// /*二元运算符*/
// StoreMapList.SyncStatus = StoreMapList.SyncStatus | model.SyncFlagModifiedMask
// StoreMapList.UpdatedAt = time.Now()
// StoreMapList.LastOperator = ctx.GetUserName()
// dao.UpdateEntity(db, StoreMapList, "SyncStatus", "UpdatedAt", "LastOperator")
// //}
// /*同步*/
// if _, err = CurVendorSync.SyncStore(ctx, db, StoreMapList.VendorID, StoreList.ID, false, ctx.GetUserName()); err != nil {
// globals.SugarLogger.Debugf("同步失败")
// }
// }
// }
// if StoreMapLists, err = dao.GetStoresMapList(db, []int{9}, []int{StoreList.ID}, nil, 1, -1, "", ""); err != nil {
// globals.SugarLogger.Debugf("商店列表获取失败")
// }
// if len(StoreMapLists) == 0 {
// /*遍历,绑定*/
// Map := &model.StoreMap{}
// Map.VendorStoreID = strconv.Itoa(StoreList.ID)
// Map.AutoPickup = 1
// Map.DeliveryCompetition = 1
// Map.PricePercentage = 100
// Map.IsSync = 1
// Map.PricePercentagePack = "京西100-100"
// Map.DeliveryFeeDeductionSill = 0
// Map.DeliveryFeeDeductionFee = 0
// Map.IsOrder = 0
// if _, err := AddStoreVendorMap(ctx, db, 9, "", StoreList.ID, Map); err != nil {
// globals.SugarLogger.Debugf("AddStoreVendorMap调用出错StoreID是" + strconv.Itoa(StoreList.ID))
// globals.SugarLogger.Debugf(err.Error())
// }
// }
// /*改配送范围*/
// //deliverrangetype 3
// //deliverrange 3000
// StoreList.DeliveryRange = "3000"
// StoreList.DeliveryRangeType = 3
// StoreList.UpdatedAt = time.Now()
// StoreList.LastOperator = ctx.GetUserName()
// dao.UpdateEntity(db, StoreList, "DeliveryRange", "DeliveryRangeType", "LastOperator", "UpdatedAt")
// }
//}
func TestDiff(ctx *jxcontext.Context, vendorIDList []int, storeIDList []int) {
baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor start time: %v", time.Now())
startProcessTime := time.Now().Unix()
vendorMap := make(map[int]bool)
for _, vendorID := range vendorIDList {
vendorMap[vendorID] = true //map[平台ID:true]
}
storeIDMap := make(map[int]bool)
for _, storeID := range storeIDList {
storeIDMap[storeID] = true //map[门店ID:true]
}
/************************************************update**************************************************/
//自己存值
a := func() {
for vendorID, _ := range vendorNameList {
//filter for vendorID
if len(vendorMap) > 0 {
if _, ok := vendorMap[vendorID]; !ok {
continue
}
}
if partner.IsMultiStore(vendorID) {
multiHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler)
for _, vendorOrgCode := range apimanager.CurAPIManager.GetAppOrgCodeList(vendorID) {
allSkuNameInfoList, err := multiHandler.GetSkus(ctx, vendorOrgCode, 0, "")
//获取单个表格对比的物品信息列表
skuNameInfoList = allSkuNameInfoList
if err != nil {
fmt.Println("allSkuNameInfoList赋值错误error信息" + err.Error())
continue
}
//*partner.StoreSkuInfo skuNameList []*SkuNameInfo
var bareStoreSkuList []*partner.StoreSkuInfo
for _, v := range allSkuNameInfoList {
for _, v2 := range v.SkuList {
if v2.Status > model.SkuStatusDontSale {
for _, v2 := range v.SkuList {
bareStoreSkuList = append(bareStoreSkuList, &v2.StoreSkuInfo)
}
}
}
}
//if multiStoreAllSkuInfoList[vendorID][vendorOrgCode] != nil && bareStoreSkuList != nil {
if multiStoreAllSkuInfoList[vendorID] != nil && bareStoreSkuList != nil {
multiStoreAllSkuInfoList[vendorID][vendorOrgCode] = bareStoreSkuList
//}else if multiStoreAllSkuInfoList[vendorID][vendorOrgCode] == nil{
} else if multiStoreAllSkuInfoList[vendorID] == nil {
multiStoreAllSkuInfoList = make(map[int]map[string][]*partner.StoreSkuInfo)
multiStoreAllSkuInfoList[vendorID] = make(map[string][]*partner.StoreSkuInfo)
multiStoreAllSkuInfoList[vendorID][vendorOrgCode] = bareStoreSkuList
}
tempMap := make(map[int]*partner.SkuNameInfo)
for _, value := range allSkuNameInfoList {
for _, skuInfo := range value.SkuList {
//表示平台商品库未下架的
if skuInfo.Status > model.SkuStatusDontSale {
filterVendorDepotUnSaleSkuIds = append(filterVendorDepotUnSaleSkuIds, skuInfo.SkuID)
tempMap[skuInfo.SkuID] = value
}
}
}
//商品信息
if multiStoreAllSkuInfoMap[vendorID] == nil {
multiStoreAllSkuInfoMap = make(map[int]map[string]map[int]*partner.SkuNameInfo)
multiStoreAllSkuInfoMap[vendorID] = make(map[string]map[int]*partner.SkuNameInfo)
//multiStoreAllSkuInfoMap[vendorID][vendorOrgCode] = make(map[int]*partner.SkuNameInfo)
multiStoreAllSkuInfoMap[vendorID][vendorOrgCode] = tempMap
} else {
multiStoreAllSkuInfoMap[vendorID][vendorOrgCode] = tempMap
}
}
}
}
}
/************************************************update****************************************************/
//1.获取京西本地所有门店信息 store、place、user表联查 jxStoreInfoList
//2.过滤所有门店信息只留下传进来的vendorMapstoreIDMap中对应的平台和门台信息 filterStoreList
//3.判断是否多平台门店,两种情况两种处理
b := func() {
jxStoreInfoList, err := GetStores(ctx, "", map[string]interface{}{}, 0, -1, utils.DefaultTimeValue, utils.DefaultTimeValue, 0, 0)
if err != nil {
baseapi.SugarLogger.Errorf("CheckSkuDiffBetweenJxAndVendor GetStores error:%v", err)
} else {
//获取总共几个门店任务
filterStoreList := GetFilterStoreList(jxStoreInfoList.Stores, vendorMap, storeIDMap)
diffData.InitData()
jxStoreInfoListValue := filterStoreList[0]
storeID := jxStoreInfoListValue.ID
storeIDStr := utils.Int2Str(storeID)
storeName := jxStoreInfoListValue.Name
jxSkuInfoDataSingle := &dao.StoreSkuNamesInfo{}
jxSkuInfoDataMulti := &dao.StoreSkuNamesInfo{}
if jxStoreInfoListValue.StoreMaps != nil {
var multiFlag = false
var singleFlag = false
var filterJxSkuInfoMapSingle map[int]*dao.StoreSkuNameExt
var filterJxSkuInfoMapMulti map[int]*dao.StoreSkuNameExt
for _, vendorListValue := range jxStoreInfoListValue.StoreMaps {
vendorID := vendorListValue.VendorID
if partner.IsMultiStore(vendorID) {
if multiFlag == false {
jxSkuInfoDataMulti, _ = GetStoreSkus(ctx, storeID, filterJxDepotUnSaleSkuIds, true, "", true, false, map[string]interface{}{}, 0, -1)
/*重新计算价格*/
SetJxPrice(jxSkuInfoDataMulti, storeID)
filterJxSkuInfoMapMulti = GetFilterJxSkuInfoMap(jxSkuInfoDataMulti.SkuNames) //map[京西商品ID:StoreSkuNameExt]
multiFlag = true
}
} else {
if singleFlag == false {
jxSkuInfoDataSingle, _ = GetStoreSkus(ctx, storeID, nil, true, "", true, false, map[string]interface{}{}, 0, -1)
filterJxSkuInfoMapSingle = GetFilterJxSkuInfoMap(jxSkuInfoDataSingle.SkuNames) //map[京西商品ID:StoreSkuNameExt]
singleFlag = true
}
}
vendorStoreID := vendorListValue.VendorStoreID
baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor storeID:%d vendorID:%d vendorStoreID:%s vendorListValue:%v", storeID, vendorID, vendorStoreID, vendorListValue)
if partner.IsMultiStore(vendorID) {
singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler)
allSkuInfoList := GetMultiStoreAllSkuInfoList(vendorID, vendorListValue.VendorOrgCode)
skuBareInfoList, err := singleStoreHandler.GetStoreSkusBareInfo(ctx, vendorListValue.VendorOrgCode, nil, storeID, vendorStoreID, allSkuInfoList)
if err != nil {
baseapi.SugarLogger.Infof("CheckSkuDiffBetweenJxAndVendor GetStoreSkusBareInfo error:%v", err)
} else if len(skuBareInfoList) > 0 {
//获取京东的商品
filterSkuInfoMap := GetFilterMultiStoreSkuInfoMap(vendorID, vendorListValue.VendorOrgCode, skuBareInfoList) //map[京东商品ID:SkuNameInfo]
CompareJxAndVendor(vendorID, storeIDStr, vendorStoreID, storeName, filterJxSkuInfoMapMulti, filterSkuInfoMap, 1)
}
} else {
singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler)
vendorSkuInfoList, err := singleStoreHandler.GetStoreSkusFullInfo(ctx, nil, storeID, vendorStoreID, nil)
if err != nil {
baseapi.SugarLogger.Infof("CheckSkuDiffBetweenJxAndVendor GetStoreSkusFullInfo error:%v", err)
} else if len(vendorSkuInfoList) > 0 {
//获取京东的商品
filterVendorSkuInfoMap := GetFilterVendorSkuInfoMap(vendorSkuInfoList) //map[平台商品ID:SkuNameInfo]
CompareJxAndVendor(vendorID, storeIDStr, vendorStoreID, storeName, filterJxSkuInfoMapSingle, filterVendorSkuInfoMap, 0)
}
}
}
}
}
}
/********************************第三步****************************/
c := func(data map[int][]DiffData, depotData map[int][]DepotDiffData) {
var sheetList []*excel.Obj2ExcelSheetConfig
for key, value := range data {
sheetName := vendorNameList[key]
if partner.IsMultiStore(key) {
excelConfDepot := &excel.Obj2ExcelSheetConfig{
Title: sheetName + "商品库与京西商品库对比",
Data: depotData[key],
CaptionList: deoptTitleList,
}
sheetList = append(sheetList, excelConfDepot)
}
excelConf := &excel.Obj2ExcelSheetConfig{
Title: sheetName,
Data: value,
CaptionList: titleList,
}
sheetList = append(sheetList, excelConf)
if needStatistic {
statisticSheet := AddStatisticSheet(sheetName, value)
sheetList = append(sheetList, statisticSheet)
}
baseapi.SugarLogger.Debugf("WriteToExcel:append:%s count:%d", sheetName, len(value))
}
if len(sheetList) > 0 {
excelBin := excel.Obj2Excel(sheetList)
sheetList = nil
timeStr := utils.Int64ToStr(time.Now().Unix())
diffFullFileName := diffFileName[IsJXCS()] + timeStr + fileExt
if canWriteTolocal {
jxutils.WriteFile(diffFullFileName, excelBin)
}
baseapi.SugarLogger.Debugf("WriteToExcel:save %s success", diffFullFileName)
//上传
downloadURL, err := jxutils.UploadExportContent(excelBin, diffFullFileName)
if err != nil {
baseapi.SugarLogger.Errorf("WriteToExcel:upload %s failed error:%v", diffFullFileName, err)
} else {
baseapi.SugarLogger.Debugf("WriteToExcel:upload %s success, downloadURL: %s", diffFullFileName, downloadURL)
/*************发送钉钉消息**************/
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "", "异步任务完成", "京西平台对比数据上传成功Excel下载地址是 "+downloadURL)
}
} else {
baseapi.SugarLogger.Debug("WriteToExcel:No diff data!!!")
}
//}
endProcessTime := time.Now().Unix()
diff := endProcessTime - startProcessTime
baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor end time: %v", time.Now())
baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor cost time: %d sec", diff)
}
apiover := make(chan int, 1)
compover := make(chan int, 1)
over := false
/********************************第三步****************************/
/*异步任务*/
/************************************************************************************/
go func() {
defer func() {
if recover() != nil {
beego.Info("执行任务失败")
panic("API调用失败")
}
}()
a()
depotDiffData.InitData2()
CompareJxAndMultiVenderDepot(ctx, vendorMap)
apiover <- 0
}()
/*a等待a现成执行完*/
go func() {
for !over {
select {
case <-apiover:
/*第二步 为了获取 filterJxDepotUnSaleSkuIds*/
go func() {
defer func() {
if recover() != nil {
beego.Info("比较任务失败")
panic("比较任务失败")
}
}()
b()
compover <- 0 //比较任务完成
}()
/*第二步*/
case <-compover:
go func() {
defer func() {
if recover() != nil {
beego.Info("写入任务失败")
panic("写入任务失败")
}
}()
c(diffData.diffDataMap, depotDiffData.diffDataMap)
fmt.Println("任务执行完成")
over = true
}()
break
}
}
}()
/************************************************************************************/
}
//入口函数,校验本地商品京西和其他平台的差异
func CheckSkuDiffBetweenJxAndVendor(ctx *jxcontext.Context, vendorIDList []int, storeIDList []int) {
startProcessTime := time.Now().Unix()
baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor start time: %v", time.Now())
vendorMap := make(map[int]bool)
for _, vendorID := range vendorIDList {
vendorMap[vendorID] = true //map[平台ID:true]
}
storeIDMap := make(map[int]bool)
for _, storeID := range storeIDList {
storeIDMap[storeID] = true //map[门店ID:true]
}
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
switch step {
case 0:
//获取所有多门店平台的商品信息
//1.循环传进来的平台id如果是多门店的平台查询该门店京东到家平台的所有商品
//2.为multiStoreAllSkuInfoList 和 multiStoreAllSkuInfoMap 赋值
GetMultiStoreAllSkuInfo(ctx, vendorMap)
case 1:
//对比京西库和多门店平台的库的信息
depotDiffData.InitData2()
CompareJxAndMultiVenderDepot(ctx, vendorMap)
case 2:
//1.获取京西本地所有门店信息 store、place、user表联查 jxStoreInfoList
//2.过滤所有门店信息只留下传进来的vendorMapstoreIDMap中对应的平台和门台信息 filterStoreList
//3.判断是否多平台门店,两种情况两种处理
jxStoreInfoList, err := GetStores(ctx, "", map[string]interface{}{}, 0, -1, utils.DefaultTimeValue, utils.DefaultTimeValue, 0, 0)
if err != nil {
baseapi.SugarLogger.Errorf("CheckSkuDiffBetweenJxAndVendor GetStores error:%v", err)
} else {
filterStoreList := GetFilterStoreList(jxStoreInfoList.Stores, vendorMap, storeIDMap)
diffData.InitData()
//循环门店store
taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
jxStoreInfoListValue := batchItemList[0].(*StoreExt)
storeID := jxStoreInfoListValue.ID
storeIDStr := utils.Int2Str(storeID)
storeName := jxStoreInfoListValue.Name
jxSkuInfoDataSingle := &dao.StoreSkuNamesInfo{}
jxSkuInfoDataMulti := &dao.StoreSkuNamesInfo{}
if jxStoreInfoListValue.StoreMaps != nil {
var multiFlag = false
var singleFlag = false
var filterJxSkuInfoMapSingle map[int]*dao.StoreSkuNameExt
var filterJxSkuInfoMapMulti map[int]*dao.StoreSkuNameExt
for _, vendorListValue := range jxStoreInfoListValue.StoreMaps {
vendorID := vendorListValue.VendorID
if partner.IsMultiStore(vendorID) {
if multiFlag == false {
jxSkuInfoDataMulti, _ = GetStoreSkus(ctx, storeID, filterJxDepotUnSaleSkuIds, true, "", true, false, map[string]interface{}{}, 0, -1)
filterJxSkuInfoMapMulti = GetFilterJxSkuInfoMap(jxSkuInfoDataMulti.SkuNames) //map[京西商品ID:StoreSkuNameExt]
multiFlag = true
}
} else {
if singleFlag == false {
jxSkuInfoDataSingle, _ = GetStoreSkus(ctx, storeID, nil, true, "", true, false, map[string]interface{}{}, 0, -1)
filterJxSkuInfoMapSingle = GetFilterJxSkuInfoMap(jxSkuInfoDataSingle.SkuNames) //map[京西商品ID:StoreSkuNameExt]
singleFlag = true
}
}
vendorStoreID := vendorListValue.VendorStoreID
baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor storeID:%d vendorID:%d vendorStoreID:%s vendorListValue:%v", storeID, vendorID, vendorStoreID, vendorListValue)
if partner.IsMultiStore(vendorID) {
singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler)
allSkuInfoList := GetMultiStoreAllSkuInfoList(vendorID, vendorListValue.VendorOrgCode)
skuBareInfoList, err := singleStoreHandler.GetStoreSkusBareInfo(ctx, vendorListValue.VendorOrgCode, task, storeID, vendorStoreID, allSkuInfoList)
if err != nil {
baseapi.SugarLogger.Infof("CheckSkuDiffBetweenJxAndVendor GetStoreSkusBareInfo error:%v", err)
} else if len(skuBareInfoList) > 0 {
filterSkuInfoMap := GetFilterMultiStoreSkuInfoMap(vendorID, vendorListValue.VendorOrgCode, skuBareInfoList) //map[京东商品ID:SkuNameInfo]
CompareJxAndVendor(vendorID, storeIDStr, vendorStoreID, storeName, filterJxSkuInfoMapMulti, filterSkuInfoMap, 1)
}
} else {
singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler)
vendorSkuInfoList, err := singleStoreHandler.GetStoreSkusFullInfo(ctx, task, storeID, vendorStoreID, nil)
if err != nil {
baseapi.SugarLogger.Infof("CheckSkuDiffBetweenJxAndVendor GetStoreSkusFullInfo error:%v", err)
} else if len(vendorSkuInfoList) > 0 {
filterVendorSkuInfoMap := GetFilterVendorSkuInfoMap(vendorSkuInfoList) //map[平台商品ID:SkuNameInfo]
CompareJxAndVendor(vendorID, storeIDStr, vendorStoreID, storeName, filterJxSkuInfoMapSingle, filterVendorSkuInfoMap, 0)
}
}
}
}
return retVal, err
}
taskParallel := tasksch.NewParallelTask("京西和平台商品差异对比-门店商品对比", tasksch.NewParallelConfig().SetParallelCount(parallelCount), ctx, taskFunc, filterStoreList)
tasksch.HandleTask(taskParallel, task, true).Run()
_, err = taskParallel.GetResult(0)
if err != nil {
baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor taskParallel error:%v", err)
}
}
case 3:
WriteToExcel(task, diffData.diffDataMap, depotDiffData.diffDataMap)
endProcessTime := time.Now().Unix()
diff := endProcessTime - startProcessTime
baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor end time: %v", time.Now())
baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor cost time: %d sec", diff)
}
return result, err
}
taskSeq := tasksch.NewSeqTask("京西和平台商品差异对比-序列任务", ctx, taskSeqFunc, 4)
tasksch.HandleTask(taskSeq, nil, true).Run()
}
func IsJXCS() bool {
return globals.IsMainProductEnv()
}
func AddStatisticSheet(sheetName string, data []DiffData) (sheet *excel.Obj2ExcelSheetConfig) {
statisticData := make([]StatisticData, 9)
var count [9]int
var percent [9]float32
totalCount := len(data)
for _, rowData := range data {
if rowData.JxSkuName != "" && rowData.VendorSkuName == "" {
if rowData.ToBeCreate == "是" {
if rowData.JxStatus == "下架" {
count[0]++
} else if rowData.JxStatus == "上架" {
count[1]++
}
} else if rowData.ToBeCreate == "否" {
if rowData.JxStatus == "下架" {
count[2]++
} else if rowData.JxStatus == "上架" {
count[3]++
}
}
} else if rowData.JxSkuName == "" && rowData.VendorSkuName != "" {
if rowData.ToBeCreate == "" && rowData.JxStatus == "" {
count[4]++
}
} else if rowData.JxSkuName != "" && rowData.VendorSkuName != "" {
if rowData.ToBeCreate == "是" {
if rowData.JxStatus == "下架" {
count[5]++
} else if rowData.JxStatus == "上架" {
count[6]++
}
} else if rowData.ToBeCreate == "否" {
if rowData.JxStatus == "下架" {
count[7]++
} else if rowData.JxStatus == "上架" {
count[8]++
}
}
}
}
for index, value := range count {
percent[index] = float32(value*100) / float32(totalCount)
countStr := utils.Int2Str(value)
percentStr := fmt.Sprintf("%.2f%%", percent[index])
subStatisticData := statisticDataList[index]
statisticData[index] = StatisticData{subStatisticData[0], subStatisticData[1], subStatisticData[2], countStr, percentStr}
}
sheetName = sheetName + "统计"
sheet = &excel.Obj2ExcelSheetConfig{
Title: sheetName,
Data: statisticData,
CaptionList: statisticTitleList,
}
return sheet
}
func WriteToExcel(task *tasksch.SeqTask, data map[int][]DiffData, depotData map[int][]DepotDiffData) {
var sheetList []*excel.Obj2ExcelSheetConfig
for key, value := range data {
sheetName := vendorNameList[key]
if partner.IsMultiStore(key) {
excelConfDepot := &excel.Obj2ExcelSheetConfig{
Title: sheetName + "商品库与京西商品库对比",
Data: depotData[key],
CaptionList: deoptTitleList,
}
sheetList = append(sheetList, excelConfDepot)
}
excelConf := &excel.Obj2ExcelSheetConfig{
Title: sheetName,
Data: value,
CaptionList: titleList,
}
sheetList = append(sheetList, excelConf)
if needStatistic {
statisticSheet := AddStatisticSheet(sheetName, value)
sheetList = append(sheetList, statisticSheet)
}
baseapi.SugarLogger.Debugf("WriteToExcel:append:%s count:%d", sheetName, len(value))
}
if len(sheetList) > 0 {
excelBin := excel.Obj2Excel(sheetList)
sheetList = nil
timeStr := utils.Int64ToStr(time.Now().Unix())
diffFullFileName := diffFileName[IsJXCS()] + timeStr + fileExt
if canWriteTolocal {
jxutils.WriteFile(diffFullFileName, excelBin)
}
baseapi.SugarLogger.Debugf("WriteToExcel:save %s success", diffFullFileName)
//上传
downloadURL, err := jxutils.UploadExportContent(excelBin, diffFullFileName)
if err != nil {
baseapi.SugarLogger.Errorf("WriteToExcel:upload %s failed error:%v", diffFullFileName, err)
} else {
noticeMsg := fmt.Sprintf("[详情点我]%s/billshow/?normal=true&path=%s \n", globals.BackstageHost, downloadURL)
task.SetNoticeMsg(noticeMsg)
baseapi.SugarLogger.Debugf("WriteToExcel:upload %s success, downloadURL:%s", diffFullFileName, downloadURL)
}
} else {
baseapi.SugarLogger.Debug("WriteToExcel:No diff data!!!")
}
}
func SetJxPrice(jxSkuInfoDataMulti *dao.StoreSkuNamesInfo, storeId int) (err error) {
db := dao.GetDB()
storeDetail, err := dao.GetStoreDetail(dao.GetDB(), storeId, model.VendorIDJX)
if err != nil {
dao.Rollback(db)
return err
}
/*重新计算京西价格*/
for _, values := range jxSkuInfoDataMulti.SkuNames {
for _, value := range values.Skus {
value.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), value.JxPrice)
}
}
/*重新计算京西价格*/
return nil
}