Files
kami_boss/internal/service/queryService.go
danial 6ce7e2faba feat(order): 添加订单汇总功能- 新增 OrderSummaryOutput 结构体用于订单汇总信息
- 实现 GetOrderRawSummary 和 GetOrderProfitRawSummary 函数获取订单汇总数据
- 重构 QueryTotalSummary 和 QueryTodaySummary 函数,使用新的汇总查询逻辑
- 优化订单查询参数处理,支持模糊匹配和自定义字段筛选
2025-06-24 21:55:47 +08:00

289 lines
8.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"boss/internal/common"
"boss/internal/config"
"boss/internal/datas"
"boss/internal/models/order"
"boss/internal/models/payfor"
"boss/internal/models/road"
"boss/internal/models/user"
"boss/internal/utils/mfa"
"context"
"fmt"
"math"
"time"
"github.com/duke-git/lancet/v2/slice"
"github.com/beego/beego/v2/client/httplib"
"github.com/beego/beego/v2/core/logs"
)
type QueryService struct {
}
func OrderQuery(ctx context.Context, bankOrderId string) string {
orderInfo := order.GetOrderByBankOrderId(ctx, bankOrderId)
if orderInfo.BankOrderId == "" || len(orderInfo.BankOrderId) == 0 {
logs.Error("不存在这样的订单,订单查询结束")
return "不存在这样的订单"
}
if orderInfo.Status != "" && orderInfo.Status != "wait" {
logs.Error(fmt.Sprintf("该订单=%s已经处理完毕", bankOrderId))
return "该订单已经处理完毕"
}
// 向gateway发送请求请求上游的支付结果
gUrl := config.GetGatewayHost()
gUrl = gUrl + "gateway/supplier/order/query" + "?" + "bankOrderId=" + bankOrderId
res, err := httplib.Get(gUrl).String()
if err != nil {
logs.Error("获取gateway上游订单查询结果失败" + err.Error())
}
logs.Info("请求远程地址", gUrl, "远程返回结果:", res)
return res
}
func (c *QueryService) SupplierOrderQuery(ctx context.Context, bankOrderId string) *datas.KeyDataJSON {
keyDataJSON := new(datas.KeyDataJSON)
keyDataJSON.Code = 200
exist := order.BankOrderIdIsExist(ctx, bankOrderId)
if !exist {
keyDataJSON.Msg = "该订单不存在"
keyDataJSON.Code = -1
}
msg := OrderQuery(ctx, bankOrderId)
keyDataJSON.Msg = msg
return keyDataJSON
}
func (c *QueryService) SupplierPayForQuery(ctx context.Context, bankOrderId string) *datas.KeyDataJSON {
keyDataJSON := new(datas.KeyDataJSON)
keyDataJSON.Code = 200
if bankOrderId == "" {
keyDataJSON.Code = -1
keyDataJSON.Msg = "不存在这样的代付订单"
} else {
payFor := payfor.GetPayForByBankOrderId(ctx, bankOrderId)
if payFor.RoadUid == "" {
keyDataJSON.Msg = "该代付订单没有对应的通道uid"
} else {
result := querySupplierPayForResult(ctx, bankOrderId)
if result {
keyDataJSON.Msg = "处理成功!"
} else {
keyDataJSON.Msg = "处理失败!"
}
}
}
return keyDataJSON
}
func querySupplierPayForResult(ctx context.Context, bankOrderId string) bool {
u := config.GetGatewayHost() + "gateway/supplier/payfor/query" + "?bankOrderId=" + bankOrderId
s, err := httplib.Get(u).String()
if err != nil {
logs.Error("处理代付查询请求gateway失败", err)
return false
}
if s == "fail" {
return false
} else {
return true
}
}
func QueryTotalSummary(ctx context.Context, params map[string]string) order.Summary {
summaryInfos, err := order.GetOrderRawSummary(ctx, params)
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
}
func QuerySummaryByOrderInfo(ctx context.Context, infoInfoList []order.OrderInfo) order.Summary {
orderProfitInfoList := make([]order.OrderProfitInfo, 0)
for _, info := range infoInfoList {
orderProfitInfoList = append(orderProfitInfoList, order.GetOrderProfitByBankOrderId(ctx, info.BankOrderId))
}
totalNum := 0
todayAllAmount := 0.0
todaySupplierAll := 0.0
todayPlatformAll := 0.0
todayAgentAll := 0.0
TodaySuccessNum := 0
for _, info := range orderProfitInfoList {
totalNum += 1
todayAllAmount += info.FactAmount
if info.Status != common.OrderStatusSuccess {
continue
}
todaySupplierAll += info.SupplierProfit
todayPlatformAll += info.PlatformProfit
todayAgentAll += info.AgentProfit
TodaySuccessNum += 1
}
succeedRate := 0.0
if totalNum != 0 {
succeedRate = math.Round(float64(TodaySuccessNum)/float64(totalNum)*100*100) / 100
} else {
succeedRate = 0
}
return order.Summary{
TotalNum: int64(totalNum),
TotalAmount: math.Round(todayAllAmount*100) / 100,
PaidNum: int64(TodaySuccessNum),
PlatformIncome: math.Round(todayPlatformAll*100) / 100,
AgencyIncome: todayAgentAll,
SucceedRate: succeedRate,
}
}
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 := todayAtMidnight.Add(time.Hour * 24)
st := todayAtMidnight.Format("2006-01-02 15:04:05")
end := tomorrowAtMidNight.Format("2006-01-02 15:04:05")
paramsProfit := params
if startTimeStr, exists := paramsProfit["create_time__gte"]; exists {
startTime, err := time.Parse("2006-01-02 15:04:05", startTimeStr)
if err != nil {
paramsProfit["create_time__gte"] = st
} else {
if tomorrowAtMidNight.Before(startTime) || todayAtMidnight.After(startTime) {
paramsProfit["create_time__gte"] = st
}
}
} else {
paramsProfit["create_time__gte"] = st
}
if endTimeStr, exists := paramsProfit["create_time__lte"]; exists {
endTime, err := time.Parse("2006-01-02 15:04:05", endTimeStr)
if err != nil {
paramsProfit["create_time__gte"] = st
} else {
if tomorrowAtMidNight.Before(endTime) || todayAtMidnight.After(endTime) {
paramsProfit["create_time__gte"] = st
}
}
} else {
paramsProfit["create_time__lte"] = end
}
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
//
//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 {
userInfo := user.GetUserInfoByUserID(ctx, accountUid)
if userInfo.Id == 0 {
return false
}
if userInfo.OtpSecret == "" {
return true
}
return mfa.ValidCode(totpCode, userInfo.OtpSecret)
}
func QueryRoad(ctx context.Context) []road.RoadInfo {
roadInfoList := road.GetAllRoad(ctx, map[string]string{})
return roadInfoList
}