feat(merchant): 集成OpenAI接口实现订单记录自动总结功能

- 在订单查询接口增加调用OpenAI聊天模型生成中文总结的功能
- 修改OrderQueryRes结构体,新增Summary字段用于返回总结信息
- 添加queryAppleResult方法,通过OpenAI接口生成订单记录总结文本
- 在查询订单接口聚合苹果充值和兑换记录后,调用该方法获取总结
- 修改推送兑换逻辑优化充值成功余额显示,简化错误失败注释
- 调整订单状态修改时的备注信息,增强日志一致性和清晰度
- 更新go.mod引入OpenAI官方Go SDK及相关依赖
- 新增单元测试验证OpenAI接口调用正确性
- 添加AppleOrderOperation的String方法及对应测试实现,提高代码整洁度
This commit is contained in:
danial
2025-11-28 21:30:01 +08:00
parent 5bd3d5268c
commit 2d317037b0
9 changed files with 111 additions and 38 deletions

View File

@@ -21,8 +21,10 @@ type OrderQueryRecord struct {
} }
type OrderQueryRes struct { type OrderQueryRes struct {
g.Meta `mime:"application/json"` g.Meta `mime:"application/json"`
Result *OrderQueryRecord `json:"result"` Summary struct {
Msg string `json:"msg"`
} `json:"result"`
commonApi.CommonPageRes[*OrderQueryRecord] commonApi.CommonPageRes[*OrderQueryRecord]
BankOrderId string `json:"bankOrderId" dc:"平台订单号"` BankOrderId string `json:"bankOrderId" dc:"平台订单号"`
CreateTime *gtime.Time `json:"createTime" dc:"创建时间"` CreateTime *gtime.Time `json:"createTime" dc:"创建时间"`

7
go.mod
View File

@@ -5,7 +5,7 @@ go 1.25
require ( require (
github.com/Lofanmi/pinyin-golang v0.0.0-20250305082105-87d20ae3d695 github.com/Lofanmi/pinyin-golang v0.0.0-20250305082105-87d20ae3d695
github.com/bytedance/sonic v1.14.2 github.com/bytedance/sonic v1.14.2
github.com/casbin/casbin/v2 v2.132.0 github.com/casbin/casbin/v2 v2.134.0
github.com/duke-git/lancet/v2 v2.3.8 github.com/duke-git/lancet/v2 v2.3.8
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.5 github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.5
github.com/gogf/gf/contrib/metric/otelmetric/v2 v2.9.5 github.com/gogf/gf/contrib/metric/otelmetric/v2 v2.9.5
@@ -17,6 +17,7 @@ require (
github.com/jinzhu/copier v0.4.0 github.com/jinzhu/copier v0.4.0
github.com/mojocn/base64Captcha v1.3.8 github.com/mojocn/base64Captcha v1.3.8
github.com/mssola/user_agent v0.6.0 github.com/mssola/user_agent v0.6.0
github.com/openai/openai-go/v3 v3.8.1
github.com/rs/xid v1.6.0 github.com/rs/xid v1.6.0
github.com/shopspring/decimal v1.4.0 github.com/shopspring/decimal v1.4.0
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
@@ -77,6 +78,10 @@ require (
github.com/richardlehane/mscfb v1.0.4 // indirect github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.4 // indirect github.com/richardlehane/msoleps v1.0.4 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/tidwall/gjson v1.18.0 // indirect
github.com/tidwall/match v1.2.0 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
github.com/tiendc/go-deepcopy v1.7.1 // indirect github.com/tiendc/go-deepcopy v1.7.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/xuri/efp v0.0.1 // indirect github.com/xuri/efp v0.0.1 // indirect

17
go.sum
View File

@@ -19,8 +19,8 @@ github.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPII
github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980= github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980=
github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o= github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o=
github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
github.com/casbin/casbin/v2 v2.132.0 h1:73hGmOszGSL3hTVquwkAi98XLl3gPJ+BxB6D7G9Fxtk= github.com/casbin/casbin/v2 v2.134.0 h1:wyO3hZb487GzlGVAI2hUoHQT0ehFD+9B5P+HVG9BVTM=
github.com/casbin/casbin/v2 v2.132.0/go.mod h1:FmcfntdXLTcYXv/hxgNntcRPqAbwOG9xsism0yXT+18= github.com/casbin/casbin/v2 v2.134.0/go.mod h1:FmcfntdXLTcYXv/hxgNntcRPqAbwOG9xsism0yXT+18=
github.com/casbin/govaluate v1.3.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A= github.com/casbin/govaluate v1.3.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A=
github.com/casbin/govaluate v1.10.0 h1:ffGw51/hYH3w3rZcxO/KcaUIDOLP84w7nsidMVgaDG0= github.com/casbin/govaluate v1.10.0 h1:ffGw51/hYH3w3rZcxO/KcaUIDOLP84w7nsidMVgaDG0=
github.com/casbin/govaluate v1.10.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A= github.com/casbin/govaluate v1.10.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A=
@@ -119,6 +119,8 @@ github.com/olekukonko/ll v0.1.2 h1:lkg/k/9mlsy0SxO5aC+WEpbdT5K83ddnNhAepz7TQc0=
github.com/olekukonko/ll v0.1.2/go.mod h1:b52bVQRRPObe+yyBl0TxNfhesL0nedD4Cht0/zx55Ew= github.com/olekukonko/ll v0.1.2/go.mod h1:b52bVQRRPObe+yyBl0TxNfhesL0nedD4Cht0/zx55Ew=
github.com/olekukonko/tablewriter v1.1.0 h1:N0LHrshF4T39KvI96fn6GT8HEjXRXYNDrDjKFDB7RIY= github.com/olekukonko/tablewriter v1.1.0 h1:N0LHrshF4T39KvI96fn6GT8HEjXRXYNDrDjKFDB7RIY=
github.com/olekukonko/tablewriter v1.1.0/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo= github.com/olekukonko/tablewriter v1.1.0/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
github.com/openai/openai-go/v3 v3.8.1 h1:b+YWsmwqXnbpSHWQEntZAkKciBZ5CJXwL68j+l59UDg=
github.com/openai/openai-go/v3 v3.8.1/go.mod h1:UOpNxkqC9OdNXNUfpNByKOtB4jAL0EssQXq5p8gO0Xs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
@@ -158,6 +160,17 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM=
github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
github.com/tiendc/go-deepcopy v1.7.1 h1:LnubftI6nYaaMOcaz0LphzwraqN8jiWTwm416sitff4= github.com/tiendc/go-deepcopy v1.7.1 h1:LnubftI6nYaaMOcaz0LphzwraqN8jiWTwm416sitff4=
github.com/tiendc/go-deepcopy v1.7.1/go.mod h1:4bKjNC2r7boYOkD2IOuZpYjmlDdzjbpTRyCx+goBCJQ= github.com/tiendc/go-deepcopy v1.7.1/go.mod h1:4bKjNC2r7boYOkD2IOuZpYjmlDdzjbpTRyCx+goBCJQ=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=

View File

@@ -32,8 +32,14 @@ github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo8
github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0 h1:rTnT/Jrcm+figWlYz4Ixzt0SJVR2cMC8lvZcimipiEY= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0 h1:rTnT/Jrcm+figWlYz4Ixzt0SJVR2cMC8lvZcimipiEY=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 h1:+5VZ72z0Qan5Bog5C+ZkgSqUbeVUd9wgtHOrIKuc5b8= github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 h1:+5VZ72z0Qan5Bog5C+ZkgSqUbeVUd9wgtHOrIKuc5b8=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 h1:u/LLAOFgsMv7HmNL4Qufg58y+qElGOt5qv0z1mURkRY= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 h1:u/LLAOFgsMv7HmNL4Qufg58y+qElGOt5qv0z1mURkRY=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0/go.mod h1:2e8rMJtl2+2j+HXbTBwnyGpm5Nou7KhvSfxOq8JpTag= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0/go.mod h1:2e8rMJtl2+2j+HXbTBwnyGpm5Nou7KhvSfxOq8JpTag=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
@@ -48,6 +54,8 @@ github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+Z
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/ClickHouse/clickhouse-go v1.4.3 h1:iAFMa2UrQdR5bHJ2/yaSLffZkxpcOYQMCUuKeNXGdqc= github.com/ClickHouse/clickhouse-go v1.4.3 h1:iAFMa2UrQdR5bHJ2/yaSLffZkxpcOYQMCUuKeNXGdqc=
github.com/ClickHouse/clickhouse-go v1.4.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= github.com/ClickHouse/clickhouse-go v1.4.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw=
@@ -102,8 +110,6 @@ github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11 h1:3/gm/JTX9bX8CpzTgIlrtYpB3EVB
github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11/go.mod h1:fmgDANqTUCxciViKl9hb/zD5LFbvPINFRgWhDbR+vZo= github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11/go.mod h1:fmgDANqTUCxciViKl9hb/zD5LFbvPINFRgWhDbR+vZo=
github.com/aws/smithy-go v1.13.3 h1:l7LYxGuzK6/K+NzJ2mC+VvLUbae0sL3bXU//04MkmnA= github.com/aws/smithy-go v1.13.3 h1:l7LYxGuzK6/K+NzJ2mC+VvLUbae0sL3bXU//04MkmnA=
github.com/aws/smithy-go v1.13.3/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.13.3/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/casbin/casbin/v2 v2.132.0 h1:73hGmOszGSL3hTVquwkAi98XLl3gPJ+BxB6D7G9Fxtk=
github.com/casbin/casbin/v2 v2.132.0/go.mod h1:FmcfntdXLTcYXv/hxgNntcRPqAbwOG9xsism0yXT+18=
github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo=
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
@@ -322,6 +328,8 @@ github.com/pierrec/lz4/v4 v4.1.16 h1:kQPfno+wyx6C5572ABwV+Uo3pDFzQ7yhyGchSyRda0c
github.com/pierrec/lz4/v4 v4.1.16/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.16/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
@@ -331,8 +339,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6O
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/rqlite/gorqlite v0.0.0-20230708021416-2acd02b70b79 h1:V7x0hCAgL8lNGezuex1RW1sh7VXXCqfw8nXZti66iFg= github.com/rqlite/gorqlite v0.0.0-20230708021416-2acd02b70b79 h1:V7x0hCAgL8lNGezuex1RW1sh7VXXCqfw8nXZti66iFg=
github.com/rqlite/gorqlite v0.0.0-20230708021416-2acd02b70b79/go.mod h1:xF/KoXmrRyahPfo5L7Szb5cAAUl53dMWBh9cMruGEZg= github.com/rqlite/gorqlite v0.0.0-20230708021416-2acd02b70b79/go.mod h1:xF/KoXmrRyahPfo5L7Szb5cAAUl53dMWBh9cMruGEZg=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=

View File

@@ -95,6 +95,10 @@ const (
AppleRechargeOperationResetStatus AppleOrderOperation = "重置订单状态" AppleRechargeOperationResetStatus AppleOrderOperation = "重置订单状态"
) )
func (a AppleOrderOperation) String() string {
return string(a)
}
type StealStatus int type StealStatus int
const ( const (

View File

@@ -0,0 +1,11 @@
package consts
import (
"github.com/gogf/gf/v2/os/glog"
"testing"
)
func TestAppleOrderOperation_String(t *testing.T) {
historyOperation := AppleRechargeOperationItunesSucceed
glog.Info(t.Context(), historyOperation.String())
}

View File

@@ -2,6 +2,10 @@ package merchant
import ( import (
"context" "context"
"encoding/json"
"fmt"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/option"
"kami/internal/consts" "kami/internal/consts"
"kami/internal/model/entity" "kami/internal/model/entity"
"kami/internal/service" "kami/internal/service"
@@ -56,31 +60,32 @@ func (c *ControllerV1) OrderQuery(ctx context.Context, req *v1.OrderQueryReq) (r
record = append(record, appleRecord...) record = append(record, appleRecord...)
redeemRecord := queryRedeemCard(ctx, req.MerchantOrderNo) redeemRecord := queryRedeemCard(ctx, req.MerchantOrderNo)
record = append(record, redeemRecord...) record = append(record, redeemRecord...)
//if orderInfo.CardReturnData != "" { msg, err := queryAppleResult(ctx, record)
// record = append(record, &v1.OrderQueryRecord{ if err != nil {
// CreatedAt: orderInfo.UpdateTime, msg = "总结失败,请稍候重试"
// Operation: orderInfo.CardReturnData, }
// }) res.Summary.Msg = msg
//}
res.Result = queryAppleResult(ctx, req.MerchantOrderNo)
res.Total = len(record) res.Total = len(record)
res.List = record res.List = record
return return
} }
func queryAppleResult(ctx context.Context, merchantOrderNo string) (record *v1.OrderQueryRecord) { func queryAppleResult(ctx context.Context, record []*v1.OrderQueryRecord) (string, error) {
orderInfo, err := service.AppleOrder().GetOneByMerchantId(ctx, merchantOrderNo) recordStr, _ := json.Marshal(record)
if err == nil && orderInfo != nil && orderInfo.Id > 0 { client := openai.NewClient(
statusRemark := "" option.WithAPIKey("sk-jYRlGtXAJ3Q82TS_FxWLFX6wn_VubNnyCtfxYZYP32ccqfQaGwQJHMq5I7k"),
//orderInfo.Status option.WithBaseURL("https://hk.uniapi.io/v1"),
)
return &v1.OrderQueryRecord{ chatCompletion, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{
OrderNo: orderInfo.OrderNo, Messages: []openai.ChatCompletionMessageParamUnion{
Operation: statusRemark, openai.UserMessage(fmt.Sprintf("%s\n生成总结用中文回复", string(recordStr))),
Remark: orderInfo.Remark, },
} Model: "qwen3-8b",
})
if err != nil {
return "", err
} }
return nil return chatCompletion.Choices[0].Message.Content, nil
} }
func queryAppleCard(ctx context.Context, merchantOrderNo string) (record []*v1.OrderQueryRecord) { func queryAppleCard(ctx context.Context, merchantOrderNo string) (record []*v1.OrderQueryRecord) {

View File

@@ -0,0 +1,27 @@
package merchant
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/option"
"testing"
)
func Test_queryAppleResult(t *testing.T) {
client := openai.NewClient(
option.WithAPIKey("sk-jYRlGtXAJ3Q82TS_FxWLFX6wn_VubNnyCtfxYZYP32ccqfQaGwQJHMq5I7k"),
option.WithBaseURL("https://hk.uniapi.io/v1"),
)
chatCompletion, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{
Messages: []openai.ChatCompletionMessageParamUnion{
openai.UserMessage("用中文回复Say this is a test"),
},
Model: "qwen3-8b",
})
if err != nil {
panic(err.Error())
}
fmt.Print(chatCompletion.Choices[0].Message.Content)
}

View File

@@ -155,7 +155,7 @@ func (h *sAppleOrder) handleRedeemSuccess(ctx context.Context, orderEntity *enti
if amount == orderEntity.CardAmount { if amount == orderEntity.CardAmount {
orderStatus = consts.AppleRechargeOrderSuccess orderStatus = consts.AppleRechargeOrderSuccess
historyOperation = consts.AppleRechargeOperationItunesSucceed historyOperation = consts.AppleRechargeOperationItunesSucceed
remark = fmt.Sprintf("充值成功:使用卡密【%s】为账号【%s】充值【%.2f】元,卡密已核销成功,余额【%.2f】->【%.2f】", orderEntity.CardPass, accountInfo.Account, amount, balanceBefore, balanceAfter) remark = fmt.Sprintf("充值成功:使用卡密【%s】为账号【%s】充值【%.2f】元,卡密已核销成功,余额【%.2f】", orderEntity.CardPass, accountInfo.Account, amount, balanceAfter)
} else { } else {
orderStatus = consts.AppleRechargeOrderAmountDifferent orderStatus = consts.AppleRechargeOrderAmountDifferent
historyOperation = consts.AppleRechargeOperationItunesSucceedButWrongAmount historyOperation = consts.AppleRechargeOperationItunesSucceedButWrongAmount
@@ -168,7 +168,7 @@ func (h *sAppleOrder) handleRedeemSuccess(ctx context.Context, orderEntity *enti
OrderNo: orderEntity.OrderNo, OrderNo: orderEntity.OrderNo,
Amount: amount, Amount: amount,
Status: orderStatus, Status: orderStatus,
Remark: remark, Remark: historyOperation.String(),
}, },
AccountId: accountInfo.Id, AccountId: accountInfo.Id,
HistoryRemark: remark, HistoryRemark: remark,
@@ -188,7 +188,7 @@ func (h *sAppleOrder) handleRedeemSuccess(ctx context.Context, orderEntity *enti
// handleRedeemUnknown 处理核销失败的情况 // handleRedeemUnknown 处理核销失败的情况
func (h *sAppleOrder) handleRedeemUnknown(ctx context.Context, orderEntity *entity.V1CardAppleRechargeInfo, accountInfo *entity.V1CardAppleAccountInfo, errMsg string) error { func (h *sAppleOrder) handleRedeemUnknown(ctx context.Context, orderEntity *entity.V1CardAppleRechargeInfo, accountInfo *entity.V1CardAppleAccountInfo, errMsg string) error {
// 订单退回待处理状态 // 订单退回待处理状态
err := h.ModifyOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderWaiting, fmt.Sprintf("使用卡密【%s】为账号【%s】充值失败核销失败%s", orderEntity.CardPass, accountInfo.Account, errMsg), nil) err := h.ModifyOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderWaiting, "核销失败,结果未知,重新处理", nil)
if err != nil { if err != nil {
glog.Error(ctx, fmt.Sprintf("更新订单失败状态失败 - 订单号: %s, 错误: %v", orderEntity.OrderNo, err)) glog.Error(ctx, fmt.Sprintf("更新订单失败状态失败 - 订单号: %s, 错误: %v", orderEntity.OrderNo, err))
return err return err
@@ -201,7 +201,7 @@ func (h *sAppleOrder) handleRedeemUnknown(ctx context.Context, orderEntity *enti
RechargeId: int(orderEntity.Id), RechargeId: int(orderEntity.Id),
AccountName: accountInfo.Account, AccountName: accountInfo.Account,
Operation: consts.AppleRechargeOperationItunesRefund, Operation: consts.AppleRechargeOperationItunesRefund,
Remark: fmt.Sprintf("核销失败:%s退回订单重新处理", errMsg), Remark: fmt.Sprintf("使用卡密【%s】为账号【%s】充值失败核销失败%s", orderEntity.CardPass, accountInfo.Account, errMsg),
}, nil) }, nil)
glog.Info(ctx, fmt.Sprintf("订单核销失败,已退回待处理 - 订单号: %s", orderEntity.OrderNo)) glog.Info(ctx, fmt.Sprintf("订单核销失败,已退回待处理 - 订单号: %s", orderEntity.OrderNo))
@@ -212,7 +212,7 @@ func (h *sAppleOrder) handleRedeemUnknown(ctx context.Context, orderEntity *enti
// 订单退回待处理,等待系统重新调度重试 // 订单退回待处理,等待系统重新调度重试
func (h *sAppleOrder) handleSystemError(ctx context.Context, orderEntity *entity.V1CardAppleRechargeInfo, accountInfo *entity.V1CardAppleAccountInfo, code apple.Code) error { func (h *sAppleOrder) handleSystemError(ctx context.Context, orderEntity *entity.V1CardAppleRechargeInfo, accountInfo *entity.V1CardAppleAccountInfo, code apple.Code) error {
// 订单退回待处理状态 // 订单退回待处理状态
err := h.ModifyOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderWaiting, fmt.Sprintf("使用卡密【%s】为账号【%s】充值失败系统错误%s", orderEntity.CardPass, accountInfo.Account, code.String()), nil) err := h.ModifyOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderWaiting, "网络错误,退回重新处理", nil)
if err != nil { if err != nil {
glog.Error(ctx, fmt.Sprintf("更新订单状态失败 - 订单号: %s, 错误: %v", orderEntity.OrderNo, err)) glog.Error(ctx, fmt.Sprintf("更新订单状态失败 - 订单号: %s, 错误: %v", orderEntity.OrderNo, err))
return err return err
@@ -257,7 +257,7 @@ func (h *sAppleOrder) handleAccountError(ctx context.Context, orderEntity *entit
_ = service.AppleAccount().ModifyStatus(ctx, accountInfo.Id, accountStatus, nil) _ = service.AppleAccount().ModifyStatus(ctx, accountInfo.Id, accountStatus, nil)
// 订单重新设为待调度状态 // 订单重新设为待调度状态
err := h.ModifyOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderWaiting, fmt.Sprintf("使用卡密【%s】为账号【%s】充值失败订单退回重新充值因为苹果账户错误原因%s", orderEntity.CardPass, accountInfo.Account, code.String()), nil) err := h.ModifyOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderWaiting, "退回,账户原因重新处理", nil)
if err != nil { if err != nil {
glog.Error(ctx, fmt.Sprintf("更新订单状态失败 - 订单号: %s, 错误: %v", orderEntity.OrderNo, err)) glog.Error(ctx, fmt.Sprintf("更新订单状态失败 - 订单号: %s, 错误: %v", orderEntity.OrderNo, err))
return err return err
@@ -272,7 +272,7 @@ func (h *sAppleOrder) handleAccountError(ctx context.Context, orderEntity *entit
RechargeId: int(orderEntity.Id), RechargeId: int(orderEntity.Id),
AccountName: accountInfo.Account, AccountName: accountInfo.Account,
Operation: consts.AppleRechargeOperationWrongPassword, Operation: consts.AppleRechargeOperationWrongPassword,
Remark: fmt.Sprintf("订单退回重新充值,因为苹果账户错误,原因:%s", code.String()), Remark: fmt.Sprintf("使用卡密【%s】为账号【%s】充值失败订单退回重新充值,因为苹果账户错误,原因:%s", orderEntity.CardPass, accountInfo.Account, code.String()),
}, nil) }, nil)
glog.Warning(ctx, fmt.Sprintf("苹果账户原因导致失效,订单已退回待重新分配 - 订单号: %s, 账号: %s", orderEntity.OrderNo, accountInfo.Account)) glog.Warning(ctx, fmt.Sprintf("苹果账户原因导致失效,订单已退回待重新分配 - 订单号: %s, 账号: %s", orderEntity.OrderNo, accountInfo.Account))
@@ -307,7 +307,7 @@ func (h *sAppleOrder) handleRedeemLimitError(ctx context.Context, orderEntity *e
_ = service.AppleAccount().ModifyStatus(ctx, accountInfo.Id, accountStatus, nil) _ = service.AppleAccount().ModifyStatus(ctx, accountInfo.Id, accountStatus, nil)
// 订单退回待处理,后续可根据限制类型进行重试或转移到其他账户 // 订单退回待处理,后续可根据限制类型进行重试或转移到其他账户
err := h.ModifyOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderWaiting, fmt.Sprintf("使用卡密【%s】为账号【%s】充值失败订单退回重新充值账户受限%s", orderEntity.CardPass, accountInfo.Account, accountRemark), nil) err := h.ModifyOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderWaiting, "退回,账户原因重新处理", nil)
if err != nil { if err != nil {
glog.Error(ctx, fmt.Sprintf("更新订单状态失败 - 订单号: %s, 错误: %v", orderEntity.OrderNo, err)) glog.Error(ctx, fmt.Sprintf("更新订单状态失败 - 订单号: %s, 错误: %v", orderEntity.OrderNo, err))
return err return err
@@ -323,7 +323,7 @@ func (h *sAppleOrder) handleRedeemLimitError(ctx context.Context, orderEntity *e
RechargeId: int(orderEntity.Id), RechargeId: int(orderEntity.Id),
AccountName: accountInfo.Account, AccountName: accountInfo.Account,
Operation: consts.AppleRechargeOperationItunesFail, Operation: consts.AppleRechargeOperationItunesFail,
Remark: fmt.Sprintf("订单退回重新充值,因为苹果账户错误,原因:%s", code.String()), Remark: fmt.Sprintf("使用卡密【%s】为账号【%s】充值失败订单退回重新充值账户受限%s", orderEntity.CardPass, accountInfo.Account, accountRemark),
}, nil) }, nil)
glog.Warning(ctx, fmt.Sprintf("账户充值限制,订单已退回待处理 - 订单号: %s, 账号: %s, 限制类型: %d", orderEntity.OrderNo, accountInfo.Account, code)) glog.Warning(ctx, fmt.Sprintf("账户充值限制,订单已退回待处理 - 订单号: %s, 账号: %s, 限制类型: %d", orderEntity.OrderNo, accountInfo.Account, code))
@@ -346,13 +346,13 @@ func (h *sAppleOrder) handleCardCodeError(ctx context.Context, orderEntity *enti
operationRemark = "卡密错误" operationRemark = "卡密错误"
} }
operationRemark += fmt.Sprintf("使用卡密【%s】为账号【%s】充值失败%s", orderEntity.CardPass, accountInfo.Account, operationRemark)
// 更新订单为失败状态 // 更新订单为失败状态
err := h.ModifyOrderStatus(ctx, orderEntity.OrderNo, orderStatus, operationRemark, nil) err := h.ModifyOrderStatus(ctx, orderEntity.OrderNo, orderStatus, operationRemark, nil)
if err != nil { if err != nil {
glog.Error(ctx, fmt.Sprintf("更新订单失败状态失败 - 订单号: %s, 错误: %v", orderEntity.OrderNo, err)) glog.Error(ctx, fmt.Sprintf("更新订单失败状态失败 - 订单号: %s, 错误: %v", orderEntity.OrderNo, err))
return err return err
} }
operationRemark = fmt.Sprintf("使用卡密【%s】为账号【%s】充值失败%s", orderEntity.CardPass, accountInfo.Account, operationRemark)
// 添加历史记录 // 添加历史记录
_ = h.AddHistory(ctx, &model.AppleCardRechargeHistoryInput{ _ = h.AddHistory(ctx, &model.AppleCardRechargeHistoryInput{