- 添加对于监控平台门店状态初始版本

This commit is contained in:
gazebo
2019-06-26 16:58:38 +08:00
parent f7ec972d2e
commit 0adf3e7d31
15 changed files with 422 additions and 30 deletions

View File

@@ -8,6 +8,8 @@ import (
"strings"
"time"
"git.rosy.net.cn/jx-callback/business/auth2"
"git.rosy.net.cn/baseapi/platformapi/dadaapi"
"git.rosy.net.cn/baseapi/platformapi/feieapi"
"git.rosy.net.cn/baseapi/platformapi/jdapi"
@@ -15,6 +17,7 @@ import (
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/jxutils/excel"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/jxutils/msg"
"git.rosy.net.cn/jx-callback/business/jxutils/netprinter"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
@@ -91,6 +94,13 @@ var (
"deliveryRange": 1,
"status": 1,
}
WatchVendorStoreTimeList = []string{
"8:00:00",
"10:00:00",
"11:00:00",
"15:00:00",
}
)
// todo 门店绑定信息可以考虑以数组形式返回,而不是现在这样
@@ -1077,7 +1087,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)
storeMapList, err := dao.GetStoresMapList(db, []int{vendorID}, storeIDs, model.StoreStatusAll, model.StoreIsSyncYes)
if err != nil {
return "", err
}
@@ -1161,3 +1171,194 @@ func GetCorporationInfo(ctx *jxcontext.Context, licenceCode string) (corporation
corporationInfo, err = api.JdAPI.GetCorporationInfo("", licenceCode)
return corporationInfo, err
}
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)
if err != nil {
return nil, err
}
task := tasksch.NewParallelTask("GetStoresVendorSnapshot", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
storeMap := batchItemList[0].(*model.StoreMap)
if handler := partner.GetPurchasePlatformFromVendorID(storeMap.VendorID); handler != nil {
store, err2 := handler.ReadStore(storeMap.VendorStoreID)
if err = err2; err == nil {
retVal = []interface{}{&model.VendorStoreSnapshot{
StoreID: storeMap.StoreID,
VendorID: storeMap.VendorID,
VendorStoreID: storeMap.VendorStoreID,
Status: store.Status,
OpenTime1: store.OpenTime1,
CloseTime1: store.CloseTime1,
OpenTime2: store.OpenTime2,
CloseTime2: store.CloseTime2,
}}
}
}
return retVal, err
}, storeMapList)
tasksch.HandleTask(task, parentTask, true).Run()
resultList, err := task.GetResult(0)
if len(resultList) > 0 {
err = nil // 强制忽略
for _, v := range resultList {
dao.WrapAddIDCULDEntity(v, ctx.GetUserName())
vendorStoreSnapshotList = append(vendorStoreSnapshotList, v.(*model.VendorStoreSnapshot))
}
}
return vendorStoreSnapshotList, err
}
func getCurrentSnapshotAt(now time.Time) (snapshotAt time.Time) {
return jxutils.GetLastTimeFromList(now, WatchVendorStoreTimeList)
}
func SaveStoresVendorSnapshot(db *dao.DaoDB, snapshotAt time.Time, curSnapshotList []*model.VendorStoreSnapshot) (err error) {
dao.Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
dao.Rollback(db)
if r != nil {
panic(r)
}
}
}()
for _, v := range curSnapshotList {
v.SnapshotAt = snapshotAt
dao.DeleteEntity(db, v, "VendorStoreID", "VendorID", "SnapshotAt")
if err = dao.CreateEntity(db, v); err != nil {
return err
}
}
dao.Commit(db)
return err
}
func SendAlarmVendorSnapshot(ctx *jxcontext.Context, parentTask tasksch.ITask, prevSnapshotList, curSnapshotList []*model.VendorStoreSnapshot) (err error) {
prevSnapshotMap := make(map[string]*model.VendorStoreSnapshot)
for _, v := range prevSnapshotList {
prevSnapshotMap[v.GenMapKey()] = v
}
alarmMap := make(map[int]map[int]*model.VendorStoreSnapshot)
storeDetailMap := make(map[int]*dao.StoreDetail)
userMap := make(map[string][]int)
db := dao.GetDB()
for _, v := range curSnapshotList {
prevSnapshot := prevSnapshotMap[v.GenMapKey()]
if prevSnapshot != nil {
if ((prevSnapshot == nil || prevSnapshot.Status == model.StoreStatusOpened) && v.Status != model.StoreStatusOpened) ||
v.CompareOperationTime(prevSnapshot) < 0 {
if alarmMap[v.StoreID] == nil {
alarmMap[v.StoreID] = make(map[int]*model.VendorStoreSnapshot)
storeDetail, _ := dao.GetStoreDetail(db, v.StoreID, v.VendorID)
if storeDetail != nil {
storeDetailMap[v.StoreID] = storeDetail
userMap[storeDetail.Tel1] = append(userMap[storeDetail.Tel1], v.StoreID)
userMap[storeDetail.MarketManPhone] = append(userMap[storeDetail.MarketManPhone], v.StoreID)
userMap[storeDetail.OperatorPhone] = append(userMap[storeDetail.OperatorPhone], v.StoreID)
}
}
alarmMap[v.StoreID][v.VendorID] = v
}
}
}
var mobileList []string
for mobile := range userMap {
if mobile != "" {
mobileList = append(mobileList, mobile)
}
}
if len(mobileList) > 0 {
task := tasksch.NewParallelTask("SendAlarmVendorSnapshot", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
mobile := batchItemList[0].(string)
var dataList []map[string]interface{}
captionList := []string{"京西门店ID", "门店名"}
isFirstRow := true
for _, storeID := range userMap[mobile] {
snapshotMap := alarmMap[storeID]
data := map[string]interface{}{
"京西门店ID": storeID,
"门店名": storeDetailMap[storeID].Store.Name,
}
for _, vendorID := range []int{model.VendorIDJD, model.VendorIDEBAI, model.VendorIDMTWM} {
if isFirstRow {
captionList = append(captionList, model.VendorChineseNames[vendorID]+"ID",
model.VendorChineseNames[vendorID]+"之前状态", model.VendorChineseNames[vendorID]+"当前状态",
model.VendorChineseNames[vendorID]+"之前营业时间", model.VendorChineseNames[vendorID]+"当前营业时间")
}
data[model.VendorChineseNames[vendorID]+"ID"] = ""
data[model.VendorChineseNames[vendorID]+"之前状态"] = ""
data[model.VendorChineseNames[vendorID]+"当前状态"] = ""
data[model.VendorChineseNames[vendorID]+"之前营业时间"] = ""
data[model.VendorChineseNames[vendorID]+"当前营业时间"] = ""
snapshot := snapshotMap[vendorID]
if snapshot != nil {
data[model.VendorChineseNames[vendorID]+"ID"] = snapshot.VendorStoreID
data[model.VendorChineseNames[vendorID]+"当前状态"] = model.StoreStatusName[snapshot.Status]
data[model.VendorChineseNames[vendorID]+"当前营业时间"] = jxutils.OperationTimeStr4VendorStore(snapshot)
if p := prevSnapshotMap[snapshot.GenMapKey()]; p != nil {
data[model.VendorChineseNames[vendorID]+"之前状态"] = model.StoreStatusName[p.Status]
data[model.VendorChineseNames[vendorID]+"之前营业时间"] = jxutils.OperationTimeStr4VendorStore(p)
}
}
}
dataList = append(dataList, data)
isFirstRow = false
}
excelConf := &excel.Obj2ExcelSheetConfig{
Title: "平台门店重要信息",
Data: dataList,
CaptionList: captionList,
}
excelBin := excel.Obj2Excel([]*excel.Obj2ExcelSheetConfig{excelConf})
key := "export/" + mobile + time.Now().Format("20060102T150405") + ".xlsx"
excelURL, err2 := jxutils.UploadExportContent(excelBin, key)
if err2 != nil {
globals.SugarLogger.Warnf("SendAlarmVendorSnapshot, send %s failed with error:%v", key, err2)
}
sendStoreStatusInfo2Mobile(mobile, excelURL)
return nil, nil
}, mobileList)
tasksch.HandleTask(task, parentTask, true).Run()
_, err = task.GetResult(0)
}
return err
}
func sendStoreStatusInfo2Mobile(mobile, excelURL string) {
if user := userProvider.GetUser(mobile, auth2.AuthTypeMobile); user != nil {
globals.SugarLogger.Debugf("sendStoreStatusInfo2Mobile %s:%s", mobile, excelURL)
msg.SendUserMessage(user.GetID(), "平台门店重要信息", fmt.Sprintf("详情见: %s", excelURL))
}
}
func SaveAndSendAlarmVendorSnapshot(ctx *jxcontext.Context, vendorIDs, storeIDs []int) (err error) {
curSnapshotAt := getCurrentSnapshotAt(time.Now())
db := dao.GetDB()
var curSnapshotList, prevSnapshotList []*model.VendorStoreSnapshot
task := tasksch.NewSeqTask("SaveAndSendAlarmVendorSnapshot", ctx,
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
switch step {
case 0:
curSnapshotList, err = GetStoresVendorSnapshot(ctx, task, vendorIDs, storeIDs)
case 1:
err = SaveStoresVendorSnapshot(db, curSnapshotAt, curSnapshotList)
case 2:
prevSnapshotList, err = dao.GetVendorStoreSnapshot(db, curSnapshotAt)
case 3:
err = SendAlarmVendorSnapshot(ctx, task, prevSnapshotList, curSnapshotList)
}
return nil, err
}, 4)
tasksch.ManageTask(task).Run()
_, err = task.GetResult(0)
return err
}

