package cms import ( "fmt" "strings" "sync" "time" "git.rosy.net.cn/baseapi/platformapi/dingdingapi" "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" beego "github.com/astaxie/beego/adapter" "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[skuID1:SkuNameInfo1,skuID2:SkuNameInfo2]...] } } } } } 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 //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) //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.Debugf("CompareJxAndVendor vendorSkuInfo.SkuList:%d is nil", skuID) } } else { globals.SugarLogger.Debugf("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.Debugf("CompareJxAndMultiVenderDepot vendorSkuInfo.SkuList:%d is nil", skuID) } } else { globals.SugarLogger.Debugf("CompareJxAndMultiVenderDepot skuID:%d is nil", skuID) } } } } } func StoreOpenAll(ctx *jxcontext.Context) { AutoFocusStoreSkusForTopSkus(ctx, true, true) //globals.SugarLogger.Debug("StoreOpenAll skuID is start") ///*获取美团门店信息*/ //StoreInfoList, _ := api.MtpsAPI.GetStoreStatusAll() //StoreInfoList2 := make(map[string]string) //for _, store := range StoreInfoList { // for _, data := range store.DataList { // StoreInfoList2[data.OuterPoiID] = data.PoiName // } //} //db := dao.GetDB() ///*比较营业状态*/ ///*把获取的京西状态和名称存一下*/ //StoreCourierList, _ := dao.GetStoreCourierList(db, []int{}, model.StoreStatusAll, model.StoreStatusAll) ///*循环美团*/ //for _, StoreInfoList1 := range StoreInfoList { // for _, StoreInfoList11 := range StoreInfoList1.DataList { // /*循环京西*/ // for _, StoreCourierList1 := range StoreCourierList { // /*只比较美团*/ // if StoreCourierList1.VendorID != model.VendorIDMTPS { // continue // } // /*如果门店ID相同的时候进入判断,一个门店只用判断一次就行*/ // if StoreCourierList1.VendorStoreID == StoreInfoList11.OuterPoiID { // if StoreCourierList1.Status != StoreInfoList11.OpenType { // sl := make(map[string]interface{}) // sl["vendorStoreID"] = StoreInfoList11.OuterPoiID // sl["status"] = StoreInfoList11.OpenType // sl["vendorStatus"] = StoreInfoList11.OpenType // globals.SugarLogger.Debugf("被修改配送状态的VendorStoreID是:%s,名称是:%s,美团状态是:%s,本地状态是:%s", // StoreInfoList11.OuterPoiID, StoreInfoList11.PoiName, strconv.Itoa(StoreInfoList11.OpenType), strconv.Itoa(StoreCourierList1.Status)) // UpdateStoreCourierMap(ctx, nil, StoreCourierList1.StoreID, StoreCourierList1.VendorID, sl, ctx.GetUserName()) // break // } // } // } // } //} ///* 美团配送的门店是否存在,调用美团配送的api(有可能接了),查询京西门店对应的美团配送门店是否存在,若不存在则要在京西这边解绑美团配送门店 // 怎么解绑可以在网页上门店管理那点一下看看调的什么接口,传的什么参数*/ ///*获取所有门店信息*/ ////test: //for _, StoreCourierList1 := range StoreCourierList { // diff := false // StoreLists, _ := dao.GetStoreList(db, []int{StoreCourierList1.StoreID}, nil, nil, nil, "") // if StoreLists == nil { // globals.SugarLogger.Debugf("StoreID为:%s,在store表未找到", StoreCourierList1.StoreID) // continue // } // if StoreCourierList1.VendorID != model.VendorIDMTPS || StoreCourierList1.VendorStoreID == "" { // continue // } // if StoreCourierList1.Status == model.StoreStatusDisabled || StoreCourierList1.Status == model.StoreStatusClosed { // continue // } // /*京西不为空,容错*/ // //if { // /*调用API获取美团的商店信息*/ // MTPSInfo := new(mtpsapi.ShopInfo) // MTPSInfo, _ = api.MtpsAPI.ShopQuery(StoreCourierList1.VendorStoreID) // if MTPSInfo == nil { // globals.SugarLogger.Debug("美团未找到该门店," + StoreLists[0].Name + strconv.Itoa(StoreCourierList1.StoreID) + " 被解绑,关联的ID为:" + StoreCourierList1.VendorStoreID) // diff = true // } // if MTPSInfo != nil && MTPSInfo.ShopName == "" { // MTPSInfo.ShopName = StoreInfoList2[MTPSInfo.ShopID] // } // if MTPSInfo != nil && MTPSInfo.ShopLng != StoreCourierList1.Lng && MTPSInfo.ShopLat == StoreCourierList1.Lat { // /*平台上但是坐标不同,解绑*/ // globals.SugarLogger.Debug("商店与美团配送上的坐标不同," + StoreLists[0].Name + strconv.Itoa(StoreCourierList1.StoreID) + " 被解绑,关联的ID为:" + StoreCourierList1.VendorStoreID) // if _, err := DeleteStoreCourierMap(ctx, db, StoreCourierList1.StoreID, StoreCourierList1.VendorID, ctx.GetUserName()); err != nil { // globals.SugarLogger.Debug(err.Error()) // return // } // diff = true // } // if diff { // if _, err := DeleteStoreCourierMap(ctx, db, StoreCourierList1.StoreID, StoreCourierList1.VendorID, ctx.GetUserName()); err != nil { // globals.SugarLogger.Debug(err.Error()) // return // } // //break test // } //} //globals.SugarLogger.Debug("StoreOpenAll skuID is Complete") } //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 StoreList.StoreLevel == "E" { // continue // } // 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") // } // globals.SugarLogger.Debug("StoreOpenAll skuID is Complete") //} 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.过滤所有门店信息,只留下传进来的vendorMap,storeIDMap中对应的平台和门台信息 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() for i := range filterStoreList { jxStoreInfoListValue := filterStoreList[i] 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, vendorID) 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) /*重新计算价格*/ SetJxPrice(jxSkuInfoDataSingle, storeID, vendorID) 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, ctx.GetUserID(), "异步任务完成", "京西平台对比数据上传成功: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.过滤所有门店信息,只留下传进来的vendorMap,storeIDMap中对应的平台和门台信息 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, vendorid int) (err error) { db := dao.GetDB() storeDetail, err := dao.GetStoreDetail(dao.GetDB(), storeId, vendorid, "") 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.BindPrice) } } /*重新计算京西价格*/ return nil }