导入Excel更新京西价,推荐商品
This commit is contained in:
@@ -3,7 +3,9 @@ package cms
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"mime/multipart"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
@@ -23,6 +25,7 @@ import (
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
"github.com/360EntSecGroup-Skylar/excelize"
|
||||
"github.com/astaxie/beego/orm"
|
||||
)
|
||||
|
||||
@@ -34,69 +37,16 @@ const (
|
||||
CopyStoreSkuModeUpdatePrice = "updatePrice" // 增量复制价格
|
||||
)
|
||||
|
||||
type StoreSkuExt struct {
|
||||
NameID int `orm:"column(name_id)" json:"nameID"`
|
||||
SkuID int `orm:"column(sku_id)" json:"id"`
|
||||
Comment string `orm:"size(255)" json:"comment"`
|
||||
SkuCategoryID int `orm:"column(sku_category_id)" json:"categoryID"`
|
||||
SkuSpecQuality float32 `json:"specQuality"`
|
||||
SkuSpecUnit string `orm:"size(8)" json:"specUnit"` // 质量或容量
|
||||
Weight int `json:"weight"` // 重量/质量,单位为克,当相应的SkuName的SpecUnit为g或kg时,必须等于SpecQuality
|
||||
JdID string `orm:"column(sku_jd_id);null;index" json:"jdID"`
|
||||
SkuStatus int `json:"status"`
|
||||
|
||||
BindCreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"`
|
||||
BindUpdatedAt time.Time `orm:"auto_now;type(datetime)" json:"updatedAt"`
|
||||
BindLastOperator string `orm:"size(32)" json:"lastOperator"` // 最后操作员
|
||||
BindDeletedAt time.Time `orm:"type(datetime)" json:"deletedAt"`
|
||||
SubStoreID int `orm:"column(sub_store_id)" json:"subStoreID"`
|
||||
BindPrice int `json:"price"` // 单位为分,不用int64的原因是这里不需要累加
|
||||
UnitPrice int `json:"unitPrice"` // 这个是一斤的门店商品价,放在这里的原因是避免额外增加一张store sku_name表,逻辑上要保证同一SKU NAME中的所有SKU这个字段的数据一致
|
||||
StoreSkuStatus int `json:"storeSkuStatus"`
|
||||
|
||||
EbaiID string `orm:"column(ebai_id);index" json:"ebaiID"`
|
||||
MtwmID string `orm:"column(mtwm_id)" json:"mtwmID"` // 这个也不是必须的,只是为了DAO取数据语句一致
|
||||
// WscID string `orm:"column(wsc_id);index" json:"wscID"` // 表示微盟skuId
|
||||
// WscID2 string `orm:"column(wsc_id2);index" json:"wscID2"` // 表示微盟goodsId
|
||||
|
||||
JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"`
|
||||
EbaiSyncStatus int8 `orm:"default(2)" json:"ebaiSyncStatus"`
|
||||
MtwmSyncStatus int8 `orm:"default(2)" json:"mtwmSyncStatus"`
|
||||
// WscSyncStatus int8 `orm:"default(2)" json:"wscSyncStatus"`
|
||||
|
||||
JdPrice int `json:"jdPrice"`
|
||||
EbaiPrice int `json:"ebaiPrice"`
|
||||
MtwmPrice int `json:"mtwmPrice"`
|
||||
JxPrice int `json:"jxPrice"`
|
||||
|
||||
AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"`
|
||||
|
||||
ActPrice int `json:"actPrice"`
|
||||
ActID int `orm:"column(act_id)" json:"actID"`
|
||||
ActType int `orm:"column(act_type)" json:"actType"`
|
||||
|
||||
EarningPrice int `json:"earningPrice"`
|
||||
EarningActID int `orm:"column(earning_act_id)" json:"earningActID"`
|
||||
|
||||
RealEarningPrice int `json:"realEarningPrice"`
|
||||
|
||||
StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围
|
||||
StatusSaleEnd int16 `json:"statusSaleEnd"`
|
||||
|
||||
Count int `json:"count"`
|
||||
Times int `json:"times"`
|
||||
}
|
||||
|
||||
// GetStoreSkus用
|
||||
type StoreSkuNameExt struct {
|
||||
StoreID int `orm:"column(store_id)" json:"storeID"`
|
||||
StoreName string `json:"storeName"`
|
||||
|
||||
model.SkuName
|
||||
PayPercentage int `json:"-"`
|
||||
UnitPrice int `json:"unitPrice"`
|
||||
Skus []*StoreSkuExt `orm:"-" json:"skus,omitempty"`
|
||||
SkusStr string `json:"-"`
|
||||
PayPercentage int `json:"-"`
|
||||
UnitPrice int `json:"unitPrice"`
|
||||
Skus []*dao.StoreSkuExt `orm:"-" json:"skus,omitempty"`
|
||||
SkusStr string `json:"-"`
|
||||
|
||||
PendingOpType int8 `json:"pendingOpType"` // 取值同 StoreOpRequest.Type
|
||||
PendingUnitPrice int `json:"pendingUnitPrice"` // 这个是待审核的价格申请
|
||||
@@ -171,7 +121,36 @@ type tGetStoresSkusInfo struct {
|
||||
|
||||
model.SkuName
|
||||
PayPercentage int `json:"-"`
|
||||
StoreSkuExt
|
||||
dao.StoreSkuExt
|
||||
}
|
||||
|
||||
type SheetParam struct {
|
||||
OutSkuIDCol int
|
||||
SkuNameIDCol int
|
||||
SkuPriceCol int
|
||||
SkuNameCol int
|
||||
SkuUnitCol int
|
||||
SkuRow int
|
||||
}
|
||||
|
||||
type DataSuccess struct {
|
||||
NameID string `json:"商品编码"`
|
||||
Name string `json:"商品名称"`
|
||||
OrgPrice float64 `json:"原价"`
|
||||
NowPrice float64 `json:"现价"`
|
||||
MixPrice float64 `json:"涨跌"`
|
||||
}
|
||||
|
||||
type DataFailed struct {
|
||||
NameID string `json:"商品ID"`
|
||||
Name string `json:"商品名称"`
|
||||
Comment string `json:"备注"`
|
||||
}
|
||||
|
||||
type DataLock struct {
|
||||
dataSuccessList []DataSuccess
|
||||
dataFailedList []DataFailed
|
||||
locker sync.RWMutex
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -187,6 +166,7 @@ var (
|
||||
"18180948107": 1, // 徐
|
||||
// "13684045763": 1, // 周
|
||||
}
|
||||
dataLock DataLock
|
||||
)
|
||||
|
||||
func GetStoreSkus(ctx *jxcontext.Context, storeID int, skuIDs []int, isFocus bool, keyword string, isBySku, isAct bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *StoreSkuNamesInfo, err error) {
|
||||
@@ -627,7 +607,7 @@ func updateSaleInfo4StoreSkuName(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
|
||||
}
|
||||
var newSkuNames []*StoreSkuNameExt
|
||||
for _, skuName := range skuNamesInfo.SkuNames {
|
||||
var newSkus []*StoreSkuExt
|
||||
var newSkus []*dao.StoreSkuExt
|
||||
for _, sku := range skuName.Skus {
|
||||
saleInfo := saleInfoMap[jxutils.Combine2Int(skuName.StoreID, sku.SkuID)]
|
||||
if saleInfo == nil && fromCount == 0 {
|
||||
@@ -2190,3 +2170,77 @@ func RefershStoreSkusMidPrice(ctx *jxcontext.Context, storeIDs []int) (err error
|
||||
_, err = dao.RefershStoreSkusMidPrice(db, storeIDs)
|
||||
return err
|
||||
}
|
||||
|
||||
func RefreshJxPriceByExcel(ctx *jxcontext.Context, storeIDs []int, files []*multipart.FileHeader, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
if len(files) == 0 {
|
||||
return "", errors.New("没有文件上传!")
|
||||
}
|
||||
if len(storeIDs) == 0 {
|
||||
return "", errors.New("请选择至少一个门店!")
|
||||
}
|
||||
fileHeader := files[0]
|
||||
file, err := fileHeader.Open()
|
||||
hint, err = RefreshJxPriceByExcelBin(ctx, storeIDs, file, true, true)
|
||||
file.Close()
|
||||
return hint, err
|
||||
}
|
||||
|
||||
func RefreshJxPriceByExcelBin(ctx *jxcontext.Context, storeIDs []int, reader io.Reader, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
var storeSkuNamePriceList []*model.StoreSkuNamePrice
|
||||
dataLock.dataFailedList = dataLock.dataFailedList[0:0]
|
||||
dataLock.dataSuccessList = dataLock.dataSuccessList[0:0]
|
||||
sheetParam := &SheetParam{
|
||||
SkuNameIDCol: 5,
|
||||
SkuPriceCol: 3,
|
||||
SkuNameCol: 1,
|
||||
SkuRow: 1,
|
||||
SkuUnitCol: 2,
|
||||
OutSkuIDCol: 0,
|
||||
}
|
||||
xlsx, err := excelize.OpenReader(reader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
rows, _ := xlsx.GetRows(xlsx.GetSheetName(1))
|
||||
for rowNum, row := range rows {
|
||||
if rowNum < sheetParam.SkuRow {
|
||||
continue
|
||||
}
|
||||
storeSkuNamePrice := &model.StoreSkuNamePrice{}
|
||||
GetCellIntoStruct(rowNum, row, sheetParam, storeSkuNamePrice)
|
||||
storeSkuNamePriceList = append(storeSkuNamePriceList, storeSkuNamePrice)
|
||||
}
|
||||
return hint, err
|
||||
}
|
||||
|
||||
func GetCellIntoStruct(rowNum int, row []string, sheetParam *SheetParam, storeSkuNamePrice *model.StoreSkuNamePrice) {
|
||||
for k, cell := range row {
|
||||
if k == sheetParam.OutSkuIDCol {
|
||||
storeSkuNamePrice.OutSkuID = cell
|
||||
}
|
||||
if k == sheetParam.SkuNameCol {
|
||||
storeSkuNamePrice.Name = cell
|
||||
}
|
||||
if k == sheetParam.SkuNameIDCol {
|
||||
storeSkuNamePrice.NameIDGroup = cell
|
||||
}
|
||||
if k == sheetParam.SkuPriceCol {
|
||||
storeSkuNamePrice.Price = int(utils.Float64TwoInt64(utils.Str2Float64(cell) * 100))
|
||||
}
|
||||
if k == sheetParam.SkuUnitCol {
|
||||
storeSkuNamePrice.Unit = cell
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DataLock) AppendDataSuccess(dataSuccess DataSuccess) {
|
||||
d.locker.Lock()
|
||||
defer d.locker.Unlock()
|
||||
d.dataSuccessList = append(d.dataSuccessList, dataSuccess)
|
||||
}
|
||||
|
||||
func (d *DataLock) AppendDataFailed(dataFailed DataFailed) {
|
||||
d.locker.Lock()
|
||||
defer d.locker.Unlock()
|
||||
d.dataFailedList = append(d.dataFailedList, dataFailed)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user