Merge remote-tracking branch 'origin/mark' into yonghui

This commit is contained in:
苏尹岚
2020-01-08 09:09:53 +08:00
15 changed files with 173 additions and 46 deletions

View File

@@ -167,7 +167,7 @@ func ActStoreSkuParam2Model(ctx *jxcontext.Context, db *dao.DaoDB, act *model.Ac
storeIDs := jxutils.IntMap2List(storeIDMap)
skuIDs := jxutils.IntMap2List(skuIDMap)
// 判断活动是否重叠的检查,当前忽略京东平台及所有结算信息
if !(len(vendorIDs) == 1 && vendorIDs[0] == model.VendorIDJD || act.Type == model.ActSkuFake) {
if act.OverlapRule == model.OverlapRuleNormal {
effectActStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, act.Type, storeIDs, skuIDs, act.BeginAt, act.EndAt)
if err != nil {
globals.SugarLogger.Errorf("GetEffectiveActStoreSkuInfo can not get sku promotion info for error:%v", err)

View File

@@ -28,6 +28,9 @@ const (
ActCreateTypeAPI = 1
ActCreateTypeCallback = 2
ActCreateTypeSpider = 3
OverlapRuleNormal = 0 // 不允许重叠(重叠会报错)
OverlapRuleReplace = 1 // 相同活动类型,或秒杀替换直降
)
var (
@@ -63,6 +66,7 @@ type Act struct {
LimitCount int `json:"limitCount"` // 每单限购数量
Source string `orm:"size(255)" json:"source"`
CreateType int `json:"createType"`
OverlapRule int `json:"overlapRule"`
PricePercentage int `json:"pricePercentage"` // 单品级活动才有效
BeginAt time.Time `orm:"type(datetime);index" json:"beginAt"`
EndAt time.Time `orm:"type(datetime);index" json:"endAt"`

View File

@@ -54,7 +54,7 @@ func GetSysConfigAsInt64(db *DaoDB, key string) (value int64, err error) {
configList, err := QueryConfigs(db, key, model.ConfigTypeSys, "")
if err == nil && len(configList) > 0 {
value = utils.Str2Int64WithDefault(configList[0].Value, 0)
} else if IsNoRowsError(err) {
} else if true { //IsNoRowsError(err) { // todo 暂时忽略所有错误
err = nil
}
return value, err

View File

@@ -13,6 +13,11 @@ import (
"git.rosy.net.cn/jx-callback/globals"
)
type StoreSkuAndAct struct {
*model.StoreSkuBind
ActMap map[int]*model.StoreSkuAct
}
var (
dataResFieldMap = map[int]string{
model.VendorIDMTWM: "mtwm_url",
@@ -798,6 +803,55 @@ func GetStoresSkusInfo(db *DaoDB, storeIDs, skuIDs []int) (storeSkuList []*model
return storeSkuList, err
}
func GetStoresSkusAndActInfo(db *DaoDB, storeIDs, skuIDs, vendorIDs []int) (storeSkuAndActList []*StoreSkuAndAct, err error) {
storeSkuList, err := GetStoresSkusInfo(db, storeIDs, skuIDs)
if err == nil && len(storeSkuList) > 0 {
storeSkuActList, err2 := GetStoresSkusAct(db, storeIDs, skuIDs, vendorIDs)
if err = err2; err == nil {
actMap := make(map[int64][]*model.StoreSkuAct)
for _, v := range storeSkuActList {
actMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = append(actMap[jxutils.Combine2Int(v.StoreID, v.SkuID)], v)
}
for _, v := range storeSkuList {
storeSkuAct := &StoreSkuAndAct{
StoreSkuBind: v,
ActMap: make(map[int]*model.StoreSkuAct),
}
for _, vv := range actMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] {
storeSkuAct.ActMap[vv.VendorID] = vv
}
storeSkuAndActList = append(storeSkuAndActList, storeSkuAct)
}
}
}
return storeSkuAndActList, err
}
func GetStoresSkusAct(db *DaoDB, storeIDs, skuIDs, vendorIDs []int) (storeSkuActList []*model.StoreSkuAct, err error) {
sql := `
SELECT *
FROM store_sku_act t1
WHERE t1.deleted_at = ?
`
sqlParams := []interface{}{
utils.DefaultTimeValue,
}
if len(storeIDs) > 0 {
sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
sqlParams = append(sqlParams, storeIDs)
}
if len(skuIDs) > 0 {
sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
sqlParams = append(sqlParams, skuIDs)
}
if len(vendorIDs) > 0 {
sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
sqlParams = append(sqlParams, vendorIDs)
}
err = GetRows(db, &storeSkuActList, sql, sqlParams...)
return storeSkuActList, err
}
// vendorID, vendorStoreIDs和vendorSkuIDs都是必须参数
func GetStoresSkusInfoByVendorInfo(db *DaoDB, vendorID int, vendorStoreIDs, vendorSkuIDs []string) (storeSkuList []*StoreSkuBindWithVendorInfo, err error) {
if len(vendorStoreIDs) == 0 || len(vendorSkuIDs) == 0 {

View File

@@ -161,3 +161,32 @@ func (*StoreOpRequest) TableIndex() [][]string {
[]string{"StoreID", "Status", "Type"},
}
}
type StoreSkuAct struct {
ModelIDCULD // DeletedAt用于表示请求操作结束而并不一定是删除
StoreID int `orm:"column(store_id)"`
SkuID int `orm:"column(sku_id)"`
VendorID int
ActID int `orm:"column(act_id);index" json:"actID"`
VendorActID string `orm:"column(vendor_act_id);size(48);index" json:"vendorActID"`
SyncStatus int8 `orm:"default(2)" json:"syncStatus"`
VendorPrice int64 `json:"vendorPrice"` // 创建活动时的平台价格
ActualActPrice int64 `json:"actualActPrice"` // 单品级活动用,创建活动时商品的活动价格
EarningActID int `orm:"column(earning_act_id);index" json:"earningActID"`
EarningPrice int `json:"earningPrice"`
}
func (*StoreSkuAct) TableUnique() [][]string {
return [][]string{
[]string{"StoreID", "SkuID", "VendorID", "DeletedAt"},
}
}
func (*StoreSkuAct) TableIndex() [][]string {
return [][]string{
[]string{"SkuID", "DeletedAt"},
}
}

View File

@@ -100,9 +100,7 @@ func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendo
retVal.DeliveryType = EbaiDeliveryType2Jx(utils.Interface2String(result["delivery_type"]))
retVal.SetOpTime(ebaiOpTime2Jx(result["business_time"]))
if ebaiStatus, err2 := api.EbaiAPI.ShopBusStatusGet("", baiduShopID, ebaiapi.PlatformFlagElm); err2 == nil {
retVal.Status = EbaiBusStatus2JxStatus(ebaiStatus)
}
retVal.Status, _ = p.GetStoreStatus(ctx, vendorOrgCode, 0, vendorStoreID)
tel2 := utils.Interface2String(result["ivr_phone"])
if tel2 != "" && tel2 != retVal.Tel1 {
@@ -188,7 +186,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
if err == nil {
if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreStatus) != 0 {
mergeStatus := jxutils.MergeStoreStatus(store.Status, store.EbaiStoreStatus)
if err = p.updateStoreStatus(userName, storeID, store.VendorStoreID, mergeStatus, store2.Status); err != nil {
if err = p.UpdateStoreStatus(jxcontext.AdminCtx, store.VendorOrgCode, storeID, store.VendorStoreID, mergeStatus); err != nil {
return err
}
}
@@ -468,27 +466,21 @@ func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOr
}
func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) {
store, err := c.ReadStore(ctx, vendorOrgCode, vendorStoreID)
if err != nil {
return err
}
return c.updateStoreStatus(ctx.GetUserName(), storeID, vendorStoreID, status, store.Status)
}
func (c *PurchaseHandler) updateStoreStatus(userName string, storeID int, vendorStoreID string, status, currentStatus int) (err error) {
if !isStoreStatusSame(currentStatus, status) {
if globals.EnableEbaiStoreWrite {
if status == model.StoreStatusOpened {
err = api.EbaiAPI.ShopOpen("", utils.Str2Int64(vendorStoreID))
} else if status == model.StoreStatusHaveRest || status == model.StoreStatusClosed {
err = api.EbaiAPI.ShopClose("", utils.Str2Int64(vendorStoreID))
} else if status == model.StoreStatusDisabled {
err = api.EbaiAPI.ShopClose("", utils.Str2Int64(vendorStoreID))
// err = api.EbaiAPI.ShopOffline("", utils.Str2Int64(vendorStoreID))
}
if globals.EnableEbaiStoreWrite {
if status == model.StoreStatusOpened {
err = api.EbaiAPI.ShopOpen("", utils.Str2Int64(vendorStoreID))
} else if status == model.StoreStatusHaveRest || status == model.StoreStatusClosed {
err = api.EbaiAPI.ShopClose("", utils.Str2Int64(vendorStoreID))
} else if status == model.StoreStatusDisabled {
err = api.EbaiAPI.ShopClose("", utils.Str2Int64(vendorStoreID))
// err = api.EbaiAPI.ShopOffline("", utils.Str2Int64(vendorStoreID))
}
if intErr, ok := err.(*utils.ErrorWithCode); ok && intErr.IntCode() == 201100 {
err = nil
if err != nil {
if remoteStatus, err2 := c.GetStoreStatus(ctx, vendorOrgCode, storeID, vendorStoreID); err2 == nil && remoteStatus == status {
err = nil
} else if intErr, ok := err.(*utils.ErrorWithCode); ok && intErr.IntCode() == 201100 {
err = nil
}
}
}
return err

View File

@@ -41,8 +41,9 @@ var (
)
// 是否按单一门店商品维度创建活动
func isCreateTypeSingle() bool {
return !globals.IsProductEnv()
func isCreateTypeSingleStoreSku() bool {
return false
// return !globals.IsProductEnv()
}
func splitPromotionSku(skus []*jdapi.PromotionSku, maxCount int) (skusList [][]*jdapi.PromotionSku) {
@@ -219,6 +220,23 @@ func createSkuAct(ctx *jxcontext.Context, act *model.Act2, actStoreSku []*model.
return vendorActID, err
}
func proxyCreateSkuAct(ctx *jxcontext.Context, act *model.Act2, actStoreSku []*model.ActStoreSku2) (vendorActID string, err error) {
if isCreateTypeSingleStoreSku() && len(actStoreSku) > 1 {
errList := errlist.New()
vendorActID := act.VendorActID
act.VendorActID = "placeholder"
for _, v := range actStoreSku {
_, err := createSkuAct(ctx, act, []*model.ActStoreSku2{v})
errList.AddErr(err)
}
act.VendorActID = vendorActID
err = errList.GetErrListAsOne()
} else {
vendorActID, err = createSkuAct(ctx, act, actStoreSku)
}
return vendorActID, err
}
func cancelSkuActSkus(ctx *jxcontext.Context, act *model.Act2, vendorActID string, actStoreSku []*model.ActStoreSku2) (err error) {
if vendorActID != "" {
if skuList := storeSku2Jd(actStoreSku, model.IsSyncStatusNeedDelete); len(skuList) > 0 {
@@ -282,7 +300,7 @@ func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITa
updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask))
}
} else if model.IsSyncStatusNew(act.SyncStatus) {
if act.VendorActID, err = createSkuAct(ctx, act, actStoreSkuList4Create); err == nil {
if act.VendorActID, err = proxyCreateSkuAct(ctx, act, actStoreSkuList4Create); err == nil {
updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, actStoreSkuList4Create, model.SyncFlagNewMask)...)
updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagNewMask))
} else {
@@ -294,7 +312,7 @@ func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITa
} else if model.IsSyncStatusUpdate(act.SyncStatus) {
errList := errlist.New()
if len(actStoreSkuList4Create) > 0 {
if _, err = createSkuAct(ctx, act, actStoreSkuList4Create); err == nil {
if _, err = proxyCreateSkuAct(ctx, act, actStoreSkuList4Create); err == nil {
updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, actStoreSkuList4Create, model.SyncFlagNewMask)...)
} else {
errList.AddErr(err)

View File

@@ -160,7 +160,7 @@ func CreateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64,
}
// 买家取消(或申请取消)订单
func BuyerCancelOrder(ctx *jxcontext.Context, orderID int64) (canceled bool, err error) {
func BuyerCancelOrder(ctx *jxcontext.Context, orderID int64, reason string) (canceled bool, err error) {
order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(orderID), model.VendorIDJX)
if err == nil {
if order.Status < model.OrderStatusNew {
@@ -170,7 +170,8 @@ func BuyerCancelOrder(ctx *jxcontext.Context, orderID int64) (canceled bool, err
canceled = true
}
} else {
err = changeOrderStatus(utils.Int64ToStr(orderID), model.OrderStatusApplyCancel, fmt.Sprintf("用户%s主动取消", ctx.GetUserName()))
err = fmt.Errorf("暂不支持自行取消订单,请联系商家取消")
// err = changeOrderStatus(utils.Int64ToStr(orderID), model.OrderStatusApplyCancel, fmt.Sprintf("用户%s主动取消", ctx.GetUserName()))
}
}
return canceled, err

View File

@@ -295,7 +295,7 @@ func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgC
func (c *PurchaseHandler) UpdateStoreBoxFee(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (err error) {
boxFee, err := dao.GetSysConfigAsInt64(dao.GetDB(), model.ConfigSysMtwmBoxFee)
if err == nil {
if globals.EnableMtwmStoreWrite {
if globals.EnableMtwmStoreWrite && globals.IsProductEnv() {
err = api.MtwmAPI.PackagePriceUpdate(vendorStoreID, 1, int(boxFee))
}
}

View File

@@ -25,6 +25,7 @@ type ActController struct {
// @Param pricePercentage formData int true "活动价格比例"
// @Param advertising formData string true "广告语"
// @Param actStoreSkuList formData string true "活动门店商品信息"
// @Param overlapRule formData int false "活动重叠规则"
// @Param limitDaily formData int false "是否按日0-不限,>0限购单数秒杀需填"
// @Param limitUser formData int false "是否用户限购0-不限1-限购"
// @Param limitCount formData int false "限购件数 0-不限如账号限购、设备限购有一个为1则限购件数必须大于0的整数"
@@ -42,11 +43,12 @@ func (c *ActController) PreCreateAct() {
if err == nil {
if err = jxutils.Strings2Objs(params.VendorIDs, &vendorIDs, params.ActStoreSkuList, &actStoreSkuList); err == nil {
actObj := &model.Act{
Name: params.Name,
Type: params.Type,
LimitUser: params.LimitUser,
LimitDaily: params.LimitDaily,
LimitCount: params.LimitCount,
Name: params.Name,
Type: params.Type,
LimitUser: params.LimitUser,
LimitDaily: params.LimitDaily,
LimitCount: params.LimitCount,
OverlapRule: params.OverlapRule,
// Source:,
CreateType: model.ActCreateTypeAPI,
PricePercentage: params.PricePercentage,
@@ -74,6 +76,7 @@ func (c *ActController) PreCreateAct() {
// @Param pricePercentage formData int true "活动价格比例"
// @Param advertising formData string true "广告语"
// @Param actStoreSkuList formData string true "活动门店商品信息"
// @Param overlapRule formData int false "活动重叠规则"
// @Param limitDaily formData int false "是否按日0-不限,>0限购单数秒杀需填"
// @Param limitUser formData int false "是否用户限购0-不限1-限购"
// @Param limitCount formData int false "限购件数 0-不限如账号限购、设备限购有一个为1则限购件数必须大于0的整数"
@@ -92,11 +95,12 @@ func (c *ActController) CreateAct() {
if err == nil {
if err = jxutils.Strings2Objs(params.VendorIDs, &vendorIDs, params.ActStoreSkuList, &actStoreSkuList); err == nil {
actObj := &model.Act{
Name: params.Name,
Type: params.Type,
LimitUser: params.LimitUser,
LimitDaily: params.LimitDaily,
LimitCount: params.LimitCount,
Name: params.Name,
Type: params.Type,
LimitUser: params.LimitUser,
LimitDaily: params.LimitDaily,
LimitCount: params.LimitCount,
OverlapRule: params.OverlapRule,
// Source:,
CreateType: model.ActCreateTypeAPI,
PricePercentage: params.PricePercentage,

View File

@@ -571,7 +571,7 @@ func (c *StoreSkuController) FocusStoreSkusByExcel() {
// @Title 得到门店的分类列表
// @Description 得到门店的分类列表(按商品销量)
// @Param token header string true "认证token"
// @Param token header string false "认证token"
// @Param storeID query int true "门店ID"
// @Param parentID query int false "父分类id"
// @Success 200 {object} controllers.CallResult

View File

@@ -35,8 +35,7 @@ func (c *User2Controller) RegisterUser() {
)
if params.AuthToken != "" {
inAuthInfo, err = auth2.GetTokenInfo(params.AuthToken)
}
if params.Token != "" {
} else if params.Token != "" {
manTokenInfo, err = auth2.GetTokenInfo(params.Token)
}
if err == nil {

View File

@@ -46,6 +46,21 @@ func (c *JxOrderController) Pay4Order() {
})
}
// @Title 买家取消(或申请取消)订单
// @Description 买家取消(或申请取消)订单
// @Param token header string true "认证token"
// @Param vendorOrderID formData string true "订单ID"
// @Param reason formData string true "原因"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /BuyerCancelOrder [post]
func (c *JxOrderController) BuyerCancelOrder() {
c.callBuyerCancelOrder(func(params *tJxorderBuyerCancelOrderParams) (retVal interface{}, errCode string, err error) {
retVal, err = localjx.BuyerCancelOrder(params.Ctx, utils.Str2Int64(params.VendorOrderID), params.Reason)
return retVal, "", err
})
}
// @Title 查询网络打印机状态
// @Description 查询网络打印机状态
// @Param token header string true "认证token"

View File

@@ -56,6 +56,8 @@ 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.StoreSkuAct{})
orm.RegisterModel(&model.NewConfig{})
orm.RegisterModel(&model.CasbinRule{})

View File

@@ -583,6 +583,15 @@ func init() {
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:JxOrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:JxOrderController"],
beego.ControllerComments{
Method: "BuyerCancelOrder",
Router: `/BuyerCancelOrder`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:JxOrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:JxOrderController"],
beego.ControllerComments{
Method: "CreateOrder",