- 平台门店调价价格包实现初始版本

This commit is contained in:
gazebo
2019-07-16 11:36:28 +08:00
parent bdee4269d5
commit f133ccb290
13 changed files with 292 additions and 22 deletions

View File

@@ -1,7 +1,9 @@
package cms
import (
"fmt"
"strconv"
"strings"
"time"
"git.rosy.net.cn/jx-callback/business/jxutils/msg"
@@ -186,3 +188,96 @@ func SendMsg2Somebody(ctx *jxcontext.Context, msgType, msgContent string) (err e
}
return err
}
func checkConfig(configType, value string) (err error) {
switch configType {
case model.ConfigTypePricePack:
if value != "" {
pricePack := dao.PricePercentagePack2Obj(value)
if pricePack == nil {
err = fmt.Errorf("配置:%s不合法", value)
}
}
default:
err = fmt.Errorf("当前只支持价格包配置:%s", model.ConfigTypePricePack)
}
return
}
func AddConfig(ctx *jxcontext.Context, key, configType, value string) (err error) {
if err = checkConfig(configType, value); err != nil {
return err
}
db := dao.GetDB()
conf := &model.NewConfig{
Key: key,
Type: configType,
Value: value,
}
dao.WrapAddIDCULDEntity(conf, ctx.GetUserName())
return dao.CreateEntity(db, conf)
}
func DeleteConfig(ctx *jxcontext.Context, key, configType string) (err error) {
if err = checkConfig(configType, ""); err != nil {
return err
}
db := dao.GetDB()
storeMapList, err := dao.GetStoresMapList(db, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, key)
if err != nil {
return err
}
if len(storeMapList) > 0 {
var storeInfo []string
for _, v := range storeMapList {
storeInfo = append(storeInfo, fmt.Sprintf("门店:%d, 平台:%s", v.StoreID, model.VendorChineseNames[v.VendorID]))
}
return fmt.Errorf("还有门店在使用价格包:%s门店信息:%s", key, strings.Join(storeInfo, ","))
}
_, err = dao.DeleteEntityLogically(db, &model.NewConfig{}, nil, ctx.GetUserName(), map[string]interface{}{
"Key": key,
"Type": configType,
})
return err
}
func UpdateConfig(ctx *jxcontext.Context, key, configType, value string) (err error) {
if err = checkConfig(configType, value); err != nil {
return err
}
db := dao.GetDB()
configList, err := dao.QueryConfigs(db, key, configType, "")
if err != nil {
return err
}
storeMapList, err := dao.GetStoresMapList(db, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, key)
if err != nil {
return err
}
dao.Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
dao.Rollback(db)
if r != nil {
panic(r)
}
}
}()
if _, err = dao.UpdateEntityLogically(db, configList[0], map[string]interface{}{
"Value": value,
}, ctx.GetUserName(), nil); err != nil {
return err
}
for _, v := range storeMapList {
if _, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, &model.StoreSkuBind{}, nil, ctx.GetUserName(), map[string]interface{}{
model.FieldStoreID: v.StoreID,
}, dao.GetSyncStatusStructField(model.VendorNames[v.VendorID]), model.SyncFlagPriceMask); err != nil {
return err
}
}
dao.Commit(db)
return err
}

View File

