Merge branch 'mark' of e.coding.net:rosydev/jx-callback into mark
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi"
|
"git.rosy.net.cn/baseapi"
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
@@ -18,17 +19,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
canWriteTolocal = false
|
canWriteTolocal = false
|
||||||
needStatistic = true
|
needStatistic = true
|
||||||
isFilterToBeCreateAndNotSale = true
|
isFilterToBeCreateAndNotSale = true
|
||||||
parallelCount = 5
|
parallelCount = 5
|
||||||
fileExt = ".xlsx"
|
fileExt = ".xlsx"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
diffFileName = map[bool]string {
|
diffFileName = map[bool]string{
|
||||||
true : "export/JXCSAndVendorSkuDiff",
|
true: "export/JXCSAndVendorSkuDiff",
|
||||||
false : "export/JXGYAndVendorSkuDiff",
|
false: "export/JXGYAndVendorSkuDiff",
|
||||||
}
|
}
|
||||||
vendorNameList = map[int]string{
|
vendorNameList = map[int]string{
|
||||||
model.VendorIDMTWM: model.VendorChineseNames[model.VendorIDMTWM],
|
model.VendorIDMTWM: model.VendorChineseNames[model.VendorIDMTWM],
|
||||||
@@ -86,7 +87,7 @@ type DiffData struct {
|
|||||||
SkuID string `json:"SkuID"`
|
SkuID string `json:"SkuID"`
|
||||||
SyncStatus string `json:"同步状态"`
|
SyncStatus string `json:"同步状态"`
|
||||||
ToBeCreate string `json:"待创建"`
|
ToBeCreate string `json:"待创建"`
|
||||||
ToBeDel string `json:"待删除"`
|
ToBeDel string `json:"待删除"`
|
||||||
JxSkuName string `json:"京西商品名"`
|
JxSkuName string `json:"京西商品名"`
|
||||||
VendorSkuName string `json:"平台商品名"`
|
VendorSkuName string `json:"平台商品名"`
|
||||||
JxStatus string `json:"京西可售状态"`
|
JxStatus string `json:"京西可售状态"`
|
||||||
@@ -94,11 +95,11 @@ type DiffData struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StatisticData struct {
|
type StatisticData struct {
|
||||||
JxVendorStatus string `json:"京西和平台商品状态"`
|
JxVendorStatus string `json:"京西和平台商品状态"`
|
||||||
ToBeCreate string `json:"待创建"`
|
ToBeCreate string `json:"待创建"`
|
||||||
JxSaleStatus string `json:"京西可售状态"`
|
JxSaleStatus string `json:"京西可售状态"`
|
||||||
Count string `json:"数量"`
|
Count string `json:"数量"`
|
||||||
Percent string `json:"占比"`
|
Percent string `json:"占比"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DiffDataLock) AppendData(vendorID int, diffData DiffData) {
|
func (d *DiffDataLock) AppendData(vendorID int, diffData DiffData) {
|
||||||
@@ -111,14 +112,6 @@ func (d *DiffDataLock) InitData() {
|
|||||||
d.diffDataMap = make(map[int][]DiffData)
|
d.diffDataMap = make(map[int][]DiffData)
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsMultiStore(vendorID int) bool {
|
|
||||||
if _, ok := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler); ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func InitMultiStoreData() {
|
func InitMultiStoreData() {
|
||||||
multiStoreAllSkuInfoMap = make(map[int]map[int]*partner.SkuNameInfo)
|
multiStoreAllSkuInfoMap = make(map[int]map[int]*partner.SkuNameInfo)
|
||||||
multiStoreAllSkuInfoList = make(map[int][]*partner.StoreSkuInfo)
|
multiStoreAllSkuInfoList = make(map[int][]*partner.StoreSkuInfo)
|
||||||
@@ -141,7 +134,7 @@ func GetMultiStoreAllSkuInfo(ctx *jxcontext.Context, vendorMap map[int]bool) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if IsMultiStore(vendorID) {
|
if partner.IsMultiStore(vendorID) {
|
||||||
multiHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler)
|
multiHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler)
|
||||||
allSkuNameInfoList, err := multiHandler.GetSkus(ctx, 0, "", "")
|
allSkuNameInfoList, err := multiHandler.GetSkus(ctx, 0, "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -344,7 +337,7 @@ func CheckSkuDiffBetweenJxAndVendor(ctx *jxcontext.Context, vendorIDList []int,
|
|||||||
vendorStoreID := utils.Interface2String(vendorListValue["vendorStoreID"])
|
vendorStoreID := utils.Interface2String(vendorListValue["vendorStoreID"])
|
||||||
baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor storeID:%d vendorID:%d vendorStoreID:%s vendorListValue:%v", storeID, vendorID, vendorStoreID, vendorListValue)
|
baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor storeID:%d vendorID:%d vendorStoreID:%s vendorListValue:%v", storeID, vendorID, vendorStoreID, vendorListValue)
|
||||||
|
|
||||||
if IsMultiStore(vendorID) {
|
if partner.IsMultiStore(vendorID) {
|
||||||
singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler)
|
singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler)
|
||||||
allSkuInfoList := GetMultiStoreAllSkuInfoList(vendorID)
|
allSkuInfoList := GetMultiStoreAllSkuInfoList(vendorID)
|
||||||
skuBareInfoList, err := singleStoreHandler.GetStoreSkusBareInfo(ctx, task, storeID, vendorStoreID, allSkuInfoList)
|
skuBareInfoList, err := singleStoreHandler.GetStoreSkusBareInfo(ctx, task, storeID, vendorStoreID, allSkuInfoList)
|
||||||
@@ -433,14 +426,14 @@ func AddStatisticSheet(sheetName string, data []DiffData) (sheet *excel.Obj2Exce
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for index, value := range count {
|
for index, value := range count {
|
||||||
percent[index] = float32(value * 100) / float32(totalCount)
|
percent[index] = float32(value*100) / float32(totalCount)
|
||||||
countStr := utils.Int2Str(value)
|
countStr := utils.Int2Str(value)
|
||||||
percentStr := fmt.Sprintf("%.2f%%", percent[index])
|
percentStr := fmt.Sprintf("%.2f%%", percent[index])
|
||||||
subStatisticData := statisticDataList[index]
|
subStatisticData := statisticDataList[index]
|
||||||
statisticData[index] = StatisticData{subStatisticData[0], subStatisticData[1], subStatisticData[2], countStr, percentStr}
|
statisticData[index] = StatisticData{subStatisticData[0], subStatisticData[1], subStatisticData[2], countStr, percentStr}
|
||||||
}
|
}
|
||||||
sheetName = sheetName + "统计"
|
sheetName = sheetName + "统计"
|
||||||
sheet = &excel.Obj2ExcelSheetConfig {
|
sheet = &excel.Obj2ExcelSheetConfig{
|
||||||
Title: sheetName,
|
Title: sheetName,
|
||||||
Data: statisticData,
|
Data: statisticData,
|
||||||
CaptionList: statisticTitleList,
|
CaptionList: statisticTitleList,
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ func Init() {
|
|||||||
ScheduleTimerFunc("UpdateActStatusByTime", func() {
|
ScheduleTimerFunc("UpdateActStatusByTime", func() {
|
||||||
dao.UpdateActStatusByTime(dao.GetDB(), time.Now().Add(-48*time.Hour))
|
dao.UpdateActStatusByTime(dao.GetDB(), time.Now().Add(-48*time.Hour))
|
||||||
}, updateActStatusTimeList)
|
}, updateActStatusTimeList)
|
||||||
|
ScheduleScoreStore()
|
||||||
}
|
}
|
||||||
ScheduleTimerFunc("AutoSaleStoreSku", func() {
|
ScheduleTimerFunc("AutoSaleStoreSku", func() {
|
||||||
cms.AutoSaleStoreSku(jxcontext.AdminCtx, nil, false)
|
cms.AutoSaleStoreSku(jxcontext.AdminCtx, nil, false)
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package misc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestStartOrEndOpStore(t *testing.T) {
|
func TestStartOrEndOpStore(t *testing.T) {
|
||||||
StartOrEndOpStore(1, true, 0, 0, false, true)
|
StartOrEndOpStore(jxcontext.AdminCtx, true, nil, nil, 0, 0, false, true)
|
||||||
}
|
}
|
||||||
|
|||||||
780
business/jxstore/misc/store_score.go
Normal file
780
business/jxstore/misc/store_score.go
Normal file
@@ -0,0 +1,780 @@
|
|||||||
|
package misc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"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/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/refutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
EnableScheduleScoreStore = true
|
||||||
|
ParallelCount = 1
|
||||||
|
|
||||||
|
GoldMedalScore = 90
|
||||||
|
SilverMedalScore = 80
|
||||||
|
BronzeMedalScore = 70
|
||||||
|
GoldMedalLevel = 1
|
||||||
|
SilverMedalLevel = 2
|
||||||
|
BronzeMedalLevel = 3
|
||||||
|
|
||||||
|
ItemTotalScore = 10
|
||||||
|
|
||||||
|
StoreOpenTimeNormalTime = 12.0 //小时
|
||||||
|
SaleSkuNormalCount = 1000 //数量
|
||||||
|
SaleSkuScorePerUnit = float64(ItemTotalScore) / SaleSkuNormalCount //分数
|
||||||
|
PromotionSkuNormalCount = 20 //数量
|
||||||
|
AveragePickupTimeNormalTime = 10.0 //分钟
|
||||||
|
BadCommentOrderNormalRatio = 0.2 //百分比
|
||||||
|
UnfinishOrderNormalRatio = 1.0 //百分比
|
||||||
|
AbsentGoodsOrderNormalRatio = 1.0 //百分比
|
||||||
|
StoreRangeGoodRadius = 2.0 //千米
|
||||||
|
StoreRangeBadRadius = 1.0 //千米
|
||||||
|
SaleSkuPriceRatio = 90 //千米
|
||||||
|
SaleSkuCheckRange = 5.0 //千米
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
scoreStoreTimeList = []string{
|
||||||
|
"22:00:00",
|
||||||
|
}
|
||||||
|
scoreStoreCheckTimeEnd = "23:30:00"
|
||||||
|
fullVendorList = map[int]bool{
|
||||||
|
model.VendorIDJD: true,
|
||||||
|
model.VendorIDMTWM: true,
|
||||||
|
model.VendorIDEBAI: true,
|
||||||
|
}
|
||||||
|
storeScoreFieldName = []string{
|
||||||
|
model.FieldStoreOpenTime,
|
||||||
|
model.FieldSaleSkuCount,
|
||||||
|
model.FieldAveragePickupTime,
|
||||||
|
model.FieldBadCommentOrder,
|
||||||
|
model.FieldUnfinishOrder,
|
||||||
|
model.FieldAbsentGoodsOrder,
|
||||||
|
model.FieldPromotionSku,
|
||||||
|
model.FieldFullVendor,
|
||||||
|
model.FieldStoreRange,
|
||||||
|
model.FieldSaleSkuPrice,
|
||||||
|
}
|
||||||
|
|
||||||
|
storeScoreDataWrapper StoreScoreDataWrapper
|
||||||
|
allStoreSkusWrapper AllStoreSkusWrapper
|
||||||
|
scoreDate time.Time
|
||||||
|
isScoring bool
|
||||||
|
)
|
||||||
|
|
||||||
|
type AllStoreSkusWrapper struct {
|
||||||
|
allStoreSkus map[int]map[int]int
|
||||||
|
locker sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AllStoreSkusWrapper) InitData() {
|
||||||
|
a.allStoreSkus = make(map[int]map[int]int)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AllStoreSkusWrapper) ClearData() {
|
||||||
|
a.allStoreSkus = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AllStoreSkusWrapper) SetData(storeID int, skuMapData map[int]int) {
|
||||||
|
a.locker.Lock()
|
||||||
|
defer a.locker.Unlock()
|
||||||
|
a.allStoreSkus[storeID] = skuMapData
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AllStoreSkusWrapper) GetData(storeID int) map[int]int {
|
||||||
|
a.locker.RLock()
|
||||||
|
defer a.locker.RUnlock()
|
||||||
|
return a.allStoreSkus[storeID]
|
||||||
|
}
|
||||||
|
|
||||||
|
type StoreScoreDataWrapper struct {
|
||||||
|
storeScoreData map[int]*model.StoreScore
|
||||||
|
dailyBadCommentOrderCount map[int]int
|
||||||
|
dailyUnFinishOrderCount map[int]int
|
||||||
|
dailyFinishOrderCount map[int]int
|
||||||
|
dailyAbsentGoodsOrderCount map[int]int
|
||||||
|
locker sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StoreScoreDataWrapper) InitData() {
|
||||||
|
s.storeScoreData = make(map[int]*model.StoreScore)
|
||||||
|
s.dailyBadCommentOrderCount = make(map[int]int)
|
||||||
|
s.dailyUnFinishOrderCount = make(map[int]int)
|
||||||
|
s.dailyFinishOrderCount = make(map[int]int)
|
||||||
|
s.dailyAbsentGoodsOrderCount = make(map[int]int)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StoreScoreDataWrapper) ClearData() {
|
||||||
|
s.storeScoreData = nil
|
||||||
|
s.dailyBadCommentOrderCount = nil
|
||||||
|
s.dailyUnFinishOrderCount = nil
|
||||||
|
s.dailyFinishOrderCount = nil
|
||||||
|
s.dailyAbsentGoodsOrderCount = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StoreScoreDataWrapper) SetData(storeID int, valueName string, value int) {
|
||||||
|
s.locker.Lock()
|
||||||
|
defer s.locker.Unlock()
|
||||||
|
data := s.storeScoreData[storeID]
|
||||||
|
if data == nil {
|
||||||
|
data = &model.StoreScore{}
|
||||||
|
data.StoreID = storeID
|
||||||
|
data.ScoreDate = scoreDate
|
||||||
|
s.storeScoreData[storeID] = data
|
||||||
|
}
|
||||||
|
valueInfo := reflect.ValueOf(data).Elem()
|
||||||
|
valueInfo.FieldByName(valueName).SetInt(int64(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StoreScoreDataWrapper) SetDailyBadCommentOrderCount(storeCountList []*model.StoreCount) {
|
||||||
|
s.locker.Lock()
|
||||||
|
defer s.locker.Unlock()
|
||||||
|
for _, value := range storeCountList {
|
||||||
|
s.dailyBadCommentOrderCount[value.StoreID] = value.Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StoreScoreDataWrapper) GetDailyBadCommentOrderCount(storeID int) int {
|
||||||
|
s.locker.RLock()
|
||||||
|
defer s.locker.RUnlock()
|
||||||
|
if count, ok := s.dailyBadCommentOrderCount[storeID]; ok {
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StoreScoreDataWrapper) SetDailyUnFinishOrderCount(storeCountList []*model.StoreCount) {
|
||||||
|
for _, value := range storeCountList {
|
||||||
|
s.dailyUnFinishOrderCount[value.StoreID] = value.Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StoreScoreDataWrapper) GetDailyUnFinishOrderCount(storeID int) int {
|
||||||
|
s.locker.RLock()
|
||||||
|
defer s.locker.RUnlock()
|
||||||
|
if count, ok := s.dailyUnFinishOrderCount[storeID]; ok {
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StoreScoreDataWrapper) SetDailyFinishOrderCount(storeCountList []*model.StoreCount) {
|
||||||
|
for _, value := range storeCountList {
|
||||||
|
s.dailyFinishOrderCount[value.StoreID] = value.Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StoreScoreDataWrapper) GetDailyFinishOrderCount(storeID int) int {
|
||||||
|
s.locker.RLock()
|
||||||
|
defer s.locker.RUnlock()
|
||||||
|
if count, ok := s.dailyFinishOrderCount[storeID]; ok {
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StoreScoreDataWrapper) SetDailyAbsentGoodsOrderCount(storeCountList []*model.StoreCount) {
|
||||||
|
for _, value := range storeCountList {
|
||||||
|
s.dailyAbsentGoodsOrderCount[value.StoreID] = value.Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StoreScoreDataWrapper) GetDailyAbsentGoodsOrderCount(storeID int) int {
|
||||||
|
s.locker.RLock()
|
||||||
|
defer s.locker.RUnlock()
|
||||||
|
if count, ok := s.dailyAbsentGoodsOrderCount[storeID]; ok {
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StoreScoreDataWrapper) InsertStoreScore() {
|
||||||
|
for _, value := range s.storeScoreData {
|
||||||
|
dao.InsertStoreScore(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//得到所有门店的可售商品(优化内存,只存商品的价格)
|
||||||
|
func GetAllStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeList []*cms.StoreExt) {
|
||||||
|
allStoreSkusWrapper.InitData()
|
||||||
|
taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
storeInfo := batchItemList[0].(*cms.StoreExt)
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
jxSkuInfoData, _ := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, map[string]interface{}{}, 0, -1)
|
||||||
|
jxSkuPriceMapData := make(map[int]int)
|
||||||
|
for _, value := range jxSkuInfoData.SkuNames {
|
||||||
|
for _, skuInfo := range value.Skus2 {
|
||||||
|
saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus)
|
||||||
|
if saleStatus == model.SkuStatusNormal {
|
||||||
|
jxSkuPriceMapData[skuInfo.SkuID] = skuInfo.BindPrice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allStoreSkusWrapper.SetData(storeID, jxSkuPriceMapData)
|
||||||
|
return retVal, err
|
||||||
|
}
|
||||||
|
taskParallel := tasksch.NewParallelTask("得到所有门店商品", tasksch.NewParallelConfig().SetParallelCount(ParallelCount), ctx, taskFunc, storeList)
|
||||||
|
tasksch.HandleTask(taskParallel, parentTask, true).Run()
|
||||||
|
taskParallel.GetResult(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetOpenTime(opTimeList []int16) (opTime float64) {
|
||||||
|
opTime = 0
|
||||||
|
for index, _ := range opTimeList {
|
||||||
|
if index%2 == 1 {
|
||||||
|
endTime := opTimeList[index]
|
||||||
|
startTime := opTimeList[index-1]
|
||||||
|
diffHour := float64(endTime/100 - startTime/100)
|
||||||
|
diffMin := float64(endTime%100-startTime%100) / 60
|
||||||
|
opTime += diffHour + diffMin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return opTime
|
||||||
|
}
|
||||||
|
|
||||||
|
//营业时间12小时及以上满分,总分10分,每少一个小时扣1分
|
||||||
|
func ScoreStoreOpenTime(storeInfo *cms.StoreExt) {
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
storeStatus := storeInfo.Status
|
||||||
|
isStoreOpen := storeStatus == model.StoreStatusOpened
|
||||||
|
finalScore := 0
|
||||||
|
if isStoreOpen {
|
||||||
|
for _, storeMap := range storeInfo.StoreMaps {
|
||||||
|
isSyncStoreSku := int(utils.MustInterface2Int64(storeMap["isSync"]))
|
||||||
|
vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"]))
|
||||||
|
isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened
|
||||||
|
opTimeList := storeInfo.GetOpTimeList()
|
||||||
|
if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen && isSyncStoreSku != 0 {
|
||||||
|
opTime := GetOpenTime(opTimeList)
|
||||||
|
if opTime >= StoreOpenTimeNormalTime {
|
||||||
|
finalScore = ItemTotalScore
|
||||||
|
} else {
|
||||||
|
decScore := int(math.Round(StoreOpenTimeNormalTime - opTime))
|
||||||
|
finalScore = ItemTotalScore - decScore
|
||||||
|
if finalScore < 0 {
|
||||||
|
finalScore = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeScoreDataWrapper.SetData(storeID, model.FieldStoreOpenTime, finalScore)
|
||||||
|
}
|
||||||
|
|
||||||
|
//可售商品数量大于1000,总分10分,按比例扣
|
||||||
|
func ScoreSaleSkuCount(storeInfo *cms.StoreExt) {
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
skusMapData := allStoreSkusWrapper.GetData(storeID)
|
||||||
|
finalScore := 0
|
||||||
|
if len(skusMapData) > 0 {
|
||||||
|
saleSkuCount := len(skusMapData)
|
||||||
|
finalScore = int(math.Round(float64(saleSkuCount) * SaleSkuScorePerUnit))
|
||||||
|
if finalScore > ItemTotalScore {
|
||||||
|
finalScore = ItemTotalScore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuCount, finalScore)
|
||||||
|
}
|
||||||
|
|
||||||
|
//平均捡货时间小于等于拣货截止时间为10分满分,每超出1分钟,减1分
|
||||||
|
func ScoreAveragePickupTime(storeInfo *cms.StoreExt) {
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
db := dao.GetDB()
|
||||||
|
orderList, err := dao.GetDailyFinishOrderList(db, storeID, scoreDate)
|
||||||
|
orderListCount := len(orderList)
|
||||||
|
finalScore := 0
|
||||||
|
if err == nil && orderListCount > 0 {
|
||||||
|
totalScore := 0
|
||||||
|
for _, value := range orderList {
|
||||||
|
statusTime := value.StatusTime.Unix()
|
||||||
|
pickDeadline := value.PickDeadline.Unix()
|
||||||
|
if statusTime <= pickDeadline {
|
||||||
|
totalScore += ItemTotalScore
|
||||||
|
} else {
|
||||||
|
decScore := int(math.Round(float64(statusTime-pickDeadline) / 60))
|
||||||
|
tempScore := ItemTotalScore - decScore
|
||||||
|
if tempScore < 0 {
|
||||||
|
tempScore = 0
|
||||||
|
}
|
||||||
|
totalScore += tempScore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finalScore = totalScore / orderListCount
|
||||||
|
}
|
||||||
|
storeScoreDataWrapper.SetData(storeID, model.FieldAveragePickupTime, finalScore)
|
||||||
|
}
|
||||||
|
|
||||||
|
//差评订单和完成订单比例小于0.2%,得满分10分,每增加0.1%减1分
|
||||||
|
func ScoreBadCommentOrder(storeInfo *cms.StoreExt) {
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
badCommentOrderCount := storeScoreDataWrapper.GetDailyBadCommentOrderCount(storeID)
|
||||||
|
finishOrderCount := storeScoreDataWrapper.GetDailyFinishOrderCount(storeID)
|
||||||
|
finalScore := 0
|
||||||
|
if finishOrderCount > 0 {
|
||||||
|
badCommentOrderRatio := float64(badCommentOrderCount) * 100 / float64(finishOrderCount)
|
||||||
|
if badCommentOrderRatio <= BadCommentOrderNormalRatio {
|
||||||
|
finalScore = ItemTotalScore
|
||||||
|
} else {
|
||||||
|
decScore := int(math.Round((badCommentOrderRatio - BadCommentOrderNormalRatio) / 0.1))
|
||||||
|
finalScore = ItemTotalScore - decScore
|
||||||
|
if finalScore < 0 {
|
||||||
|
finalScore = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeScoreDataWrapper.SetData(storeID, model.FieldBadCommentOrder, finalScore)
|
||||||
|
}
|
||||||
|
|
||||||
|
//未完成订单和完成订单比小于1%,得满分10分,比例每增加5%,分数减1
|
||||||
|
func ScoreUnfinishOrder(storeInfo *cms.StoreExt) {
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
unFinishOrderCount := storeScoreDataWrapper.GetDailyUnFinishOrderCount(storeID)
|
||||||
|
finishOrderCount := storeScoreDataWrapper.GetDailyFinishOrderCount(storeID)
|
||||||
|
finalScore := 0
|
||||||
|
if finishOrderCount > 0 {
|
||||||
|
unfinishOrderRatio := float64(unFinishOrderCount) * 100 / float64(finishOrderCount)
|
||||||
|
if unfinishOrderRatio <= UnfinishOrderNormalRatio {
|
||||||
|
finalScore = ItemTotalScore
|
||||||
|
} else {
|
||||||
|
decScore := int(math.Round((unfinishOrderRatio - UnfinishOrderNormalRatio) / 5))
|
||||||
|
finalScore = ItemTotalScore - decScore
|
||||||
|
if finalScore < 0 {
|
||||||
|
finalScore = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeScoreDataWrapper.SetData(storeID, model.FieldUnfinishOrder, finalScore)
|
||||||
|
}
|
||||||
|
|
||||||
|
//缺货订单和完成订单比小于1%得10分,比例每增加0.1%减1分
|
||||||
|
func ScoreAbsentGoodsOrder(storeInfo *cms.StoreExt) {
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
absentGoodsOrderCount := storeScoreDataWrapper.GetDailyAbsentGoodsOrderCount(storeID)
|
||||||
|
finishOrderCount := storeScoreDataWrapper.GetDailyFinishOrderCount(storeID)
|
||||||
|
finalScore := 0
|
||||||
|
if finishOrderCount > 0 {
|
||||||
|
absentGoodsOrderRatio := float64(absentGoodsOrderCount) * 100 / float64(finishOrderCount)
|
||||||
|
if absentGoodsOrderRatio <= AbsentGoodsOrderNormalRatio {
|
||||||
|
finalScore = ItemTotalScore
|
||||||
|
} else {
|
||||||
|
decScore := int(math.Round((absentGoodsOrderRatio - AbsentGoodsOrderNormalRatio) / 0.1))
|
||||||
|
finalScore = ItemTotalScore - decScore
|
||||||
|
if finalScore < 0 {
|
||||||
|
finalScore = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeScoreDataWrapper.SetData(storeID, model.FieldAbsentGoodsOrder, finalScore)
|
||||||
|
}
|
||||||
|
|
||||||
|
//促销品数量20个以上为满分10分,每少2个扣1分
|
||||||
|
func ScorePromotionSku(storeInfo *cms.StoreExt) {
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
db := dao.GetDB()
|
||||||
|
beginTime := time.Now()
|
||||||
|
endTime := time.Now()
|
||||||
|
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, -1, nil, []int{storeID}, nil, beginTime, endTime)
|
||||||
|
finalScore := 0
|
||||||
|
if err == nil && len(actStoreSkuList) > 0 {
|
||||||
|
actStoreSkuMap := make(map[int]int)
|
||||||
|
for _, value := range actStoreSkuList {
|
||||||
|
if value.Type != model.ActSkuFake {
|
||||||
|
actStoreSkuMap[value.SkuID] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
promotionSkuCount := len(actStoreSkuMap)
|
||||||
|
if promotionSkuCount >= PromotionSkuNormalCount {
|
||||||
|
finalScore = ItemTotalScore
|
||||||
|
} else {
|
||||||
|
decScore := (PromotionSkuNormalCount - promotionSkuCount) / 2
|
||||||
|
finalScore = ItemTotalScore - decScore
|
||||||
|
if finalScore < 0 {
|
||||||
|
finalScore = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeScoreDataWrapper.SetData(storeID, model.FieldPromotionSku, finalScore)
|
||||||
|
}
|
||||||
|
|
||||||
|
//经营全平台满分10分,每少一个平台扣2分(一个平台没有得0分)
|
||||||
|
func ScoreFullVendor(storeInfo *cms.StoreExt) {
|
||||||
|
fullVendorCount := len(fullVendorList)
|
||||||
|
finalScore := 0
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
storeStatus := storeInfo.Status
|
||||||
|
isStoreOpen := storeStatus == model.StoreStatusOpened
|
||||||
|
count := 0
|
||||||
|
for _, storeMap := range storeInfo.StoreMaps {
|
||||||
|
isSyncStoreSku := int(utils.MustInterface2Int64(storeMap["isSync"]))
|
||||||
|
vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"]))
|
||||||
|
isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened
|
||||||
|
opTimeList := storeInfo.GetOpTimeList()
|
||||||
|
if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen && isSyncStoreSku != 0 {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
if count == fullVendorCount {
|
||||||
|
finalScore = ItemTotalScore
|
||||||
|
} else {
|
||||||
|
decScore := (fullVendorCount - count) * 2
|
||||||
|
finalScore = ItemTotalScore - decScore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeScoreDataWrapper.SetData(storeID, model.FieldFullVendor, finalScore)
|
||||||
|
}
|
||||||
|
|
||||||
|
//经营范围面积大于半径2km的圆得满分10分,低于1km得分0
|
||||||
|
func ScoreStoreRange(storeInfo *cms.StoreExt) {
|
||||||
|
finalScore := 0
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
if storeInfo.DeliveryRangeType == model.DeliveryRangeTypePolygon {
|
||||||
|
if storeInfo.DeliveryRange != "" {
|
||||||
|
points := jxutils.CoordinateStr2Points(storeInfo.DeliveryRange)
|
||||||
|
area := jxutils.CalcPolygonAreaAutonavi(points)
|
||||||
|
goodArea := math.Pi * StoreRangeGoodRadius * StoreRangeGoodRadius
|
||||||
|
badArea := math.Pi * StoreRangeBadRadius * StoreRangeBadRadius
|
||||||
|
if area >= goodArea {
|
||||||
|
finalScore = ItemTotalScore
|
||||||
|
} else if area <= badArea {
|
||||||
|
finalScore = 0
|
||||||
|
} else {
|
||||||
|
diff := goodArea - area
|
||||||
|
ratio := float64(ItemTotalScore) / (goodArea - badArea)
|
||||||
|
finalScore = ItemTotalScore - int(math.Round(diff*ratio))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if storeInfo.DeliveryRangeType == model.DeliveryRangeTypeRadius {
|
||||||
|
deliveryRadius := utils.Str2Float64WithDefault(storeInfo.DeliveryRange, 0) / 1000
|
||||||
|
if deliveryRadius >= StoreRangeGoodRadius {
|
||||||
|
finalScore = ItemTotalScore
|
||||||
|
} else if deliveryRadius <= StoreRangeBadRadius {
|
||||||
|
finalScore = 0
|
||||||
|
} else {
|
||||||
|
diff := StoreRangeGoodRadius - deliveryRadius
|
||||||
|
ratio := float64(ItemTotalScore) / (StoreRangeGoodRadius - StoreRangeBadRadius)
|
||||||
|
finalScore = ItemTotalScore - int(math.Round(diff*ratio))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeScoreDataWrapper.SetData(storeID, model.FieldStoreRange, finalScore)
|
||||||
|
}
|
||||||
|
|
||||||
|
//得到距离某个门店多少KM内的所有门店信息
|
||||||
|
func GetRangeStoreList(storeID int, lng, lat, checkRange float64, storeList []*cms.StoreExt) (outStoreList []*cms.StoreExt) {
|
||||||
|
for _, storeInfo := range storeList {
|
||||||
|
if storeInfo.ID == storeID {
|
||||||
|
outStoreList = append(outStoreList, storeInfo)
|
||||||
|
} else {
|
||||||
|
distance := jxutils.EarthDistance(lng, lat, storeInfo.FloatLng, storeInfo.FloatLat)
|
||||||
|
if distance <= checkRange {
|
||||||
|
outStoreList = append(outStoreList, storeInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return outStoreList
|
||||||
|
}
|
||||||
|
|
||||||
|
//得到给定门店列表里的同一SkuID商品的平均价格
|
||||||
|
func GetStoreSkusAveragePrice(storeList []*cms.StoreExt) map[int]int {
|
||||||
|
skusTotalPrice := make(map[int]int)
|
||||||
|
skusCount := make(map[int]int)
|
||||||
|
skusAveragePrice := make(map[int]int)
|
||||||
|
for _, storeInfo := range storeList {
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
storeSkuMapData := allStoreSkusWrapper.GetData(storeID)
|
||||||
|
for skuID, skuPrice := range storeSkuMapData {
|
||||||
|
skusTotalPrice[skuID] += skuPrice
|
||||||
|
skusCount[skuID]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for id, totalPrice := range skusTotalPrice {
|
||||||
|
skusAveragePrice[id] = int(math.Round(float64(totalPrice) / float64(skusCount[id])))
|
||||||
|
}
|
||||||
|
return skusAveragePrice
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSkusCountLessEqualAvgPrice(storeID int, skusAveragePrice map[int]int) (count int) {
|
||||||
|
storeSkuMapData := allStoreSkusWrapper.GetData(storeID)
|
||||||
|
for skuID, skuPrice := range storeSkuMapData {
|
||||||
|
skuAvgPrice := skusAveragePrice[skuID]
|
||||||
|
if skuPrice <= skuAvgPrice {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
//可售商品价格在附近5km内门店比较,价格低于等于平均值的商品数占90%以上满分10分,比例每降低10%减1分,100%超标得0分
|
||||||
|
func ScoreSaleSkuPrice(storeInfo *cms.StoreExt, storeList []*cms.StoreExt) {
|
||||||
|
finalScore := 0
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
totalCount := len(allStoreSkusWrapper.GetData(storeID))
|
||||||
|
if totalCount > 0 {
|
||||||
|
rangeStoreList := GetRangeStoreList(storeID, storeInfo.FloatLng, storeInfo.FloatLat, SaleSkuCheckRange, storeList)
|
||||||
|
skusAveragePrice := GetStoreSkusAveragePrice(rangeStoreList)
|
||||||
|
count := GetSkusCountLessEqualAvgPrice(storeID, skusAveragePrice)
|
||||||
|
if count > 0 {
|
||||||
|
ratio := int(math.Round(float64(count) * 100 / float64(totalCount)))
|
||||||
|
if ratio >= SaleSkuPriceRatio {
|
||||||
|
finalScore = ItemTotalScore
|
||||||
|
} else {
|
||||||
|
decScore := (SaleSkuPriceRatio - ratio) / 10
|
||||||
|
finalScore = ItemTotalScore - decScore
|
||||||
|
if finalScore < 0 {
|
||||||
|
finalScore = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuPrice, finalScore)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFilterStoreListEx(storeList []*cms.StoreExt, storeIDMap map[int]int) (outStoreList []*cms.StoreExt) {
|
||||||
|
for _, storeInfo := range storeList {
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
if len(storeIDMap) > 0 {
|
||||||
|
if _, ok := storeIDMap[storeID]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var tempStoreMaps []map[string]interface{}
|
||||||
|
for _, vendorStoreInfo := range storeInfo.StoreMaps {
|
||||||
|
vendorID := int(utils.MustInterface2Int64(vendorStoreInfo["vendorID"]))
|
||||||
|
if _, ok := fullVendorList[vendorID]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tempStoreMaps = append(tempStoreMaps, vendorStoreInfo)
|
||||||
|
}
|
||||||
|
if len(tempStoreMaps) > 0 {
|
||||||
|
storeInfo.StoreMaps = tempStoreMaps
|
||||||
|
outStoreList = append(outStoreList, storeInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return outStoreList
|
||||||
|
}
|
||||||
|
|
||||||
|
func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, err error) {
|
||||||
|
isScoring = true
|
||||||
|
scoreDate = utils.GetCurDate()
|
||||||
|
var storeList []*cms.StoreExt
|
||||||
|
taskCount := 5
|
||||||
|
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||||
|
switch step {
|
||||||
|
case 0:
|
||||||
|
baseapi.SugarLogger.Debugf("ScoreStore step0 begin")
|
||||||
|
storeScoreDataWrapper.InitData()
|
||||||
|
storeList, err = GetStoreList(ctx)
|
||||||
|
storeIDMap := jxutils.IntList2Map(storeIDList)
|
||||||
|
storeList = GetFilterStoreListEx(storeList, storeIDMap)
|
||||||
|
baseapi.SugarLogger.Debugf("ScoreStore step0 end")
|
||||||
|
case 1:
|
||||||
|
baseapi.SugarLogger.Debugf("ScoreStore step1 begin")
|
||||||
|
GetAllStoreSkus(ctx, task, storeList)
|
||||||
|
baseapi.SugarLogger.Debugf("ScoreStore step1 end")
|
||||||
|
case 2:
|
||||||
|
db := dao.GetDB()
|
||||||
|
storeCountList, _ := dao.GetDailyBadCommentOrderCount(db, scoreDate)
|
||||||
|
storeScoreDataWrapper.SetDailyBadCommentOrderCount(storeCountList)
|
||||||
|
storeCountList, _ = dao.GetDailyUnFinishOrderCount(db, scoreDate)
|
||||||
|
storeScoreDataWrapper.SetDailyUnFinishOrderCount(storeCountList)
|
||||||
|
storeCountList, _ = dao.GetDailyFinishOrderCount(db, scoreDate)
|
||||||
|
storeScoreDataWrapper.SetDailyFinishOrderCount(storeCountList)
|
||||||
|
storeCountList, _ = dao.GetDailyAbsentGoodsOrderCount(db, scoreDate)
|
||||||
|
storeScoreDataWrapper.SetDailyAbsentGoodsOrderCount(storeCountList)
|
||||||
|
case 3:
|
||||||
|
baseapi.SugarLogger.Debugf("ScoreStore step2 begin")
|
||||||
|
taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
storeInfo := batchItemList[0].(*cms.StoreExt)
|
||||||
|
storeID := storeInfo.ID
|
||||||
|
baseapi.SugarLogger.Debugf("Begin store id:%d", storeID)
|
||||||
|
ScoreStoreOpenTime(storeInfo)
|
||||||
|
ScoreSaleSkuCount(storeInfo)
|
||||||
|
ScoreAveragePickupTime(storeInfo)
|
||||||
|
ScoreBadCommentOrder(storeInfo)
|
||||||
|
ScoreUnfinishOrder(storeInfo)
|
||||||
|
ScoreAbsentGoodsOrder(storeInfo)
|
||||||
|
ScorePromotionSku(storeInfo)
|
||||||
|
ScoreFullVendor(storeInfo)
|
||||||
|
ScoreStoreRange(storeInfo)
|
||||||
|
ScoreSaleSkuPrice(storeInfo, storeList)
|
||||||
|
baseapi.SugarLogger.Debugf("End store id:%d", storeID)
|
||||||
|
return retVal, err
|
||||||
|
}
|
||||||
|
taskParallel := tasksch.NewParallelTask("计算门店得分", tasksch.NewParallelConfig().SetParallelCount(ParallelCount), ctx, taskFunc, storeList)
|
||||||
|
tasksch.HandleTask(taskParallel, task, true).Run()
|
||||||
|
taskParallel.GetResult(0)
|
||||||
|
_, err = taskParallel.GetResult(0)
|
||||||
|
if err != nil {
|
||||||
|
baseapi.SugarLogger.Debugf("ScoreStore taskParallel error:%v", err)
|
||||||
|
}
|
||||||
|
baseapi.SugarLogger.Debugf("ScoreStore step2 end")
|
||||||
|
case 4:
|
||||||
|
baseapi.SugarLogger.Debugf("ScoreStore step3 begin")
|
||||||
|
storeScoreDataWrapper.InsertStoreScore()
|
||||||
|
storeScoreDataWrapper.ClearData()
|
||||||
|
allStoreSkusWrapper.ClearData()
|
||||||
|
baseapi.SugarLogger.Debugf("ScoreStore step3 end")
|
||||||
|
isScoring = false
|
||||||
|
}
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
taskSeq := tasksch.NewSeqTask("门店评分-序列任务", ctx, taskSeqFunc, taskCount)
|
||||||
|
tasksch.HandleTask(taskSeq, nil, true).Run()
|
||||||
|
|
||||||
|
return retVal, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ScheduleScoreStore() {
|
||||||
|
if EnableScheduleScoreStore {
|
||||||
|
ScheduleTimerFunc("ScheduleScoreStore", func() {
|
||||||
|
if !isScoring {
|
||||||
|
ScoreStore(jxcontext.AdminCtx, nil)
|
||||||
|
}
|
||||||
|
}, scoreStoreTimeList)
|
||||||
|
CheckScoreStore()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckScoreStore() {
|
||||||
|
if !isScoring {
|
||||||
|
curTime := time.Now()
|
||||||
|
checkTimeStr1 := fmt.Sprintf("%s %s", utils.Time2DateStr(curTime), scoreStoreTimeList[0])
|
||||||
|
checkTime1 := utils.Str2Time(checkTimeStr1)
|
||||||
|
checkTimeStr2 := fmt.Sprintf("%s %s", utils.Time2DateStr(curTime), scoreStoreCheckTimeEnd)
|
||||||
|
checkTime2 := utils.Str2Time(checkTimeStr2)
|
||||||
|
if curTime.Unix() >= checkTime1.Unix() && curTime.Unix() <= checkTime2.Unix() {
|
||||||
|
db := dao.GetDB()
|
||||||
|
hasStoreScoreData, err := dao.CheckHasStoreScoreData(db, curTime)
|
||||||
|
if err == nil && !hasStoreScoreData {
|
||||||
|
ScoreStore(jxcontext.AdminCtx, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Time2Week(t time.Time) int {
|
||||||
|
yearDay := t.YearDay()
|
||||||
|
yearFirstDay := t.AddDate(0, 0, -yearDay+1)
|
||||||
|
firstDayInWeek := int(yearFirstDay.Weekday())
|
||||||
|
|
||||||
|
firstWeekDays := 1
|
||||||
|
if firstDayInWeek != 0 {
|
||||||
|
firstWeekDays = 7 - firstDayInWeek + 1
|
||||||
|
}
|
||||||
|
var week int
|
||||||
|
if yearDay <= firstWeekDays {
|
||||||
|
week = 1
|
||||||
|
} else {
|
||||||
|
tempWeek := (float64(yearDay) - float64(firstWeekDays)) / float64(7)
|
||||||
|
week = int(math.Ceil(tempWeek)) + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return week
|
||||||
|
}
|
||||||
|
|
||||||
|
func SplitToSingleWeekDataList(storeScoreList []*model.StoreScoreEx) (weekDataList [][]*model.StoreScoreEx) {
|
||||||
|
singelWeekData := []*model.StoreScoreEx{}
|
||||||
|
weekIndex := 0
|
||||||
|
for _, value := range storeScoreList {
|
||||||
|
if weekIndex == 0 {
|
||||||
|
weekIndex = Time2Week(value.CreatedAt)
|
||||||
|
}
|
||||||
|
if weekIndex == Time2Week(value.CreatedAt) {
|
||||||
|
singelWeekData = append(singelWeekData, value)
|
||||||
|
} else {
|
||||||
|
weekDataList = append(weekDataList, singelWeekData)
|
||||||
|
singelWeekData = []*model.StoreScoreEx{}
|
||||||
|
weekIndex = 0
|
||||||
|
singelWeekData = append(singelWeekData, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(singelWeekData) > 0 {
|
||||||
|
weekDataList = append(weekDataList, singelWeekData)
|
||||||
|
}
|
||||||
|
|
||||||
|
return weekDataList
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetStoreScoreLevel(score int) int {
|
||||||
|
level := 0
|
||||||
|
if score >= GoldMedalScore {
|
||||||
|
level = GoldMedalLevel
|
||||||
|
} else if score >= SilverMedalScore {
|
||||||
|
level = SilverMedalLevel
|
||||||
|
} else if score >= BronzeMedalScore {
|
||||||
|
level = BronzeMedalLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
return level
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetWeeklyStoreScore(storeID, weekIndex int) (outWeeklyStoreScoreDataList []*model.WeeklyStoreScore, err error) {
|
||||||
|
db := dao.GetDB()
|
||||||
|
storeScoreList, err := dao.GetLatestWeeklyStoreScoreList(db, storeID, 5)
|
||||||
|
if err == nil && len(storeScoreList) > 0 {
|
||||||
|
weeklyStoreScoreDataList := []*model.WeeklyStoreScore{}
|
||||||
|
weekDataList := SplitToSingleWeekDataList(storeScoreList)
|
||||||
|
for weekIndex, weekData := range weekDataList {
|
||||||
|
weeklyData := &model.WeeklyStoreScore{}
|
||||||
|
weeklyData.ID = weekIndex
|
||||||
|
weeklyData.ItemTotalScore = ItemTotalScore
|
||||||
|
weeklyData.StoreID = storeID
|
||||||
|
weeklyStoreScoreDataList = append(weeklyStoreScoreDataList, weeklyData)
|
||||||
|
weekDataCount := len(weekData)
|
||||||
|
for dayIndex, dayData := range weekData {
|
||||||
|
for _, fieldName := range storeScoreFieldName {
|
||||||
|
srcFieldValue := refutil.GetObjFieldByName(dayData, fieldName).(int)
|
||||||
|
destFieldValue := refutil.GetObjFieldByName(weeklyData, fieldName).(int)
|
||||||
|
refutil.SetObjFieldByName(weeklyData, fieldName, destFieldValue+srcFieldValue)
|
||||||
|
}
|
||||||
|
if weekDataCount == 1 {
|
||||||
|
weeklyData.BeginTime = dayData.CreatedAt
|
||||||
|
weeklyData.EndTime = dayData.CreatedAt
|
||||||
|
} else {
|
||||||
|
if dayIndex == 0 {
|
||||||
|
weeklyData.EndTime = dayData.CreatedAt
|
||||||
|
} else if dayIndex == weekDataCount-1 {
|
||||||
|
weeklyData.BeginTime = dayData.CreatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
weeklyData.StoreName = dayData.StoreName
|
||||||
|
}
|
||||||
|
for _, fieldName := range storeScoreFieldName {
|
||||||
|
destFieldValue := refutil.GetObjFieldByName(weeklyData, fieldName).(int)
|
||||||
|
refutil.SetObjFieldByName(weeklyData, fieldName, int(math.Round(float64(destFieldValue)/float64(weekDataCount))))
|
||||||
|
}
|
||||||
|
for _, fieldName := range storeScoreFieldName {
|
||||||
|
srcFieldValue := refutil.GetObjFieldByName(weeklyData, fieldName).(int)
|
||||||
|
destFieldValue := refutil.GetObjFieldByName(weeklyData, model.FieldTotalScore).(int)
|
||||||
|
refutil.SetObjFieldByName(weeklyData, model.FieldTotalScore, destFieldValue+srcFieldValue)
|
||||||
|
}
|
||||||
|
weeklyData.Level = GetStoreScoreLevel(weeklyData.TotalScore)
|
||||||
|
}
|
||||||
|
if weekIndex == -1 {
|
||||||
|
outWeeklyStoreScoreDataList = weeklyStoreScoreDataList
|
||||||
|
} else {
|
||||||
|
outWeeklyStoreScoreDataList = []*model.WeeklyStoreScore{weeklyStoreScoreDataList[weekIndex]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return outWeeklyStoreScoreDataList, err
|
||||||
|
}
|
||||||
24
business/jxstore/misc/store_score_test.go
Normal file
24
business/jxstore/misc/store_score_test.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package misc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/api2"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/testinit"
|
||||||
|
|
||||||
|
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai"
|
||||||
|
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/elm"
|
||||||
|
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
|
||||||
|
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm"
|
||||||
|
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/weimob/wsc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
testinit.Init()
|
||||||
|
api2.Init()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestScoreStore(t *testing.T) {
|
||||||
|
ScoreStore(jxcontext.AdminCtx, []int{})
|
||||||
|
}
|
||||||
@@ -290,3 +290,71 @@ func GetStoreAfsOrderSkuList(db *DaoDB, storeIDs []int, finishedAtBegin, finishe
|
|||||||
err = GetRows(db, &afsSkuList, sql, sqlParams...)
|
err = GetRows(db, &afsSkuList, sql, sqlParams...)
|
||||||
return afsSkuList, err
|
return afsSkuList, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetDailyFinishOrderList(db *DaoDB, storeID int, dateTime time.Time) (orderList []*model.OrderPickupTime, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT t2.status_time, t1.pick_deadline
|
||||||
|
FROM goods_order t1
|
||||||
|
JOIN order_status t2 ON t1.vendor_order_id = t2.vendor_order_id AND t1.vendor_id = t2.vendor_id
|
||||||
|
WHERE t1.jx_store_id = ? AND t2.order_type = ? AND t2.status = ? AND DATE(t1.order_finished_at) = DATE(?)
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
storeID,
|
||||||
|
1,
|
||||||
|
model.OrderStatusFinishedPickup,
|
||||||
|
dateTime,
|
||||||
|
}
|
||||||
|
return orderList, GetRows(db, &orderList, sql, sqlParams...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDailyBadCommentOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT jxstoreid store_id, COUNT(*) count
|
||||||
|
FROM jx_bad_comments
|
||||||
|
WHERE DATE(createtime) = DATE(?)
|
||||||
|
GROUP BY jxstoreid
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
dateTime,
|
||||||
|
}
|
||||||
|
err = GetRows(db, &storeCountList, sql, sqlParams)
|
||||||
|
|
||||||
|
return storeCountList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDailyUnFinishOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) {
|
||||||
|
return GetDailyEndOrderCount(db, []int{model.OrderStatusCanceled}, false, dateTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDailyFinishOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) {
|
||||||
|
return GetDailyEndOrderCount(db, []int{model.OrderStatusFinished}, false, dateTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDailyAbsentGoodsOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) {
|
||||||
|
return GetDailyEndOrderCount(db, []int{model.OrderStatusFinished, model.OrderStatusCanceled}, true, dateTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDailyEndOrderCount(db *DaoDB, statusList []int, isAbsentOrder bool, dateTime time.Time) (storeCountList []*model.StoreCount, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT jx_store_id store_id, COUNT(*) count
|
||||||
|
FROM goods_order
|
||||||
|
WHERE DATE(order_finished_at) = DATE(?)
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
dateTime,
|
||||||
|
}
|
||||||
|
if len(statusList) > 0 {
|
||||||
|
sql += ` AND status IN (` + GenQuestionMarks(len(statusList)) + `)`
|
||||||
|
sqlParams = append(sqlParams, statusList)
|
||||||
|
}
|
||||||
|
if isAbsentOrder {
|
||||||
|
sql += `
|
||||||
|
AND adjust_count > 0
|
||||||
|
`
|
||||||
|
}
|
||||||
|
sql += `
|
||||||
|
GROUP BY jx_store_id`
|
||||||
|
err = GetRow(db, &storeCountList, sql, sqlParams)
|
||||||
|
|
||||||
|
return storeCountList, err
|
||||||
|
}
|
||||||
|
|||||||
67
business/model/dao/store_score.go
Normal file
67
business/model/dao/store_score.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InsertStoreScore(storeScore *model.StoreScore) error {
|
||||||
|
storeScore.CreatedAt = time.Now()
|
||||||
|
return CreateEntity(nil, storeScore)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreList []*model.StoreScoreEx, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT t2.name store_name, t1.* FROM store_score t1
|
||||||
|
JOIN store t2 ON t1.store_id = t2.id
|
||||||
|
WHERE t1.store_id = ?
|
||||||
|
AND DATE(t1.score_date) >= DATE_SUB(
|
||||||
|
DATE_SUB(
|
||||||
|
CURDATE(),
|
||||||
|
INTERVAL
|
||||||
|
IF (
|
||||||
|
DAYOFWEEK(CURDATE()) - 1 = 0,
|
||||||
|
7,
|
||||||
|
DAYOFWEEK(CURDATE()) - 1
|
||||||
|
) DAY
|
||||||
|
),
|
||||||
|
INTERVAL ? DAY
|
||||||
|
)
|
||||||
|
AND DATE(t1.score_date) <= DATE_SUB(
|
||||||
|
CURDATE(),
|
||||||
|
INTERVAL
|
||||||
|
IF (
|
||||||
|
DAYOFWEEK(CURDATE()) - 1 = 0,
|
||||||
|
7,
|
||||||
|
DAYOFWEEK(CURDATE()) - 1
|
||||||
|
) DAY
|
||||||
|
)
|
||||||
|
ORDER BY score_date DESC
|
||||||
|
`
|
||||||
|
if weekNum <= 0 {
|
||||||
|
weekNum = 1
|
||||||
|
}
|
||||||
|
diffDays := weekNum*7 - 1
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
storeID,
|
||||||
|
diffDays,
|
||||||
|
}
|
||||||
|
err = GetRows(db, &storeScoreList, sql, sqlParams)
|
||||||
|
return storeScoreList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckHasStoreScoreData(db *DaoDB, dateTime time.Time) (hasStoreScoreData bool, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT COUNT(*) count
|
||||||
|
FROM store_score
|
||||||
|
WHERE DATE(score_date) = DATE(?)
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
dateTime,
|
||||||
|
}
|
||||||
|
count := 0
|
||||||
|
err = GetRow(db, &count, sql, sqlParams)
|
||||||
|
hasStoreScoreData = count > 0
|
||||||
|
return hasStoreScoreData, err
|
||||||
|
}
|
||||||
60
business/model/store_score.go
Normal file
60
business/model/store_score.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
const (
|
||||||
|
FieldStoreOpenTime = "StoreOpenTime"
|
||||||
|
FieldSaleSkuCount = "SaleSkuCount"
|
||||||
|
FieldAveragePickupTime = "AveragePickupTime"
|
||||||
|
FieldBadCommentOrder = "BadCommentOrder"
|
||||||
|
FieldUnfinishOrder = "UnfinishOrder"
|
||||||
|
FieldAbsentGoodsOrder = "AbsentGoodsOrder"
|
||||||
|
FieldPromotionSku = "PromotionSku"
|
||||||
|
FieldFullVendor = "FullVendor"
|
||||||
|
FieldStoreRange = "StoreRange"
|
||||||
|
FieldSaleSkuPrice = "SaleSkuPrice"
|
||||||
|
|
||||||
|
FieldTotalScore = "TotalScore"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StoreScore struct {
|
||||||
|
ID int `orm:"column(id)" json:"id"`
|
||||||
|
CreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"`
|
||||||
|
ScoreDate time.Time `orm:"auto_now_add;type(datetime)" json:"scoreDate"`
|
||||||
|
StoreID int `orm:"column(store_id)" json:"storeID"`
|
||||||
|
|
||||||
|
StoreOpenTime int `orm:"column(store_open_time)" json:"storeOpenTime"`
|
||||||
|
SaleSkuCount int `orm:"column(sale_sku_count)" json:"saleSkuCount"`
|
||||||
|
AveragePickupTime int `orm:"column(average_pickup_time)" json:"averagePickupTime"`
|
||||||
|
BadCommentOrder int `orm:"column(bad_comment_order)" json:"badCommentOrder"`
|
||||||
|
UnfinishOrder int `orm:"column(unfinish_order)" json:"unfinishOrder"`
|
||||||
|
AbsentGoodsOrder int `orm:"column(absent_Goods_order)" json:"absentGoodsOrder"`
|
||||||
|
PromotionSku int `orm:"column(promotion_sku)" json:"promotionSku"`
|
||||||
|
FullVendor int `orm:"column(full_vendor)" json:"fullVendor"`
|
||||||
|
StoreRange int `orm:"column(store_range)" json:"storeRange"`
|
||||||
|
SaleSkuPrice int `orm:"column(sale_sku_price)" json:"saleSkuPrice"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type StoreScoreEx struct {
|
||||||
|
StoreScore
|
||||||
|
StoreName string `json:"storeName"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WeeklyStoreScore struct {
|
||||||
|
StoreScoreEx
|
||||||
|
BeginTime time.Time `json:"beginTime"`
|
||||||
|
EndTime time.Time `json:"endTime"`
|
||||||
|
TotalScore int `json:"totalScore"`
|
||||||
|
ItemTotalScore int `json:"itemTotalScore"`
|
||||||
|
Level int `json:"level"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type StoreCount struct {
|
||||||
|
StoreID int `orm:"column(store_id)"`
|
||||||
|
Count int
|
||||||
|
}
|
||||||
|
|
||||||
|
type OrderPickupTime struct {
|
||||||
|
StatusTime time.Time
|
||||||
|
PickDeadline time.Time
|
||||||
|
}
|
||||||
@@ -263,3 +263,11 @@ func GetSingleStoreVendorIDs() (vendorIDs []int) {
|
|||||||
}
|
}
|
||||||
return vendorIDs
|
return vendorIDs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsMultiStore(vendorID int) bool {
|
||||||
|
if _, ok := GetPurchasePlatformFromVendorID(vendorID).(IMultipleStoresHandler); ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxstore/misc"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/netprinter"
|
"git.rosy.net.cn/jx-callback/business/jxutils/netprinter"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
@@ -422,3 +423,36 @@ func (c *StoreController) SyncStoresQualify() {
|
|||||||
return retVal, "", err
|
return retVal, "", err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Title 门店评分
|
||||||
|
// @Description 门店评分
|
||||||
|
// @Param token header string true "认证token"
|
||||||
|
// @Param storeIDs formData string false "京西门店ID列表"
|
||||||
|
// @Success 200 {object} controllers.CallResult
|
||||||
|
// @Failure 200 {object} controllers.CallResult
|
||||||
|
// @router /ScoreStore [post]
|
||||||
|
func (c *StoreController) ScoreStore() {
|
||||||
|
c.callScoreStore(func(params *tStoreScoreStoreParams) (retVal interface{}, errCode string, err error) {
|
||||||
|
var storeIDList []int
|
||||||
|
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil {
|
||||||
|
misc.ScoreStore(params.Ctx, storeIDList)
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal, "", err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Title 得到门店近期周平均分数数据
|
||||||
|
// @Description 得到门店近期周平均分数数据
|
||||||
|
// @Param token header string true "认证token"
|
||||||
|
// @Param storeID query int true "京西门店ID"
|
||||||
|
// @Param weekIndex query int true "周索引(起始索引为0, -1为所有周数据)"
|
||||||
|
// @Success 200 {object} controllers.CallResult
|
||||||
|
// @Failure 200 {object} controllers.CallResult
|
||||||
|
// @router /GetWeeklyStoreScore [get]
|
||||||
|
func (c *StoreController) GetWeeklyStoreScore() {
|
||||||
|
c.callGetWeeklyStoreScore(func(params *tStoreGetWeeklyStoreScoreParams) (retVal interface{}, errCode string, err error) {
|
||||||
|
retVal, err = misc.GetWeeklyStoreScore(params.StoreID, params.WeekIndex)
|
||||||
|
return retVal, "", err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ func Init() {
|
|||||||
|
|
||||||
orm.RegisterModel(&model.CasbinRule{})
|
orm.RegisterModel(&model.CasbinRule{})
|
||||||
orm.RegisterModel(&model.SensitiveWord{})
|
orm.RegisterModel(&model.SensitiveWord{})
|
||||||
|
orm.RegisterModel(&model.StoreScore{})
|
||||||
orm.RegisterModel(&model.FoodRecipe{}, &model.FoodRecipeStep{}, &model.FoodRecipeItem{}, &model.FoodRecipeItemChoice{}, &model.FoodRecipeUser{})
|
orm.RegisterModel(&model.FoodRecipe{}, &model.FoodRecipeStep{}, &model.FoodRecipeItem{}, &model.FoodRecipeItemChoice{}, &model.FoodRecipeUser{})
|
||||||
|
|
||||||
// create table
|
// create table
|
||||||
|
|||||||
@@ -475,6 +475,15 @@ func init() {
|
|||||||
Filters: nil,
|
Filters: nil,
|
||||||
Params: nil})
|
Params: nil})
|
||||||
|
|
||||||
|
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:FoodRecipeController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:FoodRecipeController"],
|
||||||
|
beego.ControllerComments{
|
||||||
|
Method: "CreateFoodRecipe",
|
||||||
|
Router: `/CreateFoodRecipe`,
|
||||||
|
AllowHTTPMethods: []string{"post"},
|
||||||
|
MethodParams: param.Make(),
|
||||||
|
Filters: nil,
|
||||||
|
Params: nil})
|
||||||
|
|
||||||
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:InitDataController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:InitDataController"],
|
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:InitDataController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:InitDataController"],
|
||||||
beego.ControllerComments{
|
beego.ControllerComments{
|
||||||
Method: "BuildSkuFromEbaiStore",
|
Method: "BuildSkuFromEbaiStore",
|
||||||
@@ -1296,6 +1305,24 @@ func init() {
|
|||||||
Filters: nil,
|
Filters: nil,
|
||||||
Params: nil})
|
Params: nil})
|
||||||
|
|
||||||
|
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"],
|
||||||
|
beego.ControllerComments{
|
||||||
|
Method: "GetWeeklyStoreScore",
|
||||||
|
Router: `/GetWeeklyStoreScore`,
|
||||||
|
AllowHTTPMethods: []string{"get"},
|
||||||
|
MethodParams: param.Make(),
|
||||||
|
Filters: nil,
|
||||||
|
Params: nil})
|
||||||
|
|
||||||
|
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"],
|
||||||
|
beego.ControllerComments{
|
||||||
|
Method: "ScoreStore",
|
||||||
|
Router: `/ScoreStore`,
|
||||||
|
AllowHTTPMethods: []string{"post"},
|
||||||
|
MethodParams: param.Make(),
|
||||||
|
Filters: nil,
|
||||||
|
Params: nil})
|
||||||
|
|
||||||
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"],
|
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"],
|
||||||
beego.ControllerComments{
|
beego.ControllerComments{
|
||||||
Method: "SyncStoresQualify",
|
Method: "SyncStoresQualify",
|
||||||
|
|||||||
Reference in New Issue
Block a user