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

This commit is contained in:
苏尹岚
2019-12-13 16:38:35 +08:00
18 changed files with 121 additions and 85 deletions

View File

@@ -84,10 +84,11 @@ func syncCategories(ctx *jxcontext.Context, db *dao.DaoDB, parentTask tasksch.IT
}
func SyncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int, appOrgCodes []string, catIDs []int, isAsync bool) (hint string, err error) {
globals.SugarLogger.Debugf("SyncCategories catIDs:%v", catIDs)
globals.SugarLogger.Debugf("SyncCategories vendorIDs:%v, appOrgCodes:%v, catIDs:%v", vendorIDs, appOrgCodes, catIDs)
db := dao.GetDB()
catList, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, catIDs, true)
if err == nil && len(catList) > 0 {
// TODO 同一平台不同账号会有影响needSyncParentIDs暂不处理
var needSyncParentIDs []int
for _, cat := range catList {
if cat.Level == 2 && cat.ParentVendorCatID == "" {
@@ -128,7 +129,7 @@ func SyncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs
}
func SyncSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int, appOrgCodes []string, nameIDs, skuIDs []int, isAsync bool) (hint string, err error) {
globals.SugarLogger.Debugf("SyncSkus nameIDs:%v, skuIDs:%v", nameIDs, skuIDs)
globals.SugarLogger.Debugf("SyncSkus vendorIDs:%v, appOrgCodes:%v, nameIDs:%v, skuIDs:%v", vendorIDs, appOrgCodes, nameIDs, skuIDs)
db := dao.GetDB()
skuList, err := dao.GetSkusWithVendor(db, vendorIDs, appOrgCodes, nameIDs, skuIDs, true)
if err == nil && len(skuList) > 0 {

View File

@@ -409,6 +409,10 @@ func SplitSkuName(skuName string) (prefix, name, comment, specUnit, unit string,
return prefix, name, comment, specUnit, unit, specQuality
}
func GenFakeUPC(skuID int) string {
return fmt.Sprintf("%013d", int64(skuID)+6666000000000)
}
func MakeValidationMapFromSlice(validValues []string, flag int) map[string]int {
retVal := make(map[string]int)
for _, v := range validValues {

View File

@@ -2,18 +2,14 @@ package jxutils
import (
"testing"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
)
func TestGetActStoreSku(t *testing.T) {
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(dao.GetDB(), 0, []int{model.VendorIDMTWM}, []int{102046}, []int{25430, 30611},
utils.Str2Time("2019-07-27 13:29:57"), utils.Str2Time("2019-07-27 13:29:57"))
if err != nil {
t.Fatal(err)
}
storeSkuMap := jxutils.NewActStoreSkuMap(actStoreSkuList, false)
t.Log(storeSkuMap.GetActStoreSku(1, 2, 3))
// actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(dao.GetDB(), 0, []int{model.VendorIDMTWM}, []int{102046}, []int{25430, 30611},
// utils.Str2Time("2019-07-27 13:29:57"), utils.Str2Time("2019-07-27 13:29:57"))
// if err != nil {
// t.Fatal(err)
// }
// storeSkuMap := jxutils.NewActStoreSkuMap(actStoreSkuList, false)
// t.Log(storeSkuMap.GetActStoreSku(1, 2, 3))
}

View File

@@ -2,12 +2,10 @@ package jxutils
import (
"fmt"
"strings"
"testing"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
)
func TestSplitSlice(t *testing.T) {
@@ -109,22 +107,22 @@ func TestCalcPolygonAreaAutonavi(t *testing.T) {
// pointers := GetPolygonFromCircle(104.065702, 30.657488, 3000, 128)
// area := CalcPolygonAreaAutonavi(pointers)
// t.Logf("area:%f", area)
db := dao.GetDB()
storeList, err := dao.GetStoreList(db, nil, nil, "")
if err != nil {
t.Fatal(err)
}
// db := dao.GetDB()
// storeList, err := dao.GetStoreList(db, nil, nil, "")
// if err != nil {
// t.Fatal(err)
// }
strBuilder := &strings.Builder{}
strBuilder.WriteString("\n")
for _, v := range storeList {
if v.DeliveryRangeType == model.DeliveryRangeTypePolygon {
pointers := CoordinateStr2Points(v.DeliveryRange)
area1 := CalcPolygonAreaAutonavi(pointers)
strBuilder.WriteString(fmt.Sprintf("%d,%f\n", v.ID, area1))
}
}
t.Log(strBuilder.String())
// strBuilder := &strings.Builder{}
// strBuilder.WriteString("\n")
// for _, v := range storeList {
// if v.DeliveryRangeType == model.DeliveryRangeTypePolygon {
// pointers := CoordinateStr2Points(v.DeliveryRange)
// area1 := CalcPolygonAreaAutonavi(pointers)
// strBuilder.WriteString(fmt.Sprintf("%d,%f\n", v.ID, area1))
// }
// }
// t.Log(strBuilder.String())
}
func TestCaculateSkuPrice(t *testing.T) {

View File

@@ -284,3 +284,20 @@ func TestGetOneEmailFromStr(t *testing.T) {
}
}
}
func TestGenFakeUPC(t *testing.T) {
for _, v := range [][]string{
[]string{
"6666000000123",
"123",
},
[]string{
"6666007654321",
"7654321",
},
} {
if str := GenFakeUPC(int(utils.Str2Int64(v[1]))); str != v[0] {
t.Errorf("%s failed, result:%s, expect:%s", v[1], str, v[0])
}
}
}

View File

@@ -388,12 +388,6 @@ func (t *BaseTask) MarshalJSON() ([]byte, error) {
func (t *BaseTask) run(taskHandler func()) {
if t.GetStatus() == TaskStatusBegin {
utils.CallFuncAsync(func() {
defer func() {
if r := recover(); r != nil {
globals.SugarLogger.Errorf("panic in BaseTask.run task:%s, task detail:%s, r:%v", t.Name, utils.Format4Output(t, false), r)
}
}()
taskHandler()
task := t

View File

@@ -8,16 +8,17 @@ import (
"git.rosy.net.cn/jx-callback/globals"
)
type tStoreSkuSyncInfo2 struct {
StoreSkuSyncInfo
VendorPlaceCode string
}
type SkuCategoryWithVendor struct {
*model.SkuCategory
MapList []*model.ThingMap `json:"mapList"`
}
type SkuNamePlace struct {
model.Place
NameID int `orm:"column(name_id)" json:"nameID"`
SkuID int `orm:"column(sku_id)" json:"skuID"`
}
func GetSellCities(db *DaoDB, nameID int, vendorID int) (cities []*model.Place, err error) {
cities = []*model.Place{}
sql := `
@@ -211,7 +212,7 @@ func GetSkuCategoryWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string,
`
sqlParams = append(sqlParams, model.ThingTypeCategory, utils.DefaultTimeValue)
if mustDirty {
sql += " AND t1m.sync_status <> 0"
sql += " AND t1m.sync_status IS NOT NULL AND t1m.sync_status <> 0"
} else {
sql += " AND t1.deleted_at = ?"
sqlParams = append(sqlParams, utils.DefaultTimeValue)
@@ -253,8 +254,6 @@ func GetSkusWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string, nameIDs
IF(t12.resource_type IS NULL OR t12.resource_type <> ?, t2.img2, '') img2,
t2.desc_img,
t5.jd_code vendor_place_code,
t3.jd_category_id vendor_vendor_cat_id,
t3m.sync_status cat_sync_status,
@@ -281,15 +280,13 @@ func GetSkusWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string, nameIDs
LEFT JOIN sku_category t3 ON t3.id = t2.category_id
LEFT JOIN thing_map t3m ON t3m.thing_id = t3.id AND t3m.thing_type = ? AND t3m.deleted_at = ?
AND t3m.vendor_id = t1m.vendor_id AND t3m.vendor_org_code = t1m.vendor_org_code
LEFT JOIN sku_name_place_bind t4 ON t2.is_global = 0 AND t4.name_id = t1.name_id
LEFT JOIN place t5 ON t5.code = t4.place_code
LEFT JOIN data_resource t11 ON t11.main_url = t2.img
LEFT JOIN data_resource t12 ON t12.main_url = t2.img2
WHERE 1 = 1
`
sqlParams = append(sqlParams, model.ThingTypeCategory, utils.DefaultTimeValue)
if mustDirty {
sql += " AND t1m.sync_status <> 0"
sql += " AND t1m.sync_status IS NOT NULL AND t1m.sync_status <> 0"
} else {
sql += " AND t1.deleted_at = ?"
sqlParams = append(sqlParams, utils.DefaultTimeValue)
@@ -304,18 +301,47 @@ func GetSkusWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string, nameIDs
}
sql += " ORDER BY t1.seq"
var list []*tStoreSkuSyncInfo2
if err = GetRows(db, &list, sql, sqlParams...); err == nil {
skuMap := make(map[int]*StoreSkuSyncInfo)
for _, v := range list {
if skuMap[v.SkuID] == nil {
skuMap[v.SkuID] = &v.StoreSkuSyncInfo
skuList = append(skuList, &v.StoreSkuSyncInfo)
if err = GetRows(db, &skuList, sql, sqlParams...); err == nil {
skuPlaceList, err2 := GetSkuNamePlaces(db, nameIDs, skuIDs)
if err = err2; err == nil {
skuPlaceMap := make(map[int][]*SkuNamePlace)
for _, v := range skuPlaceList {
skuPlaceMap[v.SkuID] = append(skuPlaceMap[v.SkuID], v)
}
if !IsVendorThingIDEmpty(v.VendorPlaceCode) {
skuMap[v.SkuID].SellCities = append(skuMap[v.SkuID].SellCities, v.VendorPlaceCode)
for _, v := range skuList {
if v.IsGlobal == 0 {
for _, v2 := range skuPlaceMap[v.SkuID] {
// 京东到家
if v2.JdCode > 0 {
v.SellCities = append(v.SellCities, utils.Int2Str(v2.JdCode))
}
}
}
}
}
}
return skuList, err
}
func GetSkuNamePlaces(db *DaoDB, nameIDs, skuIDs []int) (skuPlaceList []*SkuNamePlace, err error) {
sql := `
SELECT
t4.*,
t2.id sku_id, t2.name_id
FROM sku t2
JOIN sku_name_place_bind t3 ON t3.name_id = t2.name_id
JOIN place t4 ON t4.code = t3.place_code
WHERE t2.deleted_at = ?
`
sqlParams := []interface{}{utils.DefaultTimeValue}
if len(nameIDs) > 0 {
sql += " AND t2.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")"
sqlParams = append(sqlParams, nameIDs)
}
if len(skuIDs) > 0 {
sql += " AND t2.id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
sqlParams = append(sqlParams, skuIDs)
}
err = GetRows(db, &skuPlaceList, sql, sqlParams...)
return skuPlaceList, err
}

View File

@@ -80,7 +80,7 @@ func (s *StoreDetail) GetPricePerentage(price int) (pricePercentage int) {
func getStoreDetail(db *DaoDB, storeID, vendorID int, vendorStoreID string) (storeDetail *StoreDetail, err error) {
sql := `
SELECT t1.*,
t2.vendor_store_id, t2.status vendor_status, t2.delivery_fee, t2.sync_status,
t2.vendor_store_id, t2.status vendor_status, t2.delivery_fee, t2.sync_status, t2.vendor_org_code,
t2.price_percentage, t2.auto_pickup, t2.delivery_type, t2.delivery_competition, t2.is_sync,
t3.value price_percentage_pack_str,
t4.value freight_deduction_pack_str,

View File

@@ -69,7 +69,7 @@ type StoreSkuSyncInfo struct {
// 平台相关的图片信息
Img string
Img2 string
DescImg string // 饿百是SkuName中的DescImgEbai
DescImg string
VendorVendorCatID int64 `orm:"column(vendor_vendor_cat_id)"` // 平台商品分类(叶子结点)
@@ -329,7 +329,7 @@ func newGetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty
}
sql += `
FROM store_sku_bind t1
LEFT JOIN store_map t14 ON t14.store_id = t1.store_id AND t14.vendor_id = ? AND t14.deleted_at = ?
JOIN store_map t14 ON t14.store_id = t1.store_id AND t14.vendor_id = ? AND t14.deleted_at = ?
LEFT JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? AND t2.status = ?
LEFT JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ?
LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ?

View File

@@ -325,7 +325,7 @@ func (c *PurchaseHandler) onActMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.C
if _, ok := actMap.Load(intPromotionID); !ok {
utils.CallFuncAsync(func() {
if !partner.CurActManager.IsVendorActExist(jxcontext.AdminCtx, promotionID, model.VendorIDJD) {
act, actStoreSkuList, err := getActFromJD(appKey2OrgCode(msg.AppKey), promotionID)
act, actStoreSkuList, err := getActFromJD(AppKey2OrgCode(msg.AppKey), promotionID)
if err == nil && len(actStoreSkuList) > 0 {
_, err = partner.CurActManager.CreateActFromVendor(jxcontext.AdminCtx, act, actStoreSkuList)
}

View File

@@ -6,21 +6,21 @@ import (
func OnOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
if CurPurchaseHandler != nil {
retVal = CurPurchaseHandler.OnOrderMsg(appKey2OrgCode(msg.AppKey), msg)
retVal = CurPurchaseHandler.OnOrderMsg(AppKey2OrgCode(msg.AppKey), msg)
}
return retVal
}
func OnWaybillMsg(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) {
if CurPurchaseHandler != nil {
retVal = CurPurchaseHandler.OnWaybillMsg(appKey2OrgCode(msg.AppKey), msg)
retVal = CurPurchaseHandler.OnWaybillMsg(AppKey2OrgCode(msg.AppKey), msg)
}
return retVal
}
func OnStoreMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
if CurPurchaseHandler != nil {
retVal = CurPurchaseHandler.OnStoreMsg(appKey2OrgCode(msg.AppKey), msg)
retVal = CurPurchaseHandler.OnStoreMsg(AppKey2OrgCode(msg.AppKey), msg)
}
return retVal
}

View File

@@ -18,7 +18,7 @@ func (p *PurchaseHandler) OnFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *j
// 京东正向/退款订单类型处理--存储
func (p *PurchaseHandler) onFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
var err error
a := GetAPIByAppKey(msg.AppKey)
a := getAPI(AppKey2OrgCode(msg.AppKey))
// if msg.StatusID == jdapi.OrderStatusPayFinishedSettle || msg.StatusID == jdapi.OrderStatusTipChanged || msg.StatusID == jdapi.OrderStatusSwitch2SelfSettle { // 如果是正向单
if msg.StatusID == jdapi.OrderStatusPayFinishedSettle || msg.StatusID == jdapi.OrderStatusTipChanged || msg.StatusID == jdapi.OrderStatusAdjustSettle || msg.StatusID == jdapi.OrderStatusSwitch2SelfSettle { // 如果是正向单
order, err2 := partner.CurOrderManager.LoadOrder(msg.BillID, model.VendorIDJD)

View File

@@ -23,6 +23,9 @@ func init() {
}
func getAPI(appOrgCode string) (apiObj *jdapi.API) {
if appOrgCode == "" {
globals.SugarLogger.Warnf("getAPI appOrgCode is empty")
}
return partner.CurAPIManager.GetAPI(model.VendorIDJD, appOrgCode).(*jdapi.API)
}
@@ -30,7 +33,7 @@ func GetAPI(appOrgCode string) (apiObj *jdapi.API) {
return getAPI(appOrgCode)
}
func appKey2OrgCode(appKey string) (vendorOrgCode string) {
func AppKey2OrgCode(appKey string) (vendorOrgCode string) {
apiList := partner.CurAPIManager.GetAppOrgCodeList(model.VendorIDJD)
for _, v := range apiList {
jdAPI := partner.CurAPIManager.GetAPI(model.VendorIDJD, v).(*jdapi.API)
@@ -42,22 +45,6 @@ func appKey2OrgCode(appKey string) (vendorOrgCode string) {
return vendorOrgCode
}
func GetAPIByAppKey(appKey string) (apiObj *jdapi.API) {
if appKey == "" {
apiObj = getAPI("")
} else {
apiList := partner.CurAPIManager.GetAppOrgCodeList(model.VendorIDJD)
for _, v := range apiList {
jdAPI := partner.CurAPIManager.GetAPI(model.VendorIDJD, v).(*jdapi.API)
if jdAPI.GetAppKey() == appKey {
apiObj = jdAPI
break
}
}
}
return apiObj
}
func (c *PurchaseHandler) GetVendorID() int {
return model.VendorIDJD
}

View File

@@ -12,6 +12,7 @@ import (
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
"github.com/astaxie/beego"
)
@@ -113,7 +114,7 @@ func (p *PurchaseHandler) ReorderCategories2(ctx *jxcontext.Context, vendorOrgCo
func (p *PurchaseHandler) getVendorCategories(level int, pid int64) (vendorCats []*model.SkuVendorCategory, err error) {
// 得到平台的分类,不需要指定分账号
cats, err := getAPI("").QueryChildCategoriesForOP(pid)
cats, err := api.Jd2API.QueryChildCategoriesForOP(pid)
if err != nil {
return nil, err
}
@@ -166,6 +167,10 @@ func skuInfo2Param(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (param *jd
Upc: sku.Upc,
Images: jxutils.BatchString2Slice(sku.Img, sku.Img2),
}
// 不为份的SKU如果没有设置upc自动生成一个假的
// if sku.Unit != model.SpecialUnit && param.Upc == "" {
// param.Upc = jxutils.GenFakeUPC(sku.SkuID)
// }
if param.CategoryID == 0 {
param.CategoryID = int64(getDefJdCategoryID())
}

View File

@@ -64,7 +64,7 @@ func (c *PurchaseHandler) callbackMsg2Waybill(msg *jdapi.CallbackDeliveryStatusM
StatusTime: utils.Str2Time(msg.DeliveryStatusTime),
Remark: msg.Remark,
VendorOrgCode: appKey2OrgCode(msg.AppKey),
VendorOrgCode: AppKey2OrgCode(msg.AppKey),
}
return retVal
}

View File

@@ -284,7 +284,9 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI
skus[0]["price"] = foodData["price"]
}
skus[0]["stock"] = stockCount2Mtwm(model.MaxStoreSkuStockQty)
skus[0]["upc"] = storeSku.Upc
if storeSku.Upc != "" {
skus[0]["upc"] = storeSku.Upc
}
if foodData["tag_id"] != nil {
skus[0]["weight"] = storeSku.Weight // weight字段仅限服饰鞋帽、美妆、日用品、母婴、生鲜果蔬、生活超市下的便利店/超市门店品类的商家使用
}

View File

@@ -23,7 +23,7 @@ func (c *DjswController) handleMsg(isNeedDecode bool, handler func(*jdapi.API, i
callbackMsg, mapData, callbackResponse := jdapi.GetCallbackMsg2(getUsefulRequest(c.Ctx))
globals.SugarLogger.Debug(utils.Format4Output(callbackMsg, true))
if callbackResponse == nil {
if jdAPI := jd.GetAPIByAppKey(callbackMsg.AppKey); jdAPI != nil {
if jdAPI := jd.GetAPI(jd.AppKey2OrgCode(callbackMsg.AppKey)); jdAPI != nil {
if callbackResponse = jdAPI.CheckCallbackValidation2(mapData, callbackMsg.Sign); callbackResponse == nil {
callbackResponse = handler(jdAPI, callbackMsg.Param)
}

View File

@@ -54,6 +54,8 @@ var (
Jd2OrgCode string
IsUseThingMap bool
OutputDebugMsgLevel int
)
func init() {
@@ -67,6 +69,10 @@ func init() {
}
func Init() {
if IsProductEnv(){
OutputDebugMsgLevel = 1
}
SugarLogger.Infof("globals RunMode=%s", beego.BConfig.RunMode)
ReallyCallPlatformAPI = (beego.BConfig.RunMode != "dev" && beego.BConfig.RunMode != "test")
ReallySendWeixinMsg = ReallyCallPlatformAPI && IsProductEnv()