@@ -791,6 +791,12 @@ func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendor
return 0, err
}
valid := dao.StrictMakeMapByStructObject(payload, storeMap, userName)
if valid["pricePercentagePack"] != nil {
_, err2 := dao.QueryConfigs(db, model.ConfigTypePricePack, utils.Interface2String(valid["pricePercentagePack"]), "")
if err = err2; err != nil {
return 0, err
}
}
if vendorStoreID := utils.Interface2String(valid["vendorStoreID"]); vendorStoreID != "" {
vendorStoreInfo, err2 := storeHandler.ReadStore(vendorStoreID)
if err = err2; err == nil {
@@ -817,7 +823,7 @@ func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendor
})
}
if err == nil && num > 0 {
if valid["pricePercentage"] != nil {
if valid["pricePercentage"] != nil || valid["pricePercentagePack"] != nil {
storeSkuBind := &model.StoreSkuBind{}
if num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, storeSkuBind, nil, userName, map[string]interface{}{
model.FieldStoreID: storeID,
@@ -1127,7 +1133,7 @@ func composeDadaStoreName(storeDetail *dao.StoreDetail2) (storeName string) {
func ExportShopsHealthInfo(ctx *jxcontext.Context, vendorIDs, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
db := dao.GetDB()
vendorID := model.VendorIDEBAI
storeMapList, err := dao.GetStoresMapList(db, []int{vendorID}, storeIDs, model.StoreStatusAll, model.StoreIsSyncYes)
storeMapList, err := dao.GetStoresMapList(db, []int{vendorID}, storeIDs, model.StoreStatusAll, model.StoreIsSyncYes, "")
if err != nil {
return "", err
}
@@ -1214,7 +1220,7 @@ func GetCorporationInfo(ctx *jxcontext.Context, licenceCode string) (corporation
func GetStoresVendorSnapshot(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs, storeIDs []int) (vendorStoreSnapshotList []*model.VendorStoreSnapshot, err error) {
db := dao.GetDB()
storeMapList, err := dao.GetStoresMapList(db, vendorIDs, storeIDs, model.StoreStatusAll, model.StoreIsSyncYes)
storeMapList, err := dao.GetStoresMapList(db, vendorIDs, storeIDs, model.StoreStatusAll, model.StoreIsSyncYes, "")
if err != nil {
return nil, err
}
@@ -1256,7 +1262,7 @@ func getCurrentSnapshotAt(now time.Time) (snapshotAt time.Time) {
}
func updateVendorStoreStatusBySnapshot(db *dao.DaoDB, curSnapshotList []*model.VendorStoreSnapshot) (err error) {
storeMapList, err := dao.GetStoresMapList(db, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll)
storeMapList, err := dao.GetStoresMapList(db, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "")
if err != nil {
return err
}

View File

@@ -819,7 +819,7 @@ func GetStoresSkusOld(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo
}
func getValidStoreVendorMap(db *dao.DaoDB, storeIDs []int) (realVendorMap map[int]int, err error) {
storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, model.StoreStatusAll, model.StoreIsSyncYes)
storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, model.StoreStatusAll, model.StoreIsSyncYes, "")
if err != nil {
return nil, err
}
@@ -1968,19 +1968,22 @@ func RefreshStoresSkuByVendor(ctx *jxcontext.Context, storeIDs []int, vendorID i
return "", fmt.Errorf("此功能当前只支持京东到家平台")
}
db := dao.GetDB()
storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, model.StoreStatusAll, model.StoreIsSyncAll)
storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, model.StoreStatusAll, model.StoreIsSyncAll, "")
if err != nil {
return "", err
}
if len(storeMapList) != len(storeIDs) {
return "", fmt.Errorf("门店绑定信息不匹配,请确定门店绑定且只绑定了京东平台")
}
storeMap := make(map[int]*model.StoreMap)
storeMap := make(map[int]*dao.StoreDetail)
for _, v := range storeMapList {
if v.VendorID != vendorID {
return "", fmt.Errorf("门店%d绑定的不是京东", v.StoreID)
}
storeMap[v.StoreID] = v
storeMap[v.StoreID], err = dao.GetStoreDetail(db, v.StoreID, v.VendorID)
if err != nil {
return "", err
}
}
handler := partner.GetPurchasePlatformFromVendorID(vendorID)

View File

@@ -541,7 +541,7 @@ func (v *VendorSync) PruneMissingStoreSkus(ctx *jxcontext.Context, vendorIDs []i
func (v *VendorSync) LoopStoresMap2(ctx *jxcontext.Context, db *dao.DaoDB, taskName string, isAsync, isManageIt bool, vendorIDs []int, storeIDs []int, handler tasksch.WorkFunc, isContinueWhenError bool) (task tasksch.ITask, hint string, err error) {
var storeMapList []*model.StoreMap
if storeMapList, err = dao.GetStoresMapList(db, vendorIDs, storeIDs, model.StoreStatusAll, model.StoreIsSyncYes); err != nil {
if storeMapList, err = dao.GetStoresMapList(db, vendorIDs, storeIDs, model.StoreStatusAll, model.StoreIsSyncYes, ""); err != nil {
return nil, "", err
}
if len(storeMapList) == 0 {

View File

@@ -183,7 +183,6 @@ func GetStoreMapByStoreID(db *DaoDB, storeID, vendorID int) (storeMap *model.Sto
}
return nil, err
}
storeMap.PricePercentagePackObj = PricePercentagePack2Obj(storeMap.PricePercentagePack)
return storeMap, nil
}

View File

@@ -0,0 +1,38 @@
package dao
import (
"fmt"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model"
)
func QueryConfigs(db *DaoDB, key, configType, keyword string) (configList []*model.NewConfig, err error) {
sql := `
SELECT
t1.*
FROM new_config t1
WHERE t1.deleted_at = ?`
sqlParams := []interface{}{
utils.DefaultTimeValue,
}
if key != "" {
sql += " AND t1.key = ?"
sqlParams = append(sqlParams, key)
}
if configType != "" {
sql += " AND t1.type = ?"
sqlParams = append(sqlParams, configType)
}
if keyword != "" {
keywordLike := "%" + keyword + "%"
sql += " AND (t1.type LIKE ? OR t1.key LIKE ? OR value LIKE ?)"
sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike)
}
err = GetRows(db, &configList, sql, sqlParams...)
if err == nil && len(configList) == 0 {
err = fmt.Errorf("条件:key:%s,type:%s,keyword:%s不能找到配置", key, configType, keyword)
}
return configList, err
}

View File

@@ -16,8 +16,8 @@ type StoreDetail struct {
DeliveryFee int `json:"deliveryFee"`
SyncStatus int8 `orm:"default(2)" json:"syncStatus"`
PricePercentage int16 `orm:"default(100)" json:"pricePercentage"` // todo 厂商价格相对于本地价格的百分比,这个字段的修改会比较特殊,因为可能需要刷新厂商价格
PricePercentagePack string `orm:"size(4096)" json:"pricePercentagePack"` //
PricePercentage int16 `orm:"default(100)" json:"pricePercentage"` // todo 厂商价格相对于本地价格的百分比,这个字段的修改会比较特殊,因为可能需要刷新厂商价格
PricePercentagePackStr string `orm:"size(4096)" json:"-"` //
PricePercentagePackObj model.PricePercentagePack `orm:"-" json:"-"`
AutoPickup int8 `orm:"default(1)" json:"autoPickup"` // 是否自动拣货
@@ -47,7 +47,7 @@ func getStoreDetail(db *DaoDB, storeID, vendorID int, vendorStoreID string) (sto
sql := `
SELECT t1.*,
t2.vendor_store_id, t2.status vendor_status, t2.delivery_fee, t2.sync_status,
t2.price_percentage, t2.price_percentage_pack, t2.auto_pickup, t2.delivery_type, t2.delivery_competition, t2.is_sync,
t2.price_percentage, t3.value price_percentage_pack_str, t2.auto_pickup, t2.delivery_type, t2.delivery_competition, t2.is_sync,
district.code, district.name district_name, district.parent_code, district.level, district.tel_code,
district.jd_code, district.ebai_code, district.enabled, district.mtps_price,
city.name city_name
@@ -55,12 +55,15 @@ func getStoreDetail(db *DaoDB, storeID, vendorID int, vendorStoreID string) (sto
JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND t2.deleted_at = ?
LEFT JOIN place city ON city.code = t1.city_code
LEFT JOIN place district ON district.code = t1.district_code
LEFT JOIN new_config t3 ON t3.key = t2.price_percentage_pack AND t3.type = ? AND t3.deleted_at = ?
WHERE t1.deleted_at = ?
`
sqlParams := []interface{}{
vendorID,
utils.DefaultTimeValue,
utils.DefaultTimeValue,
model.ConfigTypePricePack,
utils.DefaultTimeValue,
}
if storeID > 0 {
sql += " AND t1.id = ?"
@@ -73,7 +76,7 @@ func getStoreDetail(db *DaoDB, storeID, vendorID int, vendorStoreID string) (sto
storeDetail = &StoreDetail{}
if err = GetRow(db, storeDetail, sql, sqlParams...); err == nil {
storeDetail.Place.Name = storeDetail.DistrictName
storeDetail.PricePercentagePackObj = PricePercentagePack2Obj(storeDetail.PricePercentagePack)
storeDetail.PricePercentagePackObj = PricePercentagePack2Obj(storeDetail.PricePercentagePackStr)
return storeDetail, nil
}
return nil, err
@@ -199,7 +202,7 @@ func GetStoreCourierList(db *DaoDB, storeID, status int) (courierStoreList []*mo
return nil, err
}
func GetStoresMapList(db *DaoDB, vendorIDs, storeIDs []int, status, isSync int) (storeMapList []*model.StoreMap, err error) {
func GetStoresMapList(db *DaoDB, vendorIDs, storeIDs []int, status, isSync int, pricePack string) (storeMapList []*model.StoreMap, err error) {
sql := `
SELECT t1.*
FROM store_map t1
@@ -224,11 +227,12 @@ func GetStoresMapList(db *DaoDB, vendorIDs, storeIDs []int, status, isSync int)
sql += " AND t1.is_sync = ?"
sqlParams = append(sqlParams, isSync)
}
if pricePack != "" {
sql += " AND t1.price_percentage_pack = ?"
sqlParams = append(sqlParams, pricePack)
}
sql += " ORDER BY t1.store_id, t1.vendor_id"
if err = GetRows(db, &storeMapList, sql, sqlParams...); err == nil {
for _, v := range storeMapList {
v.PricePercentagePackObj = PricePercentagePack2Obj(v.PricePercentagePack)
}
return storeMapList, nil
}
return nil, err
@@ -318,6 +322,11 @@ func GetRebindPrinterStoreList(db *DaoDB) (storeList []*model.Store, err error)
func PricePercentagePack2Obj(packStr string) (obj model.PricePercentagePack) {
if packStr != "" {
if err := utils.UnmarshalUseNumber([]byte(packStr), &obj); err == nil {
for _, v := range obj {
if v.PricePercentage >= 500 || v.PricePercentage <= 80 {
return nil
}
}
sort.Sort(obj)
}
}

View File

@@ -0,0 +1,20 @@
package model
const (
ConfigTypeSys = "Sys"
ConfigTypePricePack = "PricePack"
)
type NewConfig struct {
ModelIDCULD
Type string `orm:"size(16)" json:"type"`
Key string `orm:"size(32)" json:"key"`
Value string `orm:"size(4096)" json:"value"`
}
func (*NewConfig) TableUnique() [][]string {
return [][]string{
[]string{"Key", "Type", "DeletedAt"},
}
}

View File

@@ -227,9 +227,8 @@ type StoreMap struct {
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"`
Status int `json:"status"` // 取值同Store.Status
PricePercentage int16 `orm:"default(100)" json:"pricePercentage"` // todo 厂商价格相对于本地价格的百分比,这个字段的修改会比较特殊,因为可能需要刷新厂商价格
PricePercentagePack string `orm:"size(4096)" json:"pricePercentagePack"` //
PricePercentagePackObj PricePercentagePack `orm:"-" json:"-"`
PricePercentage int16 `orm:"default(100)" json:"pricePercentage"` // todo 厂商价格相对于本地价格的百分比,这个字段的修改会比较特殊,因为可能需要刷新厂商价格
PricePercentagePack string `orm:"size(32)" json:"pricePercentagePack"` //
AutoPickup int8 `orm:"default(1)" json:"autoPickup"` // 是否自动拣货
DeliveryType int8 `orm:"default(0)" json:"deliveryType"` // 配送类型

View File

@@ -38,7 +38,7 @@ func (c *PurchaseHandler) refreshCommentOnce() {
func (c *PurchaseHandler) RefreshComment(fromTime, toTime time.Time) (err error) {
if globals.EnableMtwmStoreWrite {
storeMapList, err2 := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDMTWM}, nil, model.StoreStatusAll, model.StoreIsSyncAll)
storeMapList, err2 := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDMTWM}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "")
if err = err2; err != nil {
return err
}

View File

@@ -6,6 +6,7 @@ import (
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/jxutils/configindb"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/msghub"
"git.rosy.net.cn/jx-callback/globals/api"
"github.com/astaxie/beego"
@@ -215,3 +216,66 @@ func (c *CmsController) SendMsg2Somebody() {
return retVal, "", err
})
}
// @Title 新增配置
// @Description 新增配置
// @Param token header string true "认证token"
// @Param type formData string true "配置类型当前只支持PricePack"
// @Param key formData string true "配置名"
// @Param value formData string true "配置值"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /NewConfig [post]
func (c *CmsController) NewConfig() {
c.callNewConfig(func(params *tCmsNewConfigParams) (retVal interface{}, errCode string, err error) {
err = cms.AddConfig(params.Ctx, params.Key, params.Type, params.Value)
return retVal, "", err
})
}
// @Title 删除配置
// @Description 删除配置
// @Param token header string true "认证token"
// @Param type query string true "配置类型当前只支持PricePack"
// @Param key query string true "配置名"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /DeleteConfig [delete]
func (c *CmsController) DeleteConfig() {
c.callDeleteConfig(func(params *tCmsDeleteConfigParams) (retVal interface{}, errCode string, err error) {
err = cms.DeleteConfig(params.Ctx, params.Key, params.Type)
return retVal, "", err
})
}
// @Title 修改配置
// @Description 修改配置
// @Param token header string true "认证token"
// @Param type formData string true "配置类型当前只支持PricePack"
// @Param key formData string true "配置名"
// @Param value formData string true "配置值"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /UpdateConfig [put]
func (c *CmsController) UpdateConfig() {
c.callUpdateConfig(func(params *tCmsUpdateConfigParams) (retVal interface{}, errCode string, err error) {
err = cms.UpdateConfig(params.Ctx, params.Key, params.Type, params.Value)
return retVal, "", err
})
}
// @Title 查询配置
// @Description 查询配置
// @Param token header string true "认证token"
// @Param type query string false "配置类型当前只支持PricePack"
// @Param key query string false "配置名"
// @Param keyword query string false "关键字"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /QueryConfigs [get]
func (c *CmsController) QueryConfigs() {
c.callQueryConfigs(func(params *tCmsQueryConfigsParams) (retVal interface{}, errCode string, err error) {
retVal, err = dao.QueryConfigs(dao.GetDB(), params.Key, params.Type, params.Keyword)
return retVal, "", err
})
}

View File

@@ -50,6 +50,7 @@ func Init() {
orm.RegisterModel(&model.OrderFinancial{}, &model.AfsOrder{}, &model.OrderDiscountFinancial{}, &model.OrderSkuFinancial{})
orm.RegisterModel(&model.Act{}, &model.ActOrderRule{}, &model.ActStoreSku{})
orm.RegisterModel(&model.ActMap{}, &model.ActStoreSkuMap{})
orm.RegisterModel(&model.NewConfig{})
// create table
orm.RunSyncdb("default", false, true)
}

View File

@@ -268,6 +268,15 @@ func init() {
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"],
beego.ControllerComments{
Method: "DeleteConfig",
Router: `/DeleteConfig`,
AllowHTTPMethods: []string{"delete"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"],
beego.ControllerComments{
Method: "FakeNewOrder",
@@ -340,6 +349,24 @@ func init() {
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"],
beego.ControllerComments{
Method: "NewConfig",
Router: `/NewConfig`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"],
beego.ControllerComments{
Method: "QueryConfigs",
Router: `/QueryConfigs`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"],
beego.ControllerComments{
Method: "SendMsg2Somebody",
@@ -358,6 +385,15 @@ func init() {
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"],
beego.ControllerComments{
Method: "UpdateConfig",
Router: `/UpdateConfig`,
AllowHTTPMethods: []string{"put"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"],
beego.ControllerComments{
Method: "UpdatePlace",