Files
jx-callback/business/jxstore/yonghui/yonghui.go
2019-11-18 09:05:03 +08:00

397 lines
12 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 yonghui
import (
"errors"
"fmt"
"io"
"math"
"mime/multipart"
"unicode"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/utils"
"github.com/360EntSecGroup-Skylar/excelize"
"git.rosy.net.cn/baseapi/platformapi/jdapi"
"git.rosy.net.cn/baseapi/platformapi/weimobapi"
"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/dao"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
)
type SheetParam struct {
SkuIDCol int
SkuPriceCol int
OrgSkuIdCol int
OrgSkuPriceCol int
SkuRow int
}
var (
sheetMap = map[string]*SheetParam{
"蔬菜": &SheetParam{
SkuIDCol: 0,
SkuPriceCol: 14,
OrgSkuIdCol: 5,
OrgSkuPriceCol: 8,
SkuRow: 2,
}, "水果": &SheetParam{
SkuIDCol: 0,
SkuPriceCol: 14,
OrgSkuIdCol: 5,
OrgSkuPriceCol: 8,
SkuRow: 2,
}, "肉禽": &SheetParam{
SkuIDCol: 0,
SkuPriceCol: 12,
OrgSkuIdCol: 4,
OrgSkuPriceCol: 7,
SkuRow: 1,
}, "净配": &SheetParam{
SkuIDCol: 0,
SkuPriceCol: 12,
OrgSkuIdCol: 4,
OrgSkuPriceCol: 7,
SkuRow: 1,
}, "水产": &SheetParam{
SkuIDCol: 1,
SkuPriceCol: 15,
OrgSkuIdCol: 6,
OrgSkuPriceCol: 9,
SkuRow: 1,
}, "干货": &SheetParam{
SkuIDCol: 0,
SkuPriceCol: 13,
OrgSkuIdCol: 4,
OrgSkuPriceCol: 7,
SkuRow: 2,
}, "MINI肉禽价格": &SheetParam{
SkuIDCol: 1,
SkuPriceCol: 5,
OrgSkuIdCol: -1,
OrgSkuPriceCol: -1,
SkuRow: 1,
},
}
)
const (
parallelCount = 5
UpdateGoodsShelfStatusCount = 50 //微盟下架商品api限制一次50个
)
func LoadExcelByYongHui(ctx *jxcontext.Context, files []*multipart.FileHeader, isAsync bool) (hint string, err error) {
if len(files) == 0 {
return "", errors.New("没有文件上传!")
}
fileHeader := files[0]
file, err := fileHeader.Open()
hint, err = LoadExcelBinByYongHui(ctx, file, isAsync)
file.Close()
return hint, err
}
func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync bool) (hint string, err error) {
var (
skuMap = make(map[string]float64)
errMsg string
costPrice float64 //成本价
goodsList []*weimobapi.GoodsInfo
goodsIDListForPutAway []interface{}
)
db := dao.GetDB()
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
switch step {
case 0:
//读取excel文件
xlsx, err := excelize.OpenReader(reader)
if err != nil {
return "", err
}
for k := range sheetMap {
sheetParam := sheetMap[k]
rows, _ := xlsx.GetRows(k)
for rowNum, row := range rows {
if rowNum < sheetParam.SkuRow {
continue
}
GetCellIntoMap(sheetParam.SkuIDCol, sheetParam.SkuPriceCol, sheetParam.OrgSkuIdCol, sheetParam.OrgSkuPriceCol, skuMap, row, k, rowNum)
if len(skuMap) < 1 {
errMsg += fmt.Sprintf("读取Excel数据失败Excel格式排版可能发生了变化sheetName: [%v]", k)
}
}
if errMsg != "" {
return "", errors.New(errMsg)
}
}
case 1:
//获取微盟所有商品
goodsList, err = GetWeiMobGoodsList()
if err != nil {
baseapi.SugarLogger.Errorf("GetWeiMobGoodsList error:%v", err)
}
taskFunc2 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
v := batchItemList[0].(*weimobapi.GoodsInfo)
goodsDetail, err := api.WeimobAPI.QueryGoodsDetail(v.GoodsID)
if err != nil {
baseapi.SugarLogger.Errorf("QueryGoodsDetail error:%v", err)
}
v.GoodsDetailInfo = goodsDetail
return retVal, err
}
taskParallel2 := tasksch.NewParallelTask("获取微盟商品", tasksch.NewParallelConfig().SetParallelCount(parallelCount), ctx, taskFunc2, goodsList)
tasksch.HandleTask(taskParallel2, task, true).Run()
_, err = taskParallel2.GetResult(0)
//找出excel上有微盟没有的,有就列出报错,不进行更新
goodsInfoAndDetailMap := GetGoodsInfoAndDetailMap(goodsList)
for k, _ := range skuMap {
//表示excel上有微盟上没有
if goodsInfoAndDetailMap[k] == nil {
errMsg += fmt.Sprintf("在微盟上未找到该商品excel商品ID : [%v]\n", k)
}
}
// if errMsg != "" {
// return "", errors.New(errMsg)
// }
case 2:
//找出微盟上有excel上没有的有就更新没有就下架
taskFunc3 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
goods := batchItemList[0].(*weimobapi.GoodsInfo)
goodsDetail := goods.GoodsDetailInfo
spuCode := goodsDetail.OuterGoodsCode
if spuCode != "" {
//如果微盟商品里找得到excel中的商品
if skuMap[spuCode] != 0 {
//获取京西库商品
skuList, _ := dao.GetSkus(db, nil, []int{int(utils.Str2Int64(goodsDetail.SkuMap.SingleSku.OuterSkuCode))}, nil, nil)
if len(skuList) == 0 {
errMsg += fmt.Sprintf("在京西库中未找到该商品name_id : [%v] \n", goodsDetail.SkuMap.SingleSku.OuterSkuCode)
} else {
if skuList[0].Unit == "份" {
if goodsDetail.SkuMap.SingleSku.B2CSku.Weight == 0 {
costPrice = skuMap[spuCode]
} else {
costPrice = Float64Round(0.5 / goodsDetail.SkuMap.SingleSku.B2CSku.Weight * skuMap[spuCode])
}
} else {
costPrice = skuMap[spuCode]
}
// if errMsg == "" {
_, _, err = updateWeiMobGoods(costPrice, skuMap[spuCode], goodsDetail)
// }
}
} else {
//下架微盟商品
retVal = []int64{goodsDetail.GoodsID}
}
}
return retVal, err
}
taskParallel3 := tasksch.NewParallelTask("根据获取的微盟所有商品并更新", tasksch.NewParallelConfig().SetParallelCount(parallelCount), ctx, taskFunc3, goodsList)
tasksch.HandleTask(taskParallel3, task, true).Run()
goodsIDListForPutAwayInterface, err2 := taskParallel3.GetResult(0)
if err = err2; err != nil {
return "", err
}
// 批量下架微盟商品
goodsIDListForPutAway = goodsIDListForPutAwayInterface
case 3:
// if errMsg == "" {
taskFunc4 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
int64Slice := []int64{}
for _, v := range batchItemList {
int64Slice = append(int64Slice, v.(int64))
}
PutAwayWeiMobSku(int64Slice)
return retVal, err
}
taskParallel4 := tasksch.NewParallelTask("下架微盟商品", tasksch.NewParallelConfig().SetParallelCount(parallelCount).SetBatchSize(UpdateGoodsShelfStatusCount), ctx, taskFunc4, goodsIDListForPutAway)
tasksch.HandleTask(taskParallel4, task, true).Run()
_, err = taskParallel4.GetResult(0)
// }
}
return result, err
}
taskSeq := tasksch.NewSeqTask("读取永辉Excel文件修改微盟商品价格可售状态-序列任务", ctx, taskSeqFunc, 4)
tasksch.HandleTask(taskSeq, nil, true).Run()
if !isAsync {
_, err = taskSeq.GetResult(0)
hint = "1"
} else {
hint = taskSeq.GetID()
}
if errMsg != "" {
baseapi.SugarLogger.Debugf(errMsg)
return "", errors.New(errMsg)
}
return hint, err
}
func PutAwayWeiMobSku(goodsIDListForPutAway []int64) (err error) {
if globals.EnableStoreWrite {
// err = api.WeimobAPI.UpdateGoodsShelfStatus(goodsIDListForPutAway, false)
}
if err != nil {
baseapi.SugarLogger.Errorf("UpdateGoodsShelfStatus error:%v", err)
}
return err
}
func GetGoodsInfoAndDetailMap(goodsList []*weimobapi.GoodsInfo) (goodsMap map[string]*weimobapi.GoodsInfo) {
goodsMap = make(map[string]*weimobapi.GoodsInfo)
for _, v := range goodsList {
goodsMap[v.GoodsDetailInfo.OuterGoodsCode] = v
}
return goodsMap
}
func updateWeiMobGoods(costPrice, salePrice float64, goodsDetail *weimobapi.GoodsDetailInfo) (goodsID int64, skuMap map[string]int64, err error) {
var (
categoryList []*weimobapi.CategoryList
skuListInfo = goodsDetail.SkuList[0]
skuListParam []*weimobapi.SkuList
categoryID int
deliveryTypeListSlice []int64
)
//查询配送方式
deliveryTypeList, err := api.WeimobAPI.FindDeliveryTypeList(goodsDetail.GoodsID)
if err != nil {
baseapi.SugarLogger.Errorf("FindDeliveryTypeList error:%v", err)
}
for _, deliveryType := range deliveryTypeList {
if deliveryType.Selected {
deliveryTypeListSlice = append(deliveryTypeListSlice, deliveryType.DeliveryID)
}
}
//查询运费模板
freightTemplateListInfo, err := api.WeimobAPI.FindFreightTemplateList(goodsDetail.GoodsID)
if err != nil {
baseapi.SugarLogger.Errorf("FindFreightTemplateList error:%v", err)
}
//寻找分类子ID
categoryList = goodsDetail.CategoryList
if len(categoryList) > 0 {
categoryID = categoryList[len(categoryList)-1].CategoryID
} else {
return 0, nil, errors.New(fmt.Sprintf("未查询到此商品的分类信息goodsID : [%v] ,", goodsDetail.GoodsID))
}
b2CSku := &weimobapi.B2CSku{
Weight: skuListInfo.B2CSku.Weight,
Volume: skuListInfo.B2CSku.Volume,
}
b2CGoods := &weimobapi.B2CGoods{
B2CGoodsType: goodsDetail.B2CGoods.B2CGoodsType,
DeliveryTypeIDList: deliveryTypeListSlice,
FreightTemplateID: freightTemplateListInfo.DefaultFreightTemplate.TemplateID,
}
skuList := &weimobapi.SkuList{
SalePrice: salePrice,
CostPrice: costPrice,
SkuID: skuListInfo.SkuID,
EditStockNum: 9999 - skuListInfo.EditStockNum,
OuterSkuCode: skuListInfo.OuterSkuCode,
B2CSku: b2CSku,
}
skuListParam = append(skuListParam, skuList)
goods := &weimobapi.Goods{
B2CGoods: b2CGoods,
SkuList: skuListParam,
Title: goodsDetail.Title,
IsMultiSku: goodsDetail.IsMultiSku,
IsPutAway: weimobapi.GoodsTypeNormal,
GoodsImageURL: goodsDetail.GoodsImageURL,
GoodsID: goodsDetail.GoodsID,
CategoryID: categoryID,
OuterGoodsCode: goodsDetail.OuterGoodsCode,
PointDeductRatio: goodsDetail.PointDeductRatio,
}
updateGoodsParam := &weimobapi.UpdateGoodsParam{
Goods: goods,
}
if globals.EnableStoreWrite {
goodsID, skuMap, err = api.WeimobAPI.UpdateGoods3(updateGoodsParam)
}
return goodsID, skuMap, err
}
func GetWeiMobGoodsList() (goodsList []*weimobapi.GoodsInfo, err error) {
param := &weimobapi.QueryGoodsListParam{
PageNum: 1,
PageSize: jdapi.MaxSkuIDsCount4QueryListBySkuIds,
}
for {
goodsInfoList, _, err := api.WeimobAPI.QueryGoodsList(param)
if err != nil {
return nil, err
}
if len(goodsInfoList) > 0 {
goodsList = append(goodsList, goodsInfoList...)
}
if len(goodsInfoList) < param.PageSize {
break
}
param.PageNum++
}
return goodsList, err
}
func IsChineseChar(str string) bool {
for _, r := range str {
if unicode.Is(unicode.Scripts["Han"], r) {
return true
}
}
return false
}
func GetCellIntoMap(skuIDCol, skuPriceCol, orgSkuIDCol, orgSkuPriceCol int, skuMap map[string]float64, row []string, sheetName string, rowNum int) {
var (
skuID string
orgSkuID string
skuPrice float64
orgSkuPrice float64
)
for k, cell := range row {
if !IsChineseChar(cell) && cell != "" {
if k == skuIDCol && skuIDCol >= 0 {
skuID = cell
}
if k == skuPriceCol && skuPriceCol >= 0 {
skuPrice = Float64Round(utils.Str2Float64WithDefault(cell, 0))
}
if k == orgSkuIDCol && orgSkuIDCol >= 0 {
orgSkuID = "0" + cell
}
if k == orgSkuPriceCol && orgSkuPriceCol >= 0 {
orgSkuPrice = Float64Round(utils.Str2Float64WithDefault(cell, 0))
}
}
}
if skuMap[skuID] != 0 && skuMap[skuID] != skuPrice {
if skuPrice > skuMap[skuID] {
skuMap[skuID] = skuPrice
}
// fmt.Sprintf("读取excel表格出错有商品ID重复且价格不同,sheetName : [%v] ,行数 : [%v] , 商品编码 [%v] , 价格:[%v]\n", sheetName, rowNum, skuID, skuPrice)
} else {
skuMap[skuID] = skuPrice
}
if skuMap[orgSkuID] != 0 && skuMap[orgSkuID] != orgSkuPrice {
if orgSkuPrice > skuMap[orgSkuID] {
skuMap[orgSkuID] = orgSkuPrice
}
// fmt.Sprintf("读取excel表格出错有商品ID重复且价格不同,sheetName : [%v] ,行数 : [%v], 商品编码 [%v] , 价格:[%v]\n", sheetName, rowNum, orgSkuID, orgSkuPrice)
} else if orgSkuPriceCol >= 0 && orgSkuIDCol >= 0 {
skuMap[orgSkuID] = orgSkuPrice
}
delete(skuMap, "")
}
func Float64Round(f float64) (flt float64) {
return math.Round(f*100) / 100
}