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__lte"] = endTime
|
||||
params["merchant_name__icontains"] = merchantName
|
||||
params["merchant_order_id"] = orderNo
|
||||
params["bank_order_id"] = bankOrderId
|
||||
params["merchant_order_id__icontains"] = orderNo
|
||||
params["bank_order_id__icontains"] = bankOrderId
|
||||
params["status"] = status
|
||||
params["pay_product_code"] = supplierUid
|
||||
params["pay_type_code"] = payWayCode
|
||||
@@ -922,18 +922,21 @@ func (c *GetController) GetOrderSummary() {
|
||||
freeStatus := strings.TrimSpace(c.GetString("freeStatus"))
|
||||
cardData := strings.TrimSpace(c.GetString("cardData"))
|
||||
roadUid := strings.TrimSpace(c.GetString("roadUid"))
|
||||
message := strings.TrimSpace(c.GetString("message"))
|
||||
|
||||
params := make(map[string]string)
|
||||
params["create_time__gte"] = startTime
|
||||
params["create_time__lte"] = endTime
|
||||
params["merchant_name__icontains"] = merchantName
|
||||
params["merchant_order_id"] = orderNo
|
||||
params["bank_order_id"] = bankOrderId
|
||||
params["merchant_order_id__icontains"] = orderNo
|
||||
params["bank_order_id__icontains"] = bankOrderId
|
||||
params["status"] = status
|
||||
params["pay_product_code"] = supplierUid
|
||||
params["pay_type_code"] = payWayCode
|
||||
params["ex_value__icontains"] = cardData
|
||||
params["road_uid"] = roadUid
|
||||
params["card_return_data__icontains"] = message
|
||||
|
||||
switch freeStatus {
|
||||
case "free":
|
||||
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 (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
@@ -132,6 +134,114 @@ func GetOrderCountByMap(ctx context.Context, params map[string]string) (count in
|
||||
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 {
|
||||
o := orm.NewOrm()
|
||||
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 {
|
||||
supplierAll := 0.0
|
||||
platformAll := 0.0
|
||||
agentAll := 0.0
|
||||
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 //代理利润
|
||||
}
|
||||
summaryInfos, err := order.GetOrderRawSummary(ctx, params)
|
||||
if err != nil {
|
||||
logs.Error("获取订单汇总信息失败:", err)
|
||||
}
|
||||
succeedRate := 0.0
|
||||
if totalNum != 0 {
|
||||
succeedRate = math.Round(float64(succeedNum)/float64(totalNum)*100*100) / 100
|
||||
profit, err := order.GetOrderProfitRawSummary(ctx, params)
|
||||
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 {
|
||||
succeedRate = 0
|
||||
output.SucceedRate = math.Round(float64(output.PaidNum)/float64(output.TotalNum)*100*100) / 100
|
||||
}
|
||||
return order.Summary{
|
||||
TotalNum: totalNum,
|
||||
TotalAmount: math.Round(allAmount*100) / 100,
|
||||
PaidNum: succeedNum,
|
||||
PaidAmount: math.Round(succeedPaidAmount*100) / 100,
|
||||
PlatformIncome: math.Round(platformAll*100) / 100,
|
||||
SucceedRate: succeedRate,
|
||||
}
|
||||
|
||||
output.PlatformIncome = profit
|
||||
return output
|
||||
}
|
||||
|
||||
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 {
|
||||
now := time.Now()
|
||||
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")
|
||||
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
|
||||
}
|
||||
|
||||
todaySuccessNum := 0
|
||||
todayAllAmount := 0.0
|
||||
todaySupplierAll := 0.0
|
||||
todayPlatformAll := 0.0
|
||||
todayAgentAll := 0.0
|
||||
todayPaidAmount := 0.0
|
||||
summaryInfos, err := order.GetOrderRawSummary(ctx, paramsProfit)
|
||||
if err != nil {
|
||||
logs.Error("获取订单汇总信息失败:", err)
|
||||
}
|
||||
profit, err := order.GetOrderProfitRawSummary(ctx, params)
|
||||
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 {
|
||||
orderInfoList := order.GetOrderByMap(ctx, paramsProfit, 1000, i)
|
||||
bankIdList := slice.Map(orderInfoList, func(index int, item order.OrderInfo) string {
|
||||
return item.BankOrderId
|
||||
})
|
||||
dataInfo := order.GetOrderProfitListByBankOrderIdList(ctx, bankIdList)
|
||||
for _, info := range dataInfo {
|
||||
todayAllAmount += info.FactAmount
|
||||
if info.Status != common.OrderStatusSuccess {
|
||||
continue
|
||||
}
|
||||
todaySupplierAll += info.SupplierProfit
|
||||
todayPlatformAll += info.PlatformProfit
|
||||
todayAgentAll += info.AgentProfit
|
||||
todayPaidAmount += info.FactAmount
|
||||
todaySuccessNum += 1
|
||||
}
|
||||
}
|
||||
|
||||
succeedRate := 0.0
|
||||
if totalNum != 0 {
|
||||
succeedRate = math.Round(float64(todaySuccessNum)/float64(totalNum)*100*100) / 100
|
||||
}
|
||||
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,
|
||||
}
|
||||
//
|
||||
//todaySuccessNum := 0
|
||||
//todayAllAmount := 0.0
|
||||
//todaySupplierAll := 0.0
|
||||
//todayPlatformAll := 0.0
|
||||
//todayAgentAll := 0.0
|
||||
//todayPaidAmount := 0.0
|
||||
//
|
||||
//totalNum := order.GetOrderCountByMap(ctx, paramsProfit)
|
||||
//for i := int64(0); i < totalNum; i += 1000 {
|
||||
// orderInfoList := order.GetOrderByMap(ctx, paramsProfit, 1000, i)
|
||||
// bankIdList := slice.Map(orderInfoList, func(index int, item order.OrderInfo) string {
|
||||
// return item.BankOrderId
|
||||
// })
|
||||
// dataInfo := order.GetOrderProfitListByBankOrderIdList(ctx, bankIdList)
|
||||
// for _, info := range dataInfo {
|
||||
// todayAllAmount += info.FactAmount
|
||||
// if info.Status != common.OrderStatusSuccess {
|
||||
// continue
|
||||
// }
|
||||
// todaySupplierAll += info.SupplierProfit
|
||||
// todayPlatformAll += info.PlatformProfit
|
||||
// todayAgentAll += info.AgentProfit
|
||||
// todayPaidAmount += info.FactAmount
|
||||
// todaySuccessNum += 1
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//succeedRate := 0.0
|
||||
//if totalNum != 0 {
|
||||
// succeedRate = math.Round(float64(todaySuccessNum)/float64(totalNum)*100*100) / 100
|
||||
//}
|
||||
//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 {
|
||||
|
||||
@@ -198,7 +198,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<span>产品名称: </span>
|
||||
<span>产品名称:</span>
|
||||
<label>
|
||||
<select id="product-name">
|
||||
</select>
|
||||
|
||||
Reference in New Issue
Block a user