package cms

import (
	"fmt"
	"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  = "" //update by hang 这个提示毫无意义 并未做任何同步操作获取错误码 纯粹因为有不同才会拼接
	DatAanalyse8  = "平台门店未关注或平台门店商品库存为0，应添加对应的平台门店商品"
	DatAanalyse9  = "平台门店价格与京西商品库价格不一致"
	DatAanalyse10 = "平台商品的VendorSkuID与京西的VendorSkuID不一致"
	DatAanalyse11 = "平台商品的类别与京西的类别不一致"
)

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"`
	TaoID              string `json:"淘鲜达ID"`
	DdID               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:"平台价格"`
	JxCategoryName     string `json:"京西商品类别"`
	VendorCategoryName 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 方法")
	var vendorMap map[string]string
	if vendorID == 0 {
		//TO DO 进行查询 select  count(*) from sku_vendor_category where vendor_id=0; 一共3047 数据一次connection查询出来 组成一个map {categoryID,name}
		vendorMap = getJDVendorCategoryMap()
	}
	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
		/*抖店编码*/
		ddid := jxSkuInfo.Skus[0].DdID
		/*淘鲜达编码*/
		taoid := jxSkuInfo.Skus[0].TaoID
		//jxSkuPrice := strconv.Itoa(jxSkuInfo.Skus[0].JxPrice)
		/*商品类名*/
		jxCategoryName := jxSkuInfo.Skus[0].CategoryName
		//fmt.Println(jxCategoryName)
		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
		} else if vendorID == model.VendorIDTaoVegetable {
			status = jxSkuInfo.Skus[0].TaoSyncStatus
		}
		syncStatus := utils.Int2Str(int(status))
		toBeCreate := GetBoolName(model.IsSyncStatusNeedCreate(status))
		toBeDel := GetBoolName(model.IsSyncStatusNeedDelete(status))

		if vendorSkuInfo != nil {
			if vendorID == 0 && len(vendorMap) != 0 { //进行转换
				catID := []string{}
				categoryName := vendorMap[vendorSkuInfo.VendorCatIDList[len(vendorSkuInfo.VendorCatIDList)-1]]
				catID = append(catID, categoryName)
				vendorSkuInfo.VendorCatIDList = catID
			}

			vendorSkuDetailName := vendorSkuInfo.SkuList[0].SkuName
			vendorCategoryName := ""
			if len(vendorSkuInfo.VendorCatIDList) != 0 {
				vendorCategoryName = vendorSkuInfo.VendorCatIDList[len(vendorSkuInfo.VendorCatIDList)-1]
			}
			fmt.Println(vendorCategoryName)
			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 && skuIDStr != ddid && skuIDStr != taoid
			} else {
				IdMark = false
			}
			isSaleStatusDiff := jxSkuSaleStatusName != vendorSkuSaleStatusName
			isNameDiff := jxSkuDetailName != vendorSkuDetailName
			/*比较价格*/
			isPriceDiff := vendorPrice != jxSkuPrice
			//utils.Writelog("isSaleStatusDiff:" + strconv.FormatBool(isSaleStatusDiff))
			//utils.Writelog("isNameDiff:" + strconv.FormatBool(isNameDiff))
			isCategoryDiff := vendorCategoryName != jxCategoryName
			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 vendorID != 3 { //饿百平台查询获取到的商品信息是没有类别的 因此单独需要判断
					if isCategoryDiff {
						reason += DatAanalyse11
					}
				}
				if IdMark {
					reason += DatAanalyse10
				}
				if status != model.SkuStatusDontSale {
					reason += DatAanalyse7
				}
				outPutData := DiffData{storeIDStr, vendorStoreID, storeName, skuIDStr, mtwmid, taoid, ddid, ebaiid, syncStatus, toBeCreate, toBeDel, jxSkuDetailName, vendorSkuDetailName, jxSkuSaleStatusName, vendorSkuSaleStatusName, jxSkuPrice, vendorPrice, jxCategoryName, vendorCategoryName, reason}
				diffData.AppendData(vendorID, outPutData)
			}
			if !isSaleStatusDiff && !isNameDiff {
				if status != model.SkuStatusDontSale {
					outPutData := DiffData{storeIDStr, vendorStoreID, storeName, skuIDStr, mtwmid, taoid, ddid, ebaiid, syncStatus, toBeCreate, toBeDel, jxSkuDetailName, vendorSkuDetailName, jxSkuSaleStatusName, vendorSkuSaleStatusName, jxSkuPrice, vendorPrice, jxCategoryName, vendorCategoryName, 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, taoid, ddid, ebaiid, syncStatus, toBeCreate, toBeDel, jxSkuDetailName, "", jxSkuSaleStatusName, "", jxSkuPrice, "", jxCategoryName, "", 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 {
					//update by hang 2022/4/12 映射bug
					vendorCategoryName := ""
					if len(vendorSkuInfo.VendorCatIDList) != 0 {
						vendorCategoryName = vendorSkuInfo.VendorCatIDList[len(vendorSkuInfo.VendorCatIDList)-1]
					}
					outPutData := DiffData{storeIDStr, vendorStoreID, storeName, skuIDStr, "", "", "", "", "", "", "", vendorSkuDetailName, "", vendorSkuSaleStatusName, "", vendorPrice, "", vendorCategoryName, 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)
		}
	}
}

type VendorCategory struct {
	VendorCategoryID string `orm:"size(48);column(vendor_category_id)" json:"vendorCategoryID"`
	Name             string `orm:"size(255);index" json:"name"`
}

// 获取京东类别映射
func getJDVendorCategoryEntity() (vendorCategoryList []*VendorCategory, err error) {
	db := dao.GetDB()
	sql := `
	select  vendor_category_id,name from sku_vendor_category where vendor_id=?
	`
	var sqlParams []interface{}
	sqlParams = append(sqlParams, 0)
	err = dao.GetRows(db, &vendorCategoryList, sql, sqlParams...)
	return vendorCategoryList, err
}

//获取京东所有类别映射
func getJDVendorCategoryMap() map[string]string {
	result := make(map[string]string)
	list, err := getJDVendorCategoryEntity()
	if err == nil {
		for _, v := range list {
			result[v.VendorCategoryID] = v.Name
		}
	}
	return result
}

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)
	///*获取美团门店信息*/
	//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 {
//			}
//		}
//		/*改配送范围*/
//		//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")
//}

// CheckSkuDiffBetweenJxAndVendor2 对比本地商品和平台商品差异(价格和规格),不同的重新同步
func CheckSkuDiffBetweenJxAndVendor2(ctx *jxcontext.Context, vendorIDList []int, storeIDList []int) error {
	//var (
	//	db      = dao.GetDB()
	//	errList = make([]error, 0, 0)
	//)
	//for _, v := range storeIDList {
	//	// 1.判断本地门店是否开启了同步,未开启的跳过
	//	storeMapList, err := dao.GetStoresMapList(db, vendorIDList, []int{v}, []int{model.StoreStatusOpened, model.StoreStatusHaveRest, model.StoreStatusClosed}, model.StoreStatusOpened, model.StoreIsSyncYes, "", "", "")
	//	if err != nil {
	//		errList = append(errList, fmt.Errorf("门店id[%d]查询异常:%v", v, err))
	//		continue
	//	}
	//	if len(storeMapList) == model.NO {
	//		errList = append(errList, fmt.Errorf("门店id[%d],未绑定平台账号或者同步未打开", v))
	//		continue
	//	}
	//	// 2.查询本地商品列表,存储sku_id,vendor_price,weight
	//	skuList, skuErr := dao.GetStoreSkuBindPriceAndWeight(db, v)
	//	if len(skuList) == model.NO || skuErr != nil {
	//		errList = append(errList, fmt.Errorf("门店id[%d],商品为空或错误:%v", v, skuErr))
	//		continue
	//	}
	//
	//	// 查询平台门店所有商品
	//	for _, storeMap := range storeMapList {
	//		singleStoreHandler := partner.GetPurchasePlatformFromVendorID(storeMap.VendorID).(partner.ISingleStoreStoreSkuHandler)
	//		// 淘宝需要storeSkuList有值
	//		vendorSkuInfoList, err := singleStoreHandler.GetStoreSkusFullInfo(ctx, nil, v, storeMap.VendorStoreID, nil)
	//
	//	}
	//	// 3.比对价格和规格重量,不同的以本地为基础开始重新同步
	//
	//}
	return nil
}

//入口函数，校验本地商品京西和其他平台的差异
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)
									jxSkuInfoDataMulti, _ = GetStoreSkus2(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)
									jxSkuInfoDataSingle, _ = GetStoreSkus2(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!!!")
	}
}
