feat(order): 添加订单汇总功能- 新增 OrderSummaryOutput 结构体用于订单汇总信息
- 实现 GetOrderRawSummary 和 GetOrderProfitRawSummary 函数获取订单汇总数据 - 重构 QueryTotalSummary 和 QueryTodaySummary 函数,使用新的汇总查询逻辑 - 优化订单查询参数处理,支持模糊匹配和自定义字段筛选
This commit is contained in:
@@ -782,8 +782,8 @@ func (c *GetController) GetOrder() {
|
|||||||
params["create_time__gte"] = startTime
|
params["create_time__gte"] = startTime
|
||||||
params["create_time__lte"] = endTime
|
params["create_time__lte"] = endTime
|
||||||
params["merchant_name__icontains"] = merchantName
|
params["merchant_name__icontains"] = merchantName
|
||||||
params["merchant_order_id"] = orderNo
|
params["merchant_order_id__icontains"] = orderNo
|
||||||
params["bank_order_id"] = bankOrderId
|
params["bank_order_id__icontains"] = bankOrderId
|
||||||
params["status"] = status
|
params["status"] = status
|
||||||
params["pay_product_code"] = supplierUid
|
params["pay_product_code"] = supplierUid
|
||||||
params["pay_type_code"] = payWayCode
|
params["pay_type_code"] = payWayCode
|
||||||
@@ -922,18 +922,21 @@ func (c *GetController) GetOrderSummary() {
|
|||||||
freeStatus := strings.TrimSpace(c.GetString("freeStatus"))
|
freeStatus := strings.TrimSpace(c.GetString("freeStatus"))
|
||||||
cardData := strings.TrimSpace(c.GetString("cardData"))
|
cardData := strings.TrimSpace(c.GetString("cardData"))
|
||||||
roadUid := strings.TrimSpace(c.GetString("roadUid"))
|
roadUid := strings.TrimSpace(c.GetString("roadUid"))
|
||||||
|
message := strings.TrimSpace(c.GetString("message"))
|
||||||
|
|
||||||
params := make(map[string]string)
|
params := make(map[string]string)
|
||||||
params["create_time__gte"] = startTime
|
params["create_time__gte"] = startTime
|
||||||
params["create_time__lte"] = endTime
|
params["create_time__lte"] = endTime
|
||||||
params["merchant_name__icontains"] = merchantName
|
params["merchant_name__icontains"] = merchantName
|
||||||
params["merchant_order_id"] = orderNo
|
params["merchant_order_id__icontains"] = orderNo
|
||||||
params["bank_order_id"] = bankOrderId
|
params["bank_order_id__icontains"] = bankOrderId
|
||||||
params["status"] = status
|
params["status"] = status
|
||||||
params["pay_product_code"] = supplierUid
|
params["pay_product_code"] = supplierUid
|
||||||
params["pay_type_code"] = payWayCode
|
params["pay_type_code"] = payWayCode
|
||||||
params["ex_value__icontains"] = cardData
|
params["ex_value__icontains"] = cardData
|
||||||
params["road_uid"] = roadUid
|
params["road_uid"] = roadUid
|
||||||
|
params["card_return_data__icontains"] = message
|
||||||
|
|
||||||
switch freeStatus {
|
switch freeStatus {
|
||||||
case "free":
|
case "free":
|
||||||
params["free"] = "yes"
|
params["free"] = "yes"
|
||||||
|
|||||||
17
internal/models/order/model.go
Normal file
17
internal/models/order/model.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package order
|
||||||
|
|
||||||
|
//road_uid,
|
||||||
|
//SUM(order_amount) AS total_order_amount,
|
||||||
|
//COUNT(id) AS total_order_count,
|
||||||
|
//SUM(CASE WHEN STATUS = 'success' THEN order_amount ELSE 0 END) AS success_fact_amount,
|
||||||
|
//SUM(CASE WHEN STATUS = 'success' THEN 1 ELSE 0 END) AS success_fact_count,
|
||||||
|
//SUM(CASE WHEN STATUS = 'success' THEN 1 ELSE 0 END) / COUNT(id) AS success_fact_avg
|
||||||
|
|
||||||
|
type OrderSummaryOutput struct {
|
||||||
|
RoadUid string `json:"road_uid" orm:"road_uid"`
|
||||||
|
TotalOrderAmount float64 `json:"total_order_amount" orm:"total_order_amount"`
|
||||||
|
TotalOrderCount int64 `json:"total_order_count" orm:"total_order_count"`
|
||||||
|
SuccessFactAmount float64 `json:"success_fact_amount" orm:"success_fact_amount"`
|
||||||
|
SuccessFactCount int64 `json:"success_fact_count" orm:"success_fact_count"`
|
||||||
|
SuccessFactAvg float64 `json:"success_fact_avg" orm:"success_fact_avg"`
|
||||||
|
}
|
||||||
@@ -2,8 +2,10 @@ package order
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/beego/beego/v2/client/orm"
|
"github.com/beego/beego/v2/client/orm"
|
||||||
@@ -132,6 +134,114 @@ func GetOrderCountByMap(ctx context.Context, params map[string]string) (count in
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetOrderRawSummary(ctx context.Context, params map[string]string) (data []OrderSummaryOutput, err error) {
|
||||||
|
o := orm.NewOrm()
|
||||||
|
sql := `SELECT
|
||||||
|
road_uid,
|
||||||
|
SUM(order_amount) AS total_order_amount,
|
||||||
|
COUNT(id) AS total_order_count,
|
||||||
|
SUM(CASE WHEN STATUS = 'success' THEN order_amount ELSE 0 END) AS success_fact_amount,
|
||||||
|
SUM(CASE WHEN STATUS = 'success' THEN 1 ELSE 0 END) AS success_fact_count,
|
||||||
|
SUM(CASE WHEN STATUS = 'success' THEN 1 ELSE 0 END) / COUNT(id) AS success_fact_avg
|
||||||
|
FROM
|
||||||
|
order_info
|
||||||
|
`
|
||||||
|
if len(params) > 0 {
|
||||||
|
subSQL := ""
|
||||||
|
for k, v := range params {
|
||||||
|
if v == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch k {
|
||||||
|
case "create_time__gte":
|
||||||
|
subSQL += fmt.Sprintf("create_time >= '%s' AND ", v)
|
||||||
|
case "create_time__lte":
|
||||||
|
subSQL += fmt.Sprintf("create_time <= '%s' AND ", v)
|
||||||
|
case "merchant_name__icontains":
|
||||||
|
subSQL += fmt.Sprintf("merchant_name LIKE '%%%s%%' AND ", v)
|
||||||
|
case "merchant_order_id__icontains":
|
||||||
|
subSQL += fmt.Sprintf("merchant_order_id LIKE '%%%s%%' AND ", v)
|
||||||
|
case "bank_order_id__icontains":
|
||||||
|
subSQL += fmt.Sprintf("bank_order_id LIKE '%%%s%%' AND ", v)
|
||||||
|
case "card_return_data__icontains":
|
||||||
|
subSQL += fmt.Sprintf("card_return_data LIKE '%%%s%%' AND ", v)
|
||||||
|
case "ex_value__icontains":
|
||||||
|
subSQL += fmt.Sprintf("ex_value LIKE '%%%s%%' AND ", v)
|
||||||
|
default:
|
||||||
|
if !strings.Contains(k, "__") {
|
||||||
|
subSQL += fmt.Sprintf("%s = '%s' AND ", k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(subSQL) > 0 {
|
||||||
|
sql += "WHERE " + subSQL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sql = strings.TrimRight(sql, " AND ")
|
||||||
|
sql += `
|
||||||
|
GROUP BY
|
||||||
|
road_uid`
|
||||||
|
logs.Error(sql)
|
||||||
|
_, err = o.RawWithCtx(ctx, sql).QueryRows(&data)
|
||||||
|
if errors.Is(err, orm.ErrNoRows) {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetOrderProfitRawSummary(ctx context.Context, params map[string]string) (platformProfit float64, err error) {
|
||||||
|
o := orm.NewOrm()
|
||||||
|
|
||||||
|
sql := `
|
||||||
|
SELECT
|
||||||
|
SUM(platform_profit) AS platform_profit
|
||||||
|
FROM
|
||||||
|
order_profit_info
|
||||||
|
LEFT JOIN order_info ON order_profit_info.bank_order_id = order_info.bank_order_id
|
||||||
|
WHERE
|
||||||
|
order_info.status='success' AND `
|
||||||
|
if len(params) > 0 {
|
||||||
|
subSQL := ""
|
||||||
|
for k, v := range params {
|
||||||
|
if v == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch k {
|
||||||
|
case "create_time__gte":
|
||||||
|
subSQL += fmt.Sprintf("order_profit_info.create_time >= '%s' AND ", v)
|
||||||
|
case "create_time__lte":
|
||||||
|
subSQL += fmt.Sprintf("order_profit_info.create_time <= '%s' AND ", v)
|
||||||
|
case "merchant_name__icontains":
|
||||||
|
subSQL += fmt.Sprintf("order_profit_info.merchant_name LIKE '%%%s%%' AND ", v)
|
||||||
|
case "merchant_order_id__icontains":
|
||||||
|
subSQL += fmt.Sprintf("order_info.merchant_order_id = '%%%s%%' AND ", v)
|
||||||
|
case "bank_order_id__icontains":
|
||||||
|
subSQL += fmt.Sprintf("order_info.bank_order_id LIKE '%%%s%%' AND ", v)
|
||||||
|
case "ex_value__icontains":
|
||||||
|
subSQL += fmt.Sprintf("order_info.ex_value LIKE '%%%s%%' AND ", v)
|
||||||
|
default:
|
||||||
|
if !strings.Contains(k, "__") {
|
||||||
|
subSQL += fmt.Sprintf("%s = '%s' AND ", k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(subSQL) > 0 {
|
||||||
|
sql += subSQL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sql = strings.TrimRight(sql, " AND ")
|
||||||
|
sql += `
|
||||||
|
GROUP BY
|
||||||
|
road_uid`
|
||||||
|
logs.Error(sql)
|
||||||
|
platformProfit = 0.0
|
||||||
|
err = o.RawWithCtx(ctx, sql).QueryRow(&platformProfit)
|
||||||
|
if errors.Is(err, orm.ErrNoRows) {
|
||||||
|
return 0.0, nil
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetOrderAllByMap(ctx context.Context, params map[string]string) []OrderInfo {
|
func GetOrderAllByMap(ctx context.Context, params map[string]string) []OrderInfo {
|
||||||
o := orm.NewOrm()
|
o := orm.NewOrm()
|
||||||
var orderInfoList []OrderInfo
|
var orderInfoList []OrderInfo
|
||||||
|
|||||||
@@ -100,48 +100,28 @@ func querySupplierPayForResult(ctx context.Context, bankOrderId string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func QueryTotalSummary(ctx context.Context, params map[string]string) order.Summary {
|
func QueryTotalSummary(ctx context.Context, params map[string]string) order.Summary {
|
||||||
supplierAll := 0.0
|
summaryInfos, err := order.GetOrderRawSummary(ctx, params)
|
||||||
platformAll := 0.0
|
if err != nil {
|
||||||
agentAll := 0.0
|
logs.Error("获取订单汇总信息失败:", err)
|
||||||
allAmount := 0.0
|
|
||||||
succeedNum := int64(0)
|
|
||||||
succeedPaidAmount := 0.0
|
|
||||||
|
|
||||||
totalNum := order.GetOrderCountByMap(ctx, params)
|
|
||||||
|
|
||||||
for i := int64(0); i < totalNum; i += 1000 {
|
|
||||||
orderInfoList := order.GetOrderByMap(ctx, params, 1000, i)
|
|
||||||
bankIdList := slice.Map(orderInfoList, func(index int, item order.OrderInfo) string {
|
|
||||||
return item.BankOrderId
|
|
||||||
})
|
|
||||||
orderProfitList := order.GetOrderProfitListByBankOrderIdList(ctx, bankIdList)
|
|
||||||
for _, v := range orderProfitList {
|
|
||||||
allAmount += v.ShowAmount //订单总金额
|
|
||||||
if v.Status != common.OrderStatusSuccess {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
succeedNum += 1
|
|
||||||
succeedPaidAmount += v.FactAmount
|
|
||||||
supplierAll += v.SupplierProfit //上游利润
|
|
||||||
platformAll += v.PlatformProfit //平台利润
|
|
||||||
agentAll += v.AgentProfit //代理利润
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
succeedRate := 0.0
|
profit, err := order.GetOrderProfitRawSummary(ctx, params)
|
||||||
if totalNum != 0 {
|
if err != nil {
|
||||||
succeedRate = math.Round(float64(succeedNum)/float64(totalNum)*100*100) / 100
|
logs.Error("获取订单利润信息失败:", err)
|
||||||
|
}
|
||||||
|
output := order.Summary{}
|
||||||
|
slice.ForEach(summaryInfos, func(index int, item order.OrderSummaryOutput) {
|
||||||
|
output.TotalAmount += item.TotalOrderAmount
|
||||||
|
output.TotalNum += item.TotalOrderCount
|
||||||
|
output.PaidNum += item.SuccessFactCount
|
||||||
|
output.PaidAmount += item.SuccessFactAmount
|
||||||
|
})
|
||||||
|
if output.TotalNum == 0 {
|
||||||
|
output.SucceedRate = 0
|
||||||
} else {
|
} else {
|
||||||
succeedRate = 0
|
output.SucceedRate = math.Round(float64(output.PaidNum)/float64(output.TotalNum)*100*100) / 100
|
||||||
}
|
}
|
||||||
return order.Summary{
|
output.PlatformIncome = profit
|
||||||
TotalNum: totalNum,
|
return output
|
||||||
TotalAmount: math.Round(allAmount*100) / 100,
|
|
||||||
PaidNum: succeedNum,
|
|
||||||
PaidAmount: math.Round(succeedPaidAmount*100) / 100,
|
|
||||||
PlatformIncome: math.Round(platformAll*100) / 100,
|
|
||||||
SucceedRate: succeedRate,
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func QuerySummaryByOrderInfo(ctx context.Context, infoInfoList []order.OrderInfo) order.Summary {
|
func QuerySummaryByOrderInfo(ctx context.Context, infoInfoList []order.OrderInfo) order.Summary {
|
||||||
@@ -193,7 +173,7 @@ func QuerySummaryByOrderInfo(ctx context.Context, infoInfoList []order.OrderInfo
|
|||||||
func QueryTodaySummary(ctx context.Context, params map[string]string) order.Summary {
|
func QueryTodaySummary(ctx context.Context, params map[string]string) order.Summary {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
todayAtMidnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
todayAtMidnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||||||
tomorrowAtMidNight := time.Date(now.Year(), now.Month(), now.Day(), 59, 59, 59, 0, now.Location())
|
tomorrowAtMidNight := todayAtMidnight.Add(time.Hour * 24)
|
||||||
|
|
||||||
st := todayAtMidnight.Format("2006-01-02 15:04:05")
|
st := todayAtMidnight.Format("2006-01-02 15:04:05")
|
||||||
end := tomorrowAtMidNight.Format("2006-01-02 15:04:05")
|
end := tomorrowAtMidNight.Format("2006-01-02 15:04:05")
|
||||||
@@ -225,46 +205,70 @@ func QueryTodaySummary(ctx context.Context, params map[string]string) order.Summ
|
|||||||
paramsProfit["create_time__lte"] = end
|
paramsProfit["create_time__lte"] = end
|
||||||
}
|
}
|
||||||
|
|
||||||
todaySuccessNum := 0
|
summaryInfos, err := order.GetOrderRawSummary(ctx, paramsProfit)
|
||||||
todayAllAmount := 0.0
|
if err != nil {
|
||||||
todaySupplierAll := 0.0
|
logs.Error("获取订单汇总信息失败:", err)
|
||||||
todayPlatformAll := 0.0
|
}
|
||||||
todayAgentAll := 0.0
|
profit, err := order.GetOrderProfitRawSummary(ctx, params)
|
||||||
todayPaidAmount := 0.0
|
if err != nil {
|
||||||
|
logs.Error("获取订单利润信息失败:", err)
|
||||||
|
}
|
||||||
|
output := order.Summary{}
|
||||||
|
slice.ForEach(summaryInfos, func(index int, item order.OrderSummaryOutput) {
|
||||||
|
output.TotalAmount += item.TotalOrderAmount
|
||||||
|
output.TotalNum += item.TotalOrderCount
|
||||||
|
output.PaidNum += item.SuccessFactCount
|
||||||
|
output.PaidAmount += item.SuccessFactAmount
|
||||||
|
})
|
||||||
|
if output.TotalNum == 0 {
|
||||||
|
output.SucceedRate = 0
|
||||||
|
} else {
|
||||||
|
output.SucceedRate = math.Round(float64(output.PaidNum)/float64(output.TotalNum)*100*100) / 100
|
||||||
|
}
|
||||||
|
output.PlatformIncome = profit
|
||||||
|
return output
|
||||||
|
|
||||||
totalNum := order.GetOrderCountByMap(ctx, paramsProfit)
|
//
|
||||||
for i := int64(0); i < totalNum; i += 1000 {
|
//todaySuccessNum := 0
|
||||||
orderInfoList := order.GetOrderByMap(ctx, paramsProfit, 1000, i)
|
//todayAllAmount := 0.0
|
||||||
bankIdList := slice.Map(orderInfoList, func(index int, item order.OrderInfo) string {
|
//todaySupplierAll := 0.0
|
||||||
return item.BankOrderId
|
//todayPlatformAll := 0.0
|
||||||
})
|
//todayAgentAll := 0.0
|
||||||
dataInfo := order.GetOrderProfitListByBankOrderIdList(ctx, bankIdList)
|
//todayPaidAmount := 0.0
|
||||||
for _, info := range dataInfo {
|
//
|
||||||
todayAllAmount += info.FactAmount
|
//totalNum := order.GetOrderCountByMap(ctx, paramsProfit)
|
||||||
if info.Status != common.OrderStatusSuccess {
|
//for i := int64(0); i < totalNum; i += 1000 {
|
||||||
continue
|
// orderInfoList := order.GetOrderByMap(ctx, paramsProfit, 1000, i)
|
||||||
}
|
// bankIdList := slice.Map(orderInfoList, func(index int, item order.OrderInfo) string {
|
||||||
todaySupplierAll += info.SupplierProfit
|
// return item.BankOrderId
|
||||||
todayPlatformAll += info.PlatformProfit
|
// })
|
||||||
todayAgentAll += info.AgentProfit
|
// dataInfo := order.GetOrderProfitListByBankOrderIdList(ctx, bankIdList)
|
||||||
todayPaidAmount += info.FactAmount
|
// for _, info := range dataInfo {
|
||||||
todaySuccessNum += 1
|
// todayAllAmount += info.FactAmount
|
||||||
}
|
// if info.Status != common.OrderStatusSuccess {
|
||||||
}
|
// continue
|
||||||
|
// }
|
||||||
succeedRate := 0.0
|
// todaySupplierAll += info.SupplierProfit
|
||||||
if totalNum != 0 {
|
// todayPlatformAll += info.PlatformProfit
|
||||||
succeedRate = math.Round(float64(todaySuccessNum)/float64(totalNum)*100*100) / 100
|
// todayAgentAll += info.AgentProfit
|
||||||
}
|
// todayPaidAmount += info.FactAmount
|
||||||
return order.Summary{
|
// todaySuccessNum += 1
|
||||||
TotalNum: int64(totalNum),
|
// }
|
||||||
TotalAmount: math.Round(todayAllAmount*100) / 100,
|
//}
|
||||||
PaidNum: int64(todaySuccessNum),
|
//
|
||||||
PaidAmount: todayPaidAmount,
|
//succeedRate := 0.0
|
||||||
PlatformIncome: math.Round(todayPlatformAll*100) / 100,
|
//if totalNum != 0 {
|
||||||
AgencyIncome: todayAgentAll,
|
// succeedRate = math.Round(float64(todaySuccessNum)/float64(totalNum)*100*100) / 100
|
||||||
SucceedRate: succeedRate,
|
//}
|
||||||
}
|
//return order.Summary{
|
||||||
|
// TotalNum: int64(totalNum),
|
||||||
|
// TotalAmount: math.Round(todayAllAmount*100) / 100,
|
||||||
|
// PaidNum: int64(todaySuccessNum),
|
||||||
|
// PaidAmount: todayPaidAmount,
|
||||||
|
// PlatformIncome: math.Round(todayPlatformAll*100) / 100,
|
||||||
|
// AgencyIncome: todayAgentAll,
|
||||||
|
// SucceedRate: succeedRate,
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidTotp(ctx context.Context, accountUid, totpCode string) bool {
|
func ValidTotp(ctx context.Context, accountUid, totpCode string) bool {
|
||||||
|
|||||||
@@ -198,7 +198,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span>产品名称: </span>
|
<span>产品名称:</span>
|
||||||
<label>
|
<label>
|
||||||
<select id="product-name">
|
<select id="product-name">
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
Reference in New Issue
Block a user