286 lines
9.8 KiB
Go
286 lines
9.8 KiB
Go
package report
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"math"
|
||
"sort"
|
||
"time"
|
||
|
||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||
"git.rosy.net.cn/jx-callback/business/model"
|
||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||
)
|
||
|
||
type tStoreSkuBindAndSkuName struct {
|
||
CityCode int
|
||
StoreID int `orm:"column(store_id)"`
|
||
NameID int `orm:"column(name_id)"`
|
||
UnitPrice int
|
||
UnitPriceList []int
|
||
}
|
||
|
||
func GetStatisticsReportForOrders(ctx *jxcontext.Context, storeIDs []int, fromDate string, toDate string) (statisticsReportForOrdersList []*dao.StatisticsReportForOrdersList, err error) {
|
||
db := dao.GetDB()
|
||
fromDateParm := utils.Str2Time(fromDate)
|
||
toDateParm := utils.Str2Time(toDate)
|
||
//若时间间隔大于3个月则不允许查询
|
||
if math.Ceil(toDateParm.Sub(fromDateParm).Hours()/24) > 92 {
|
||
return nil, errors.New(fmt.Sprintf("查询间隔时间不允许大于3个月!: 时间范围:[%v] 至 [%v]", fromDate, toDate))
|
||
}
|
||
statisticsReportForOrdersList, err = dao.GetStatisticsReportForOrders(db, storeIDs, fromDateParm, toDateParm)
|
||
return statisticsReportForOrdersList, err
|
||
}
|
||
|
||
func GetStatisticsReportForAfsOrders(ctx *jxcontext.Context, storeIDs []int, fromDate string, toDate string) (statisticsReportForOrdersList []*dao.StatisticsReportForOrdersList, err error) {
|
||
db := dao.GetDB()
|
||
fromDateParm := utils.Str2Time(fromDate)
|
||
toDateParm := utils.Str2Time(toDate)
|
||
//若时间间隔大于3个月则不允许查询
|
||
if math.Ceil(toDateParm.Sub(fromDateParm).Hours()/24) > 92 {
|
||
return nil, errors.New(fmt.Sprintf("查询间隔时间不允许大于3个月!: 时间范围:[%v] 至 [%v]", fromDate, toDate))
|
||
}
|
||
statisticsReportForOrdersList, err = dao.GetGetStatisticsReportForAfsOrders(db, storeIDs, fromDateParm, toDateParm)
|
||
return statisticsReportForOrdersList, err
|
||
}
|
||
|
||
func StatisticsReportForStoreSkusPrice(ctx *jxcontext.Context, cityCodes, skuIDs []int, snapDate string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
|
||
var snapDateParam time.Time
|
||
db := dao.GetDB()
|
||
if snapDate != "" {
|
||
snapDateParam = utils.Str2Time(snapDate)
|
||
}
|
||
priceReferSnapshot, totalCount, err := dao.GetPriceReferSnapshot(db, cityCodes, skuIDs, 0, snapDateParam, offset, pageSize)
|
||
pagedInfo = &model.PagedInfo{
|
||
Data: priceReferSnapshot,
|
||
TotalCount: totalCount,
|
||
}
|
||
return
|
||
}
|
||
|
||
func BeginSavePriceRefer(ctx *jxcontext.Context, cityCodes, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||
var priceReferSnapshotList []*model.PriceReferSnapshot
|
||
db := dao.GetDB()
|
||
snapshotAt := utils.Time2Date(time.Now().AddDate(0, 0, -1))
|
||
dao.DeletePriceReferHistory(db, utils.Time2Date(snapshotAt.AddDate(0, 0, -7)))
|
||
priceReferSnapshotDelete := &model.PriceReferSnapshot{SnapshotAt: snapshotAt}
|
||
dao.DeleteEntity(db, priceReferSnapshotDelete, "SnapshotAt")
|
||
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||
switch step {
|
||
case 0:
|
||
priceReferSnapshot, err := dao.GetStatisticsReportForStoreSkusPrice(db, cityCodes, skuIDs)
|
||
if len(priceReferSnapshot) > 0 {
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil || err != nil {
|
||
dao.Rollback(db)
|
||
if r != nil {
|
||
panic(r)
|
||
}
|
||
}
|
||
}()
|
||
for _, v := range priceReferSnapshot {
|
||
dao.WrapAddIDCULDEntity(v, ctx.GetUserName())
|
||
v.SnapshotAt = snapshotAt
|
||
}
|
||
dao.CreateMultiEntities(db, priceReferSnapshot)
|
||
dao.Commit(db)
|
||
}
|
||
case 1:
|
||
priceReferSnapshotList, err = dao.GetPriceReferSnapshotNoPage(db, nil, nil, nil, snapshotAt)
|
||
var (
|
||
citySkuMap = make(map[int]map[int][]int)
|
||
countryMap = make(map[int][]int)
|
||
resultMap = make(map[int]map[int]*model.PriceReferSnapshot)
|
||
resultCountryMap = make(map[int]*model.PriceReferSnapshot)
|
||
)
|
||
storeList, err := dao.GetStoreList(db, nil, nil, nil, nil, "")
|
||
if err != nil {
|
||
return result, err
|
||
}
|
||
for _, v := range storeList {
|
||
if v.PayPercentage < 50 {
|
||
continue
|
||
}
|
||
var tList []*tStoreSkuBindAndSkuName
|
||
sql := `
|
||
SELECT DISTINCT b.city_code, a.store_id, Round(a.unit_price * IF(b.pay_percentage < 50 , 70, b.pay_percentage) / 100) AS unit_price, c.name_id
|
||
FROM store_sku_bind a
|
||
JOIN store b ON b.id = a.store_id AND b.deleted_at = ? AND b.status != ?
|
||
JOIN sku c ON c.id = a.sku_id
|
||
WHERE a.store_id = ?
|
||
AND c.name_id NOT IN(
|
||
SELECT b.name_id
|
||
FROM store_sku_bind a
|
||
JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ?
|
||
WHERE a.deleted_at = ?
|
||
AND a.store_id = ?
|
||
AND b.name_id NOT IN(SELECT DISTINCT b.name_id
|
||
FROM store_sku_bind a
|
||
JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ?
|
||
WHERE a.deleted_at = ?
|
||
AND a.store_id = ?
|
||
AND a.status = ?)
|
||
)
|
||
AND a.deleted_at = ?
|
||
`
|
||
sqlParams := []interface{}{
|
||
utils.DefaultTimeValue,
|
||
model.StoreStatusDisabled,
|
||
v.ID,
|
||
utils.DefaultTimeValue,
|
||
utils.DefaultTimeValue,
|
||
v.ID,
|
||
utils.DefaultTimeValue,
|
||
utils.DefaultTimeValue,
|
||
v.ID,
|
||
model.StoreSkuBindStatusNormal,
|
||
utils.DefaultTimeValue,
|
||
}
|
||
dao.GetRows(db, &tList, sql, sqlParams...)
|
||
skuNameMap := make(map[int][]int)
|
||
if len(tList) > 0 {
|
||
for _, vv := range tList {
|
||
skuNameMap[vv.NameID] = append(skuNameMap[vv.NameID], vv.UnitPrice)
|
||
countryMap[vv.NameID] = append(countryMap[vv.NameID], vv.UnitPrice)
|
||
}
|
||
if citySkuMap[v.CityCode] != nil {
|
||
for nameID, unitPriceList := range skuNameMap {
|
||
if citySkuMap[v.CityCode][nameID] != nil {
|
||
citySkuMap[v.CityCode][nameID] = append(citySkuMap[v.CityCode][nameID], unitPriceList...)
|
||
} else {
|
||
citySkuMap[v.CityCode][nameID] = unitPriceList
|
||
}
|
||
}
|
||
} else {
|
||
citySkuMap[v.CityCode] = skuNameMap
|
||
}
|
||
}
|
||
}
|
||
for k, v := range countryMap {
|
||
var midUnitPrice int
|
||
var avgUnitPrice int
|
||
sort.Ints(v)
|
||
if len(v)%2 == 0 {
|
||
midUnitPrice = v[len(v)/2-1]
|
||
} else {
|
||
midUnitPrice = v[len(v)/2]
|
||
}
|
||
for _, vv := range v {
|
||
avgUnitPrice += vv
|
||
}
|
||
priceRefer := &model.PriceReferSnapshot{
|
||
MidUnitPrice: midUnitPrice,
|
||
MaxUnitPrice: v[len(v)-1],
|
||
MinUnitPrice: v[0],
|
||
AvgUnitPrice: avgUnitPrice / len(v),
|
||
}
|
||
resultCountryMap[k] = priceRefer
|
||
}
|
||
for k1, v := range citySkuMap {
|
||
skuNameMap := make(map[int]*model.PriceReferSnapshot)
|
||
for k2, _ := range v {
|
||
var midUnitPrice int
|
||
var avgUnitPrice int
|
||
sort.Ints(v[k2])
|
||
if len(v[k2])%2 == 0 {
|
||
midUnitPrice = v[k2][len(v[k2])/2-1]
|
||
} else {
|
||
midUnitPrice = v[k2][len(v[k2])/2]
|
||
}
|
||
for _, vv := range v[k2] {
|
||
avgUnitPrice += vv
|
||
}
|
||
skuNameMap[k2] = &model.PriceReferSnapshot{
|
||
MidUnitPrice: midUnitPrice,
|
||
MaxUnitPrice: v[k2][len(v[k2])-1],
|
||
MinUnitPrice: v[k2][0],
|
||
AvgUnitPrice: avgUnitPrice / len(v[k2]),
|
||
}
|
||
}
|
||
resultMap[k1] = skuNameMap
|
||
}
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil || err != nil {
|
||
dao.Rollback(db)
|
||
if r != nil {
|
||
panic(r)
|
||
}
|
||
}
|
||
}()
|
||
if len(priceReferSnapshotList) > 0 {
|
||
for _, v := range priceReferSnapshotList {
|
||
if v.CityCode == 0 {
|
||
if resultCountryMap[v.NameID] != nil {
|
||
v.MidUnitPrice = resultCountryMap[v.NameID].MidUnitPrice
|
||
v.MaxUnitPrice = resultCountryMap[v.NameID].MaxUnitPrice
|
||
v.AvgUnitPrice = resultCountryMap[v.NameID].AvgUnitPrice
|
||
v.MinUnitPrice = resultCountryMap[v.NameID].MinUnitPrice
|
||
dao.UpdateEntity(db, v, "MidUnitPrice", "MaxUnitPrice", "MinUnitPrice", "AvgUnitPrice")
|
||
}
|
||
continue
|
||
}
|
||
if resultMap[v.CityCode][v.NameID] != nil {
|
||
v.MidUnitPrice = resultMap[v.CityCode][v.NameID].MidUnitPrice
|
||
v.MaxUnitPrice = resultMap[v.CityCode][v.NameID].MaxUnitPrice
|
||
v.AvgUnitPrice = resultMap[v.CityCode][v.NameID].AvgUnitPrice
|
||
v.MinUnitPrice = resultMap[v.CityCode][v.NameID].MinUnitPrice
|
||
dao.UpdateEntity(db, v, "MidUnitPrice", "MaxUnitPrice", "MinUnitPrice", "AvgUnitPrice")
|
||
}
|
||
}
|
||
}
|
||
dao.Commit(db)
|
||
case 2:
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil || err != nil {
|
||
dao.Rollback(db)
|
||
if r != nil {
|
||
panic(r)
|
||
}
|
||
}
|
||
}()
|
||
if len(priceReferSnapshotList) > 0 {
|
||
for _, v := range priceReferSnapshotList {
|
||
result, _ := dao.GetPriceReferPrice(db, v.CityCode, v.SkuID, snapshotAt)
|
||
v.MaxPrice = result.MaxPrice
|
||
v.MinPrice = result.MinPrice
|
||
v.AvgPrice = result.AvgPrice
|
||
v.MidPrice = result.MidPrice
|
||
dao.UpdateEntity(db, v, "MidPrice", "MaxPrice", "MinPrice", "AvgPrice")
|
||
}
|
||
}
|
||
dao.Commit(db)
|
||
//TODO 京东查询接口报错,暂时屏蔽了
|
||
// case 3:
|
||
// priceReferSnapshotList, err = dao.GetPriceReferSnapshotNoPage(db, []int{0}, nil, nil, snapshotAt)
|
||
// taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
// v := batchItemList[0].(*model.PriceReferSnapshot)
|
||
// for _, appOrg := range apimanager.CurAPIManager.GetAppOrgCodeList(model.VendorIDJD) {
|
||
// directPrice, _ := jd.GetAPI(appOrg).GetJdSkuDirectPrice(v.SkuID)
|
||
// v.JdDirectPrice = int(directPrice)
|
||
// dao.UpdateEntity(db, v, "JdDirectPrice")
|
||
// }
|
||
// return retVal, err
|
||
// }
|
||
// taskParallel := tasksch.NewParallelTask("获取并更新京东指导价格", tasksch.NewParallelConfig(), ctx, taskFunc, priceReferSnapshotList)
|
||
// tasksch.HandleTask(taskParallel, task, true).Run()
|
||
// _, err = taskParallel.GetResult(0)
|
||
}
|
||
return result, err
|
||
}
|
||
taskSeq := tasksch.NewSeqTask2("生成每日价格统计", ctx, isContinueWhenError, taskSeqFunc, 3)
|
||
tasksch.HandleTask(taskSeq, nil, true).Run()
|
||
if !isAsync {
|
||
_, err = taskSeq.GetResult(0)
|
||
hint = "1"
|
||
} else {
|
||
hint = taskSeq.GetID()
|
||
}
|
||
return hint, err
|
||
}
|