View File

@@ -500,7 +500,7 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bool,
}
func getValidStoreVendorMap(db *dao.DaoDB, storeIDs []int) (realVendorMap map[int]int, err error) {
storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, model.StoreStatusAll)
storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, model.StoreStatusAll, model.StoreIsSyncYes)
if err != nil {
return nil, err
}
@@ -1649,7 +1649,7 @@ func RefreshStoresSkuByVendor(ctx *jxcontext.Context, storeIDs []int, vendorID i
return "", fmt.Errorf("此功能当前只支持京东到家平台")
}
db := dao.GetDB()
storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, model.StoreStatusAll)
storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, model.StoreStatusAll, model.StoreIsSyncAll)
if err != nil {
return "", err
}

View File

@@ -0,0 +1,18 @@
package cms
import (
"testing"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/model"
)
func TestGetStoresVendorSnapshot(t *testing.T) {
result, err := GetStoresVendorSnapshot(jxcontext.AdminCtx, nil, []int{model.VendorIDEBAI}, nil)
if err != nil {
t.Fatal(err)
}
t.Log(utils.Format4Output(result, false))
t.Log(len(result))
}

View File

@@ -518,28 +518,10 @@ func (v *VendorSync) DeleteRemoteStoreSkus(ctx *jxcontext.Context, db *dao.DaoDB
}
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) {
sql := `
SELECT t1.*
FROM store_map t1
WHERE t1.is_sync = 1 AND t1.deleted_at = ?
`
sqlParams := []interface{}{
utils.DefaultTimeValue,
}
if len(vendorIDs) > 0 {
sql += " AND t1.vendor_id IN (" + dao.GenQuestionMarks(len(vendorIDs)) + ")"
sqlParams = append(sqlParams, vendorIDs)
}
if len(storeIDs) > 0 {
sql += " AND t1.store_id IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")"
sqlParams = append(sqlParams, storeIDs)
}
sql += " ORDER BY t1.store_id, t1.vendor_id"
var storeMapList []*model.StoreMap
if err = dao.GetRows(db, &storeMapList, sql, sqlParams...); err != nil {
if storeMapList, err = dao.GetStoresMapList(db, vendorIDs, storeIDs, model.StoreStatusAll, model.StoreIsSyncYes); err != nil {
return nil, "", err
}
if len(storeMapList) == 0 {
return nil, "", nil
}