Merge branch 'mark' of e.coding.net:rosydev/jx-callback into mark
This commit is contained in:
@@ -617,8 +617,8 @@ func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interfa
|
||||
if err = dao.GetEntity(db, store); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
valid := dao.StrictMakeMapByStructObject(payload, store, userName)
|
||||
var outStore *model.Store
|
||||
valid := dao.StrictMakeMapByStructObject2(payload, store, &outStore, userName)
|
||||
if err = checkStoreDeliveryRange(utils.Interface2String(valid["deliveryRange"])); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -733,6 +733,31 @@ func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interfa
|
||||
if valid["deliveryRange"] != nil {
|
||||
valid["deliveryRange"] = strings.Trim(valid["deliveryRange"].(string), ";")
|
||||
}
|
||||
|
||||
//时间校验
|
||||
if outStore.OpenTime1 != 0 && outStore.CloseTime1 != 0 {
|
||||
if err := ValidateStructPartial(outStore, "OpenTime1", "CloseTime1"); err != nil {
|
||||
return 0, errors.New(fmt.Sprintf("门店营业时间1设置不合法!时间范围1 :[%v] 至 [%v]", outStore.OpenTime1, outStore.CloseTime1))
|
||||
}
|
||||
}
|
||||
if (outStore.OpenTime1 == 0 && outStore.CloseTime1 != 0) || (outStore.OpenTime1 != 0 && outStore.CloseTime1 == 0) {
|
||||
return 0, errors.New(fmt.Sprintf("门店营业时间1设置不合法!时间范围1 :[%v] 至 [%v]", outStore.OpenTime1, outStore.CloseTime1))
|
||||
}
|
||||
if outStore.OpenTime2 != 0 && outStore.CloseTime2 != 0 {
|
||||
if err := ValidateStructPartial(outStore, "OpenTime2", "CloseTime2"); err != nil {
|
||||
return 0, errors.New(fmt.Sprintf("门店营业时间2设置不合法!时间范围2 :[%v] 至 [%v]", outStore.OpenTime2, outStore.CloseTime2))
|
||||
}
|
||||
}
|
||||
if (outStore.OpenTime2 == 0 && outStore.CloseTime2 != 0) || (outStore.OpenTime2 != 0 && outStore.CloseTime2 == 0) {
|
||||
return 0, errors.New(fmt.Sprintf("门店营业时间2设置不合法!时间范围2 :[%v] 至 [%v]", outStore.OpenTime1, outStore.CloseTime1))
|
||||
}
|
||||
if outStore.OpenTime2 > outStore.OpenTime1 {
|
||||
return 0, errors.New(fmt.Sprintf("门店营业时间设置不合法!第二段营业时间应该在第一段营业时间之后!"))
|
||||
}
|
||||
if beginAt, endAt := GetTimeMixByInt(outStore.OpenTime1, outStore.CloseTime1, outStore.OpenTime2, outStore.CloseTime2); beginAt != 0 && endAt != 0 {
|
||||
return 0, errors.New(fmt.Sprintf("两段门店营业时间不可交叉!时间范围1 :[%v] 至 [%v], 时间范围2 :[%v] 至 [%v]", outStore.OpenTime1, outStore.CloseTime1, outStore.OpenTime2, outStore.CloseTime2))
|
||||
}
|
||||
|
||||
// districtCode := 0
|
||||
// if valid["districtCode"] != nil {
|
||||
// districtCode = int(utils.MustInterface2Int64(valid["districtCode"]))
|
||||
@@ -779,7 +804,7 @@ func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interfa
|
||||
notifyStoreOperatorChanged(store, valid["operatorPhone"])
|
||||
if err == nil {
|
||||
if valid["openTime1"] != 0 || valid["closeTime1"] != 0 || valid["openTime2"] != 0 || valid["closeTime2"] != 0 {
|
||||
err = CurVendorSync.ChangeStoreSkuSaleStatus(ctx, storeID, true, false)
|
||||
err = CurVendorSync.ChangeStoreSkuSaleStatus(ctx, storeID, true, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,8 +122,8 @@ type StoreSkuBindInfo struct {
|
||||
IsFocus int `json:"isFocus"` // -1:不关注,0:忽略,1:关注
|
||||
IsSale int `json:"isSale"` // -1:不可售,0:忽略,1:可售
|
||||
SubStoreID int `json:"subStoreID,omitempty"`
|
||||
StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围
|
||||
StatusSaleEnd int16 `json:"statusSaleEnd"`
|
||||
StatusSaleBegin int16 `json:"statusSaleBegin" validate:"max=2359,min=1,ltfield=StatusSaleEnd"` //商品可售时间范围
|
||||
StatusSaleEnd int16 `json:"statusSaleEnd" validate:"max=2359,min=1"`
|
||||
Skus []*StoreSkuBindSkuInfo `json:"skus,omitempty"`
|
||||
}
|
||||
|
||||
@@ -1082,15 +1082,10 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
|
||||
updateFieldMap["JxPrice"] = 1
|
||||
}
|
||||
if skuBindInfo.StatusSaleBegin != 0 && skuBindInfo.StatusSaleEnd != 0 {
|
||||
if skuBindInfo.StatusSaleBegin < 0 || skuBindInfo.StatusSaleBegin > 2359 ||
|
||||
skuBindInfo.StatusSaleEnd < 0 || skuBindInfo.StatusSaleEnd > 2359 {
|
||||
if err := ValidateStruct(skuBindInfo); err != nil {
|
||||
dao.Rollback(db)
|
||||
return nil, fmt.Errorf("更改商品:%s, 可售时间不合法!时间范围:[%v] 至 [%v]", allBinds[0].Name, skuBindInfo.StatusSaleBegin, skuBindInfo.StatusSaleEnd)
|
||||
}
|
||||
if skuBindInfo.StatusSaleBegin >= skuBindInfo.StatusSaleEnd {
|
||||
dao.Rollback(db)
|
||||
return nil, fmt.Errorf("更改商品:%s, 可售时间不允许交叉!时间范围:[%v] 至 [%v]", allBinds[0].Name, skuBindInfo.StatusSaleBegin, skuBindInfo.StatusSaleEnd)
|
||||
}
|
||||
updateFieldMap["StatusSaleBegin"] = int(skuBindInfo.StatusSaleBegin)
|
||||
updateFieldMap["StatusSaleEnd"] = int(skuBindInfo.StatusSaleEnd)
|
||||
skuBind.StatusSaleBegin = skuBindInfo.StatusSaleBegin
|
||||
|
||||
@@ -3,6 +3,8 @@ package cms
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gopkg.in/go-playground/validator.v9"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
)
|
||||
@@ -10,6 +12,7 @@ import (
|
||||
var (
|
||||
unitNamesMap map[string]int
|
||||
specUnitNamesMap map[string]int
|
||||
validate = validator.New()
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -33,3 +36,15 @@ func ValidateUnit(value interface{}) (err error) {
|
||||
func ValidateSpecUnit(value interface{}) (err error) {
|
||||
return validateStringInMap("SpecUnit", value, specUnitNamesMap)
|
||||
}
|
||||
|
||||
func ValidateStruct(value interface{}) (err error) {
|
||||
return validate.Struct(value)
|
||||
}
|
||||
|
||||
func ValidateVar(value interface{}, tag string) (err error) {
|
||||
return validate.Var(value, tag)
|
||||
}
|
||||
|
||||
func ValidateStructPartial(value interface{}, fields ...string) (err error) {
|
||||
return validate.StructPartial(value, fields...)
|
||||
}
|
||||
|
||||
@@ -133,8 +133,10 @@ func Init() {
|
||||
}, []string{
|
||||
"04:05:06",
|
||||
})
|
||||
}
|
||||
if beego.BConfig.RunMode == "alpha" {
|
||||
ScheduleTimerFunc("ChangeStoreSkuSaleStatus", func() {
|
||||
cms.CurVendorSync.ChangeStoreSkuSaleStatus(jxcontext.AdminCtx, 0, true, false)
|
||||
cms.CurVendorSync.ChangeStoreSkuSaleStatus(jxcontext.AdminCtx, 0, true, true)
|
||||
}, ChangeStoreSkuSaleStatusList)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,18 +84,18 @@ const (
|
||||
UpdateGoodsShelfStatusCount = 50 //微盟下架商品api限制一次50个
|
||||
)
|
||||
|
||||
func LoadExcelByYongHui(ctx *jxcontext.Context, files []*multipart.FileHeader, isAsync bool) (hint string, err error) {
|
||||
func LoadExcelByYongHui(ctx *jxcontext.Context, files []*multipart.FileHeader, isAsync, isContinueWhenError 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)
|
||||
hint, err = LoadExcelBinByYongHui(ctx, file, true, true)
|
||||
file.Close()
|
||||
return hint, err
|
||||
}
|
||||
|
||||
func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync bool) (hint string, err error) {
|
||||
func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
var (
|
||||
skuMap = make(map[string]float64)
|
||||
errMsg string
|
||||
@@ -121,7 +121,7 @@ func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync boo
|
||||
}
|
||||
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)
|
||||
errMsg += fmt.Sprintf("读取Excel数据失败,Excel格式排版可能发生了变化!sheetName: [%v]\n", k)
|
||||
}
|
||||
}
|
||||
if errMsg != "" {
|
||||
@@ -169,7 +169,7 @@ func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync boo
|
||||
//获取京西库商品
|
||||
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)
|
||||
return "", errors.New(fmt.Sprintf("在京西库中未找到该商品!name_id : [%v]\n", goodsDetail.SkuMap.SingleSku.OuterSkuCode))
|
||||
} else {
|
||||
if skuList[0].Unit == "份" {
|
||||
if goodsDetail.SkuMap.SingleSku.B2CSku.Weight == 0 {
|
||||
@@ -191,15 +191,15 @@ func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync boo
|
||||
}
|
||||
return retVal, err
|
||||
}
|
||||
taskParallel3 := tasksch.NewParallelTask("根据获取的微盟所有商品并更新", tasksch.NewParallelConfig().SetParallelCount(parallelCount), ctx, taskFunc3, goodsList)
|
||||
taskParallel3 := tasksch.NewParallelTask("根据获取的微盟所有商品并更新", tasksch.NewParallelConfig().SetParallelCount(parallelCount).SetIsContinueWhenError(isContinueWhenError), 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{}
|
||||
@@ -214,9 +214,12 @@ func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync boo
|
||||
_, err = taskParallel4.GetResult(0)
|
||||
// }
|
||||
}
|
||||
if errMsg != "" {
|
||||
return result, errors.New(errMsg)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
taskSeq := tasksch.NewSeqTask("读取永辉Excel文件修改微盟商品价格可售状态-序列任务", ctx, taskSeqFunc, 4)
|
||||
taskSeq := tasksch.NewSeqTask2("读取永辉Excel文件修改微盟商品价格可售状态-序列任务", ctx, isContinueWhenError, taskSeqFunc, 4)
|
||||
tasksch.HandleTask(taskSeq, nil, true).Run()
|
||||
if !isAsync {
|
||||
_, err = taskSeq.GetResult(0)
|
||||
@@ -224,16 +227,12 @@ func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync boo
|
||||
} 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)
|
||||
err = api.WeimobAPI.UpdateGoodsShelfStatus(goodsIDListForPutAway, false)
|
||||
}
|
||||
if err != nil {
|
||||
baseapi.SugarLogger.Errorf("UpdateGoodsShelfStatus error:%v", err)
|
||||
@@ -293,7 +292,7 @@ func updateWeiMobGoods(costPrice, salePrice float64, goodsDetail *weimobapi.Good
|
||||
SalePrice: salePrice,
|
||||
CostPrice: costPrice,
|
||||
SkuID: skuListInfo.SkuID,
|
||||
EditStockNum: 9999 - skuListInfo.EditStockNum,
|
||||
EditStockNum: 9999 - skuListInfo.AvailableStockNum,
|
||||
OuterSkuCode: skuListInfo.OuterSkuCode,
|
||||
B2CSku: b2CSku,
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
func IDCULDFilterMapByStructObject(mapData map[string]interface{}, obj interface{}, isCheckValue bool) (valid map[string]interface{}, invalid map[string]interface{}) {
|
||||
// 这里必须用首字母小写,因为是用于访问map,是需要完全匹配的
|
||||
return refutil.FilterMapByStructObject(mapData, obj, []string{"id", "createdAt", "updatedAt", "finishedAt", "deletedAt", "syncStatus", "lastOperator"}, isCheckValue)
|
||||
return refutil.FilterMapByStructObject(mapData, obj, nil, []string{"id", "createdAt", "updatedAt", "finishedAt", "deletedAt", "syncStatus", "lastOperator"}, isCheckValue)
|
||||
}
|
||||
|
||||
func NormalMakeMapByStructObject(mapData map[string]interface{}, obj interface{}, userName string) (retVal map[string]interface{}) {
|
||||
@@ -26,6 +26,16 @@ func StrictMakeMapByStructObject(mapData map[string]interface{}, obj interface{}
|
||||
return retVal
|
||||
}
|
||||
|
||||
func IDCULDFilterMapByStructObject2(mapData map[string]interface{}, obj interface{}, objPtr interface{}, isCheckValue bool) (valid map[string]interface{}, invalid map[string]interface{}) {
|
||||
return refutil.FilterMapByStructObject(mapData, obj, objPtr, []string{"id", "createdAt", "updatedAt", "finishedAt", "deletedAt", "syncStatus", "lastOperator"}, isCheckValue)
|
||||
}
|
||||
|
||||
//根据传进来的objPtr去修改它的值
|
||||
func StrictMakeMapByStructObject2(mapData map[string]interface{}, obj interface{}, objPtr interface{}, userName string) (retVal map[string]interface{}) {
|
||||
retVal, _ = IDCULDFilterMapByStructObject2(mapData, obj, objPtr, true)
|
||||
return retVal
|
||||
}
|
||||
|
||||
func NormalMakeMapByFieldList(mapData map[string]interface{}, fields []string, userName string) (retVal map[string]interface{}) {
|
||||
retVal, _ = refutil.FilterMapByFieldList(mapData, fields)
|
||||
return retVal
|
||||
|
||||
@@ -252,14 +252,14 @@ type Store struct {
|
||||
Address string `orm:"size(255)" json:"address"`
|
||||
Tel1 string `orm:"size(32);index" json:"tel1"`
|
||||
Tel2 string `orm:"size(32);index" json:"tel2"`
|
||||
OpenTime1 int16 `json:"openTime1"` // 930就表示9点半,用两个的原因是为了支持中午休息,1与2的时间段不能交叉,为0表示没有
|
||||
CloseTime1 int16 `json:"closeTime1"` // 格式同上
|
||||
OpenTime2 int16 `json:"openTime2"` // 格式同上
|
||||
CloseTime2 int16 `json:"closeTime2"` // 格式同上
|
||||
Lng int `json:"-"` // 乘了10的6次方
|
||||
Lat int `json:"-"` // 乘了10的6次方
|
||||
DeliveryRangeType int8 `json:"deliveryRangeType"` // 参见相关常量定义
|
||||
DeliveryRange string `orm:"type(text)" json:"deliveryRange"` // 如果DeliveryRangeType为DeliveryRangeTypePolygon,则为逗号分隔坐标,分号分隔的坐标点(坐标与Lng和Lat一样,都是整数),比如 121361504,31189308;121420555,31150238。否则为半径,单位为米
|
||||
OpenTime1 int16 `json:"openTime1" validate:"max=2359,min=1,ltfield=CloseTime1"` // 930就表示9点半,用两个的原因是为了支持中午休息,1与2的时间段不能交叉,为0表示没有
|
||||
CloseTime1 int16 `json:"closeTime1" validate:"max=2359,min=1` // 格式同上
|
||||
OpenTime2 int16 `json:"openTime2" validate:"max=2359,min=1,ltfield=CloseTime2"` // 格式同上
|
||||
CloseTime2 int16 `json:"closeTime2" validate:"max=2359,min=1` // 格式同上
|
||||
Lng int `json:"-"` // 乘了10的6次方
|
||||
Lat int `json:"-"` // 乘了10的6次方
|
||||
DeliveryRangeType int8 `json:"deliveryRangeType"` // 参见相关常量定义
|
||||
DeliveryRange string `orm:"type(text)" json:"deliveryRange"` // 如果DeliveryRangeType为DeliveryRangeTypePolygon,则为逗号分隔坐标,分号分隔的坐标点(坐标与Lng和Lat一样,都是整数),比如 121361504,31189308;121420555,31150238。否则为半径,单位为米
|
||||
Status int `json:"status"`
|
||||
AutoEnableAt *time.Time `orm:"type(datetime);null" json:"autoEnableAt"` // 自动营业时间(临时休息用)
|
||||
ChangePriceType int8 `json:"changePriceType"` // 修改价格类型,即是否需要审核
|
||||
|
||||
@@ -46,7 +46,7 @@ func (c *FinancialController) SendFilesToStores() {
|
||||
if params.Title != "永辉" {
|
||||
retVal, err = financial.SendFilesToStores(params.Ctx, files, params.Title, params.ShopName, params.IsAsync, params.Ctx.GetUserName())
|
||||
} else {
|
||||
retVal, err = yonghui.LoadExcelByYongHui(params.Ctx, files, params.IsAsync)
|
||||
retVal, err = yonghui.LoadExcelByYongHui(params.Ctx, files, params.IsAsync, true)
|
||||
}
|
||||
return retVal, "", err
|
||||
})
|
||||
|
||||
@@ -14,8 +14,9 @@ type YongHuiController struct {
|
||||
|
||||
// @Title 读取永辉excel文件
|
||||
// @Description 读取永辉excel文件
|
||||
// @Param token header string false "认证token"
|
||||
// @Param isAsync query bool false "是否异步,缺省是同步"
|
||||
// @Param token header string false "认证token"
|
||||
// @Param isAsync query bool true "是否异步,缺省是同步"
|
||||
// @Param isContinueWhenError query bool true "单个同步失败是否继续,缺省false"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /LoadExcelByYongHui [post,get]
|
||||
@@ -36,7 +37,7 @@ func (c *YongHuiController) LoadExcelByYongHui() {
|
||||
c.callLoadExcelByYongHui(func(params *tYonghuiLoadExcelByYongHuiParams) (retVal interface{}, errCode string, err error) {
|
||||
r := c.Ctx.Request
|
||||
files := r.MultipartForm.File["userfiles"]
|
||||
retVal, err = yonghui.LoadExcelByYongHui(params.Ctx, files, params.IsAsync)
|
||||
retVal, err = yonghui.LoadExcelByYongHui(params.Ctx, files, params.IsAsync, params.IsContinueWhenError)
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func DeSerializeData(strValue string, dataPtr interface{}) (err error) {
|
||||
}
|
||||
|
||||
// todo 这里看是否需要将key值转换成标准格式(即字母大写),因为beego orm不区分,不转换也可以
|
||||
func FilterMapByStructObject(mapData map[string]interface{}, obj interface{}, excludedFields []string, isCheckValue bool) (valid map[string]interface{}, invalid map[string]interface{}) {
|
||||
func FilterMapByStructObject(mapData map[string]interface{}, obj interface{}, objPtr interface{}, excludedFields []string, isCheckValue bool) (valid map[string]interface{}, invalid map[string]interface{}) {
|
||||
excludedMap := make(map[string]int)
|
||||
for _, v := range excludedFields {
|
||||
excludedMap[v] = 1
|
||||
@@ -64,10 +64,14 @@ func FilterMapByStructObject(mapData map[string]interface{}, obj interface{}, ex
|
||||
for k, v := range mapData {
|
||||
if m[k] != nil && excludedMap[k] == 0 && v != nil && (!isCheckValue || !IsValueEqual(m[k], v)) {
|
||||
valid[k] = v
|
||||
m[k] = v
|
||||
} else {
|
||||
invalid[k] = v
|
||||
}
|
||||
}
|
||||
if objPtr != nil {
|
||||
utils.Map2StructByJson(m, objPtr, true)
|
||||
}
|
||||
return valid, invalid
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user