diff --git a/business/jxstore/misc/store_sku_sales.go b/business/jxstore/misc/store_sku_sales.go new file mode 100644 index 000000000..50ece6a35 --- /dev/null +++ b/business/jxstore/misc/store_sku_sales.go @@ -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 +} diff --git a/business/model/dao/store_sku_sales.go b/business/model/dao/store_sku_sales.go new file mode 100644 index 000000000..0f9f4e999 --- /dev/null +++ b/business/model/dao/store_sku_sales.go @@ -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 +} diff --git a/business/model/store_sku_sales.go b/business/model/store_sku_sales.go new file mode 100644 index 000000000..909a7f574 --- /dev/null +++ b/business/model/store_sku_sales.go @@ -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 +} diff --git a/controllers/cms_sku.go b/controllers/cms_sku.go index af1750251..11e26496c 100644 --- a/controllers/cms_sku.go +++ b/controllers/cms_sku.go @@ -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 + }) +} diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index 5baa4b15a..ce7539ee3 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -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",