城市商品销量统计
This commit is contained in:
125
business/jxstore/misc/store_sku_sales.go
Normal file
125
business/jxstore/misc/store_sku_sales.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package misc
|
||||
|
||||
import (
|
||||
"math"
|
||||
"sync"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
const (
|
||||
DayNum = 30 //请求天数
|
||||
LimitNum = 100 //最大数据限制
|
||||
)
|
||||
|
||||
func GetStoreSkuSalesInfo(ctx *jxcontext.Context, storeID int) (outStoreSkuSales []*model.StoreSkuSales, err error) {
|
||||
db := dao.GetDB()
|
||||
//得到所有门店
|
||||
storeList, _ := GetStoreList(ctx)
|
||||
storeList = GetFilterStoreListEx(storeList, nil)
|
||||
storeMapData := make(map[int]*cms.StoreExt)
|
||||
for _, value := range storeList {
|
||||
storeMapData[value.ID] = value
|
||||
}
|
||||
curStoreInfo := storeMapData[storeID]
|
||||
cityCode := curStoreInfo.CityCode
|
||||
|
||||
//获取本市商品总销量
|
||||
citySkuSalesCntMap := make(map[int]int)
|
||||
citySkuSalesCntList, _ := dao.GetSkuSalesCntList(db, -1, cityCode, DayNum, LimitNum, nil)
|
||||
citySkuIDs := []int{}
|
||||
for _, value := range citySkuSalesCntList {
|
||||
citySkuSalesCntMap[value.SkuID] = value.Count
|
||||
citySkuIDs = append(citySkuIDs, value.SkuID)
|
||||
}
|
||||
|
||||
//获取本店商品总销量
|
||||
storeSkuSalesCntMap := make(map[int]int)
|
||||
storeSkuSalesCntList, _ := dao.GetSkuSalesCntList(db, storeID, cityCode, DayNum, -1, citySkuIDs)
|
||||
for _, value := range storeSkuSalesCntList {
|
||||
storeSkuSalesCntMap[value.SkuID] = value.Count
|
||||
}
|
||||
|
||||
//获取本店商品差评数量
|
||||
storeSkuBadCommentCntMap := make(map[int]int)
|
||||
storeSkuBadCommentCntList, _ := dao.GetSkuBadCommentCntList(db, storeID, DayNum)
|
||||
for _, value := range storeSkuBadCommentCntList {
|
||||
storeSkuBadCommentCntMap[value.SkuID] = value.Count
|
||||
}
|
||||
|
||||
//得到当前门店商品数据
|
||||
storeSkuData, _ := cms.GetStoreSkus(ctx, storeID, citySkuIDs, true, "", true, map[string]interface{}{}, 0, -1)
|
||||
storeSkuMapData := make(map[int]*cms.StoreSkuNameExt)
|
||||
for _, value := range storeSkuData.SkuNames {
|
||||
for _, skuInfo := range value.Skus2 {
|
||||
storeSkuMapData[skuInfo.SkuID] = value
|
||||
}
|
||||
}
|
||||
|
||||
//得到5KM内的所有门店
|
||||
rangeStoreList := GetRangeStoreList(storeID, curStoreInfo.FloatLng, curStoreInfo.FloatLat, SaleSkuCheckRange, storeList)
|
||||
|
||||
//得到5KM内的所有门店的商品的价格
|
||||
allStoreSkus := make(map[int]map[int]int)
|
||||
var locker sync.RWMutex
|
||||
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, citySkuIDs, true, "", true, map[string]interface{}{}, 0, -1)
|
||||
jxSkuPriceMapData := make(map[int]int)
|
||||
for _, value := range jxSkuInfoData.SkuNames {
|
||||
for _, skuInfo := range value.Skus2 {
|
||||
jxSkuPriceMapData[skuInfo.SkuID] = skuInfo.BindPrice
|
||||
}
|
||||
}
|
||||
locker.Lock()
|
||||
defer locker.Unlock()
|
||||
allStoreSkus[storeID] = jxSkuPriceMapData
|
||||
return retVal, err
|
||||
}
|
||||
taskParallel := tasksch.NewParallelTask("得到所有门店商品", nil, ctx, taskFunc, rangeStoreList)
|
||||
taskParallel.Run()
|
||||
taskParallel.GetResult(0)
|
||||
|
||||
//计算商品的平均价格
|
||||
skusTotalPrice := make(map[int]int)
|
||||
skusCount := make(map[int]int)
|
||||
skusAveragePrice := make(map[int]int)
|
||||
for _, storeInfo := range rangeStoreList {
|
||||
storeID := storeInfo.ID
|
||||
storeSkuMapData := allStoreSkus[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])))
|
||||
}
|
||||
|
||||
//输出商品销量统计结果
|
||||
for _, value := range citySkuSalesCntList {
|
||||
skuID := value.SkuID
|
||||
if _, ok := storeSkuSalesCntMap[skuID]; ok {
|
||||
storeSkuSales := &model.StoreSkuSales{}
|
||||
storeSkuSales.SkuID = skuID
|
||||
skuInfo := storeSkuMapData[skuID]
|
||||
if skuInfo != nil {
|
||||
storeSkuSales.SkuName = skuInfo.Name
|
||||
storeSkuSales.SkuPrice = jxutils.IntPrice2StandardCurrencyString(int64(skuInfo.Skus2[0].BindPrice))
|
||||
storeSkuSales.SkuAvgPrice = jxutils.IntPrice2StandardCurrencyString(int64(skusAveragePrice[skuID]))
|
||||
storeSkuSales.BadCommentCnt = storeSkuBadCommentCntMap[skuID]
|
||||
storeSkuSales.StoreSkuSalesCnt = storeSkuSalesCntMap[skuID]
|
||||
storeSkuSales.CitySkuSalesCnt = citySkuSalesCntMap[skuID]
|
||||
outStoreSkuSales = append(outStoreSkuSales, storeSkuSales)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return outStoreSkuSales, err
|
||||
}
|
||||
69
business/model/dao/store_sku_sales.go
Normal file
69
business/model/dao/store_sku_sales.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
)
|
||||
|
||||
func GetSkuSalesCntList(db *DaoDB, storeID, cityCode, dayNum, limit int, skuIDs []int) (skuCountList []*model.SkuCount, err error) {
|
||||
sql := `
|
||||
SELECT t2.jx_sku_id sku_id, SUM(t2.count) count
|
||||
FROM goods_order t1
|
||||
JOIN order_sku t2 on t1.vendor_order_id = t2.vendor_order_id and t1.vendor_id = t2.vendor_id
|
||||
JOIN store t3 on t1.jx_store_id = t3.id
|
||||
WHERE DATE(t1.order_finished_at) BETWEEN DATE_SUB(CURDATE(), INTERVAL ? DAY) and CURDATE()
|
||||
AND t1.status = ?
|
||||
AND t2.jx_sku_id <> 0
|
||||
AND t3.city_code = ?
|
||||
`
|
||||
if dayNum < 0 {
|
||||
dayNum = 30
|
||||
}
|
||||
sqlParams := []interface{}{
|
||||
dayNum - 1,
|
||||
model.OrderStatusFinished,
|
||||
cityCode,
|
||||
}
|
||||
if storeID > 0 {
|
||||
sql += `
|
||||
AND t1.jx_store_id = ?
|
||||
`
|
||||
sqlParams = append(sqlParams, storeID)
|
||||
}
|
||||
if len(skuIDs) > 0 {
|
||||
sql += `
|
||||
AND t2.jx_sku_id IN (` + GenQuestionMarks(len(skuIDs)) + `)`
|
||||
sqlParams = append(sqlParams, skuIDs)
|
||||
}
|
||||
sql += `
|
||||
GROUP BY jx_sku_id
|
||||
ORDER BY count DESC
|
||||
`
|
||||
if limit > 0 {
|
||||
sql += `
|
||||
LIMIT ?
|
||||
`
|
||||
sqlParams = append(sqlParams, limit)
|
||||
}
|
||||
err = GetRows(db, &skuCountList, sql, sqlParams)
|
||||
return skuCountList, err
|
||||
}
|
||||
|
||||
func GetSkuBadCommentCntList(db *DaoDB, storeID, dayNum int) (skuCountList []*model.SkuCount, err error) {
|
||||
sql := `
|
||||
SELECT t2.jx_sku_id sku_id, COUNT(*) count
|
||||
FROM jx_bad_comments t1
|
||||
JOIN order_sku t2 ON t1.order_id = t2.vendor_order_id
|
||||
WHERE DATE(t1.createtime) BETWEEN DATE_SUB(CURDATE(), INTERVAL ? DAY) and CURDATE()
|
||||
AND t1.jxstoreid = ?
|
||||
GROUP BY t2.jx_sku_id
|
||||
`
|
||||
if dayNum < 0 {
|
||||
dayNum = 30
|
||||
}
|
||||
sqlParams := []interface{}{
|
||||
dayNum - 1,
|
||||
storeID,
|
||||
}
|
||||
err = GetRows(db, &skuCountList, sql, sqlParams)
|
||||
return skuCountList, err
|
||||
}
|
||||
16
business/model/store_sku_sales.go
Normal file
16
business/model/store_sku_sales.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package model
|
||||
|
||||
type StoreSkuSales struct {
|
||||
SkuID int `json:"skuID"`
|
||||
SkuName string `json:"skuName"`
|
||||
SkuPrice string `json:"skuPrice"`
|
||||
SkuAvgPrice string `json:"skuAvgPrice"`
|
||||
BadCommentCnt int `json:"badCommentCnt"`
|
||||
StoreSkuSalesCnt int `json:"storeSkuSalesCnt"`
|
||||
CitySkuSalesCnt int `json:"citySkuSalesCnt"`
|
||||
}
|
||||
|
||||
type SkuCount struct {
|
||||
SkuID int `orm:"column(sku_id)"`
|
||||
Count int
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package controllers
|
||||
import (
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"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/model"
|
||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||
@@ -359,3 +360,17 @@ func (c *SkuController) SortCategorySkus() {
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 按照当前城市近30天销量排序,显示本店价格,附近5公里平均价格,差评数量,本店销量情况,本市总销量,
|
||||
// @Description 按照当前城市近30天销量排序,显示本店价格,附近5公里平均价格,差评数量,本店销量情况,本市总销量,
|
||||
// @Param token header string true "认证token"
|
||||
// @Param storeID query int true "京西门店ID"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetStoreSkuSalesInfo [get]
|
||||
func (c *SkuController) GetStoreSkuSalesInfo() {
|
||||
c.callGetStoreSkuSalesInfo(func(params *tSkuGetStoreSkuSalesInfoParams) (retVal interface{}, errCode string, err error) {
|
||||
retVal, err = misc.GetStoreSkuSalesInfo(params.Ctx, params.StoreID)
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1161,6 +1161,15 @@ func init() {
|
||||
Filters: nil,
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"],
|
||||
beego.ControllerComments{
|
||||
Method: "GetStoreSkuSalesInfo",
|
||||
Router: `/GetStoreSkuSalesInfo`,
|
||||
AllowHTTPMethods: []string{"get"},
|
||||
MethodParams: param.Make(),
|
||||
Filters: nil,
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"],
|
||||
beego.ControllerComments{
|
||||
Method: "GetVendorCategories",
|
||||
|
||||
Reference in New Issue
Block a user