refactor(card_redeem):重构携程卡账户接口和京东cookie逻辑

- 统一使用基础请求结构体替换原有公共字段- 删除京东ck相关冗余代码和文件
- 优化jd cookie账户创建和更新逻辑
- 增加cookie变更历史记录功能
- 完善账户删除和批量删除功能
- 添加获取单个账户信息方法
- 引入工具函数生成随机UUID
-优化数据库查询条件写法
- 增加pb生成命令到Makefile
This commit is contained in:
danial
2025-10-09 22:27:35 +08:00
parent f029eb7d6c
commit 0fdae6a89f
68 changed files with 1200 additions and 2397 deletions

View File

@@ -3,9 +3,11 @@
"allow": [
"Bash(go doc:*)",
"Bash(go build:*)",
"Bash(timeout:*)"
"Bash(timeout:*)",
"WebSearch",
"mcp__fetch__fetch"
],
"deny": [],
"ask": []
}
}
}

View File

@@ -18,6 +18,8 @@ This project uses GoFrame (GF) framework and includes a custom Makefile for comm
- `make dao` - Generate DAO/DO/Entity files from database schema
- `make service` - Generate service interfaces
- `make enums` - Generate enum files from Go code
- `make pb` - Generate protobuf files
- `make pbentity` - Generate protobuf files for database tables
### Testing
@@ -29,6 +31,7 @@ This project uses GoFrame (GF) framework and includes a custom Makefile for comm
- `make image` - Build Docker image with auto-generated tag
- `make image.push` - Build and push Docker image
- `make deploy` - Deploy to kubernetes environment
## Architecture Overview
@@ -44,21 +47,28 @@ This is a Go-based backend service using the GoFrame framework with the followin
### Key Business Domains
- **Card Management**: Apple cards, JD cards, T-Mall cards, Walmart cards
- **Order Processing**: Order lifecycle management for different card types
- **User Management**: Authentication, authorization, user profiles
- **Payment Processing**: Payment handling and user payment methods
- **Merchant Management**: Merchant configurations and deployments
- **Channel & Road Management**: Business routing logic
- **Card Management**: Multi-platform card support including Apple, JD, T-Mall, Walmart, C-Trip cards with account
management and configuration
- **Order Processing**: Complete order lifecycle with callback handling, status tracking, and order summary generation
- **User Management**: Authentication via JWT, TOTP support, role-based access control with Casbin
- **Payment Processing**: Payment method management, deduction tracking, and payment statistics
- **Merchant Management**: Merchant configurations, deployment management, and steal rule processing
- **Channel & Road Management**: Business routing logic with road pools and entrance management
- **Restriction Management**: IP and device ID tracking for access control
- **JDCookie Management**: JD cookie rotation, order processing, and account management
### Technology Stack
- **Framework**: GoFrame v2
- **Database**: MySQL with GoFrame ORM
- **Cache**: Redis
- **Tracing**: OpenTelemetry with OTLP
- **Monitoring**: Built-in metrics and health checks
- **Task Scheduling**: Cron jobs for periodic tasks
- **Framework**: GoFrame v2 with code generation capabilities
- **Database**: MySQL with GoFrame ORM (DAO/DO/Entity pattern)
- **Cache**: Redis for caching and session management
- **Tracing**: OpenTelemetry with OTLP exporter for observability
- **Monitoring**: Built-in metrics and health checks with Prometheus integration
- **Task Scheduling**: Cron jobs for periodic tasks with graceful shutdown
- **Authentication**: JWT tokens with TOTP support
- **Authorization**: Casbin for role-based access control
- **External Integrations**: T-Mall SDK, JD APIs, Walmart APIs, C-Trip APIs
- **Rate Limiting**: Built-in rate limiting with Redis backend
### Configuration
@@ -68,8 +78,12 @@ This is a Go-based backend service using the GoFrame framework with the followin
### Development Notes
- The project uses GoFrame's code generation capabilities heavily
- Controllers are auto-generated from API definitions
- Database access follows GoFrame's DAO/DO/Entity pattern
- OpenTelemetry tracing is configured for both HTTP and gRPC exporters
- Graceful shutdown handling for cron jobs and connection pools
- The project uses GoFrame's code generation capabilities heavily - always run `make dao` after database schema changes
- Controllers are auto-generated from API definitions in the `api/` directory
- Database access follows GoFrame's DAO/DO/Entity pattern with generated models
- OpenTelemetry tracing is configured for HTTP and gRPC exporters with custom headers
- Graceful shutdown handling for cron jobs and connection pools is implemented
- The service includes extensive external API integrations for various card platforms
- Rate limiting and restriction management are built-in for security
- All external integrations are located in `utility/integration/` with proper abstraction
- Business logic is separated by domain in `internal/logic/` with clear boundaries

View File

@@ -11,17 +11,17 @@ import (
type AccountDeleteReq struct {
g.Meta `path:"/cardInfo/cTrip/account/delete" tags:"携程充值卡账户" method:"delete" summary:"删除携程充值卡"`
commonApi.CommonStrId
commonApi.BaseAccountDeleteReq
}
type AccountDeleteRes struct{}
type AccountDeleteRes struct {
commonApi.BaseAccountDeleteRes
}
type AccountListReq struct {
g.Meta `path:"/cardInfo/cTrip/account/getList" tags:"携程充值卡账户" method:"get" summary:"获取携程充值卡列表"`
commonApi.CommonPageReq
Name string `json:"name" description:"账户名称"`
NickName string `json:"nickName" description:"用户昵称"`
Cookie string `json:"cookie"`
commonApi.BaseAccountListReq
Cookie string `json:"cookie"`
}
type AccountListRecord struct {
@@ -64,19 +64,19 @@ type AccountCookieCheckRes struct {
IsAvailable bool `json:"isAvailable" dc:"是否可用"`
}
type AccountCreateRes struct{}
type AccountCreateRes struct {
commonApi.BaseAccountCreateRes
}
type AccountUpdateReq struct {
g.Meta `path:"/cardInfo/cTrip/account/update" tags:"携程充值卡账户" method:"put" summary:"修改携程账户"`
commonApi.CommonStrId
Status int `json:"status" description:"状态"`
Name string `json:"name" description:"别名"`
Remark string `json:"remark" description:"备注"`
MaxAmountLimit int `json:"maxAmountLimit" description:"最大充值限制"`
MaxCountLimit int `json:"maxCountLimit" description:"最大充值次数"`
commonApi.BaseAccountUpdateReq
MaxAmountLimit int `json:"maxAmountLimit" description:"最大充值限制"`
MaxCountLimit int `json:"maxCountLimit" description:"最大充值次数"`
}
type AccountUpdateRes struct {
commonApi.BaseAccountUpdateRes
}
type AccountWalletListReq struct {
@@ -91,11 +91,12 @@ type AccountWalletListRes struct {
type AccountUpdateStatusReq struct {
g.Meta `path:"/cardInfo/cTrip/account/updateStatus" tags:"携程充值卡账户" method:"put" summary:"修改携程账户状态"`
commonApi.CommonStrId
commonApi.BaseAccountUpdateStatusReq
Status consts.RedeemAccountStatus `json:"status" v:"required#状态不能为空" description:"状态"`
}
type AccountUpdateStatusRes struct {
commonApi.BaseAccountUpdateStatusRes
}
type AccountRefreshStatusReq struct {
@@ -108,10 +109,11 @@ type AccountRefreshStatusRes struct {
type DownloadTemplateReq struct {
g.Meta `path:"/cardInfo/cTrip/account/downloadTemplate" tags:"携程充值卡账户" method:"get" summary:"下载导入模板"`
commonApi.BaseDownloadTemplateReq
}
type DownloadTemplateRes struct {
g.Meta `mime:"application/vnd.ms-excel"`
commonApi.BaseDownloadTemplateRes
}
type AccountCookieBatchCheckReq struct {
@@ -142,8 +144,9 @@ type AccountCookieBatchAddRes struct {
type DownloadReq struct {
g.Meta `path:"/cardInfo/cTrip/account/download" tags:"携程充值卡账户" method:"get" summary:"下载充值账户"`
commonApi.BaseDownloadReq
}
type DownloadRes struct {
g.Meta `mime:"application/vnd.ms-excel"`
commonApi.BaseDownloadRes
}

View File

@@ -1,22 +0,0 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package card_redeem_jd
import (
"context"
"kami/api/card_redeem_jd/v1"
)
type ICardRedeemJdV1 interface {
AccountAdd(ctx context.Context, req *v1.AccountAddReq) (res *v1.AccountAddRes, err error)
AccountUpdate(ctx context.Context, req *v1.AccountUpdateReq) (res *v1.AccountUpdateRes, err error)
AccountGet(ctx context.Context, req *v1.AccountGetReq) (res *v1.AccountGetRes, err error)
AccountList(ctx context.Context, req *v1.AccountListReq) (res *v1.AccountListRes, err error)
AccountDelete(ctx context.Context, req *v1.AccountDeleteReq) (res *v1.AccountDeleteRes, err error)
AccountStatus(ctx context.Context, req *v1.AccountStatusReq) (res *v1.AccountStatusRes, err error)
OrderList(ctx context.Context, req *v1.OrderListReq) (res *v1.OrderListRes, err error)
PlaceOrder(ctx context.Context, req *v1.PlaceOrderReq) (res *v1.PlaceOrderRes, err error)
}

View File

@@ -1,77 +0,0 @@
package v1
import (
"kami/api/commonApi"
"kami/internal/consts"
"kami/internal/model/entity"
"github.com/gogf/gf/v2/frame/g"
)
type AccountEntity struct {
Name string `json:"name" v:"required#昵称不能为空" description:"用户名"`
Cookie string `json:"cookie" v:"required#ck不能为空" description:"cookie"`
Status consts.CardRedeemCookieStatus `json:"status" v:"required#状态不能为空" description:"状态"`
Notes string `json:"notes" description:"备注"`
}
type AccountAddReq struct {
g.Meta `path:"/cookieInfo/jd/account/add" tags:"京东ck账户" method:"post" summary:"添加京东ck"`
AccountEntity
}
type AccountAddRes struct{}
type AccountUpdateReq struct {
g.Meta `path:"/cookieInfo/jd/account/update" tags:"京东ck账户" method:"put" summary:"更新京东ck"`
AccountEntity
commonApi.CommonIntId
}
type AccountUpdateRes struct{}
type AccountGetReq struct {
g.Meta `path:"/cookieInfo/jd/account/get" tags:"京东ck账户" method:"get" summary:"获取京东ck"`
commonApi.CommonIntId
}
type AccountGetRes struct {
*CookieInfo
}
type AccountListReq struct {
g.Meta `path:"/cookieInfo/jd/account/list" tags:"京东ck账户" method:"get" summary:"获取京东ck列表"`
commonApi.CommonPageReq
Status consts.CardRedeemCookieStatus `json:"status" description:"状态"`
Name string `json:"name" description:"昵称"`
Cookie string `json:"cookie" description:"ck"`
}
type CookieInfo struct {
*entity.V1CardRedeemCookieInfo
Status consts.CardRedeemCookieStatus `json:"status" description:"状态"`
TotalCount int `json:"totalCount" description:"总数量"`
SuccessCount int `json:"successCount" description:"成功数量"`
TotalAmount int `json:"totalAmount" description:"总金额"`
SuccessAmount int `json:"successAmount" description:"成功金额"`
}
type AccountListRes struct {
commonApi.CommonPageRes[*CookieInfo]
}
type AccountDeleteReq struct {
g.Meta `path:"/cookieInfo/jd/account/delete" tags:"京东ck账户" method:"delete" summary:"删除京东ck"`
commonApi.CommonIntId
}
type AccountDeleteRes struct{}
// AccountStatusReq 修改状态
type AccountStatusReq struct {
g.Meta `path:"/cookieInfo/jd/account/status" tags:"京东ck账户" method:"put" summary:"修改京东ck状态"`
commonApi.CommonIntId
Status consts.CardRedeemCookieStatus `json:"status" v:"required#状态不能为空" description:"状态"`
}
type AccountStatusRes struct{}

View File

@@ -1,44 +0,0 @@
package v1
import (
"kami/api/commonApi"
"kami/internal/consts"
"kami/internal/model/entity"
"github.com/gogf/gf/v2/frame/g"
)
type OrderListReq struct {
g.Meta `path:"/cookieInfo/jd/order/list" tags:"京东ck订单" method:"get" summary:"获取订单列表"`
commonApi.CommonPageReq
CookieId int64 `json:"cookieId" description:"cookieId"`
Cookie string `json:"cookie" description:"cookie"`
Status consts.CardRedeemCookieOrderStatus `json:"status" description:"状态"`
}
type OrderListSchema struct {
*entity.V1CardRedeemCookieOrder
JdOrder *entity.V1CardRedeemCookieOrderJd `json:"jdOrder"`
Cookie *entity.V1CardRedeemCookieInfo `json:"cookie" description:"cookie"`
}
type OrderListRes struct {
commonApi.CommonPageRes[*OrderListSchema]
}
// PlaceOrderReq 下单接口
type PlaceOrderReq struct {
g.Meta `path:"/cookieInfo/jd/order/placeOrder" tags:"京东ck订单" method:"post" summary:"下单"`
MerchantOrderId string `json:"merchantOrderId" v:"required#merchantOrderId不能为空" description:"银行订单id"`
OrderAmount float64 `json:"orderAmount" v:"required#orderAmount不能为空" description:"订单金额"`
UserAgent string `json:"userAgent" description:"用户代理"`
Category consts.RedeemOrderCardCategory `json:"category" v:"required|in:apple,cTrip,walmart#类型不能为空|类型不正确" description:"分类"`
}
type PlaceOrderRes struct {
WxPay string `json:"wxPay" description:"微信支付"`
MerchantOrder string `json:"merchantOrder" description:"银行订单id"`
OrderNo string `json:"orderNo" description:"订单号"`
OrderAmount float64 `json:"orderAmount" description:"订单金额"`
OrderStatus consts.CardRedeemCookieOrderStatus `json:"orderStatus" description:"订单状态"`
}

View File

@@ -0,0 +1,85 @@
package commonApi
import "github.com/gogf/gf/v2/frame/g"
// ====================================================================================
// 通用卡类账户API结构
// ====================================================================================
// BaseAccountDeleteReq 通用账户删除请求
type BaseAccountDeleteReq struct {
g.Meta `summary:"删除账户"`
CommonStrId
}
// BaseAccountDeleteRes 通用账户删除响应
type BaseAccountDeleteRes struct{}
// BaseAccountListReq 通用账户列表请求
type BaseAccountListReq struct {
g.Meta `summary:"获取账户列表"`
CommonPageReq
Name string `json:"name" description:"账户名称"`
NickName string `json:"nickName" description:"用户昵称"`
Status int `json:"status" description:"状态筛选"`
}
// BaseAccountCreateRes 通用账户创建响应
type BaseAccountCreateRes struct{}
// BaseAccountUpdateReq 通用账户更新请求
type BaseAccountUpdateReq struct {
g.Meta `summary:"修改账户"`
CommonStrId
Name string `json:"name" description:"别名"`
Status int `json:"status" description:"状态"`
Remark string `json:"remark" description:"备注"`
}
// BaseAccountUpdateRes 通用账户更新响应
type BaseAccountUpdateRes struct{}
// BaseAccountUpdateStatusReq 通用账户状态更新请求
type BaseAccountUpdateStatusReq struct {
g.Meta `summary:"修改账户状态"`
CommonStrId
Status int `json:"status" v:"required#状态不能为空" description:"状态"`
}
// BaseAccountUpdateStatusRes 通用账户状态更新响应
type BaseAccountUpdateStatusRes struct{}
// BaseAccountCookieCheckReq 通用Cookie检测请求
type BaseAccountCookieCheckReq struct {
g.Meta `summary:"检测cookie是否可用"`
Cookie string `json:"cookie" v:"required#cookie不能为空" description:"cookie"`
}
// BaseAccountCookieCheckRes 通用Cookie检测响应
type BaseAccountCookieCheckRes struct {
Username string `json:"username" dc:"用户名"`
Nickname string `json:"nickname" dc:"昵称"`
Balance float64 `json:"balance" dc:"余额"`
IsExist bool `json:"isExist" dc:"是否存在系统中"`
IsAvailable bool `json:"isAvailable" dc:"是否可用"`
}
// BaseDownloadTemplateReq 通用下载模板请求
type BaseDownloadTemplateReq struct {
g.Meta `summary:"下载导入模板"`
}
// BaseDownloadTemplateRes 通用下载模板响应
type BaseDownloadTemplateRes struct {
g.Meta `mime:"application/vnd.ms-excel"`
}
// BaseDownloadReq 通用下载请求
type BaseDownloadReq struct {
g.Meta `summary:"下载数据"`
}
// BaseDownloadRes 通用下载响应
type BaseDownloadRes struct {
g.Meta `mime:"application/vnd.ms-excel"`
}

View File

@@ -14,14 +14,19 @@ type IJdCookieV1 interface {
CreateAccount(ctx context.Context, req *v1.CreateAccountReq) (res *v1.CreateAccountRes, err error)
BatchCreate(ctx context.Context, req *v1.BatchCreateReq) (res *v1.BatchCreateRes, err error)
ListAccount(ctx context.Context, req *v1.ListAccountReq) (res *v1.ListAccountRes, err error)
GetAccount(ctx context.Context, req *v1.GetAccountReq) (res *v1.GetAccountRes, err error)
UpdateAccount(ctx context.Context, req *v1.UpdateAccountReq) (res *v1.UpdateAccountRes, err error)
DeleteAccount(ctx context.Context, req *v1.DeleteAccountReq) (res *v1.DeleteAccountRes, err error)
BatchCheck(ctx context.Context, req *v1.BatchCheckReq) (res *v1.BatchCheckRes, err error)
CookieHistory(ctx context.Context, req *v1.CookieHistoryReq) (res *v1.CookieHistoryRes, err error)
OrderHistory(ctx context.Context, req *v1.OrderHistoryReq) (res *v1.OrderHistoryRes, err error)
CreateOrder(ctx context.Context, req *v1.CreateOrderReq) (res *v1.CreateOrderRes, err error)
GetPaymentUrl(ctx context.Context, req *v1.GetPaymentUrlReq) (res *v1.GetPaymentUrlRes, err error)
GetOrderStatus(ctx context.Context, req *v1.GetOrderStatusReq) (res *v1.GetOrderStatusRes, err error)
GetOrder(ctx context.Context, req *v1.GetOrderReq) (res *v1.GetOrderRes, err error)
GetJdOrder(ctx context.Context, req *v1.GetJdOrderReq) (res *v1.GetJdOrderRes, err error)
ListOrder(ctx context.Context, req *v1.ListOrderReq) (res *v1.ListOrderRes, err error)
ListJdOrder(ctx context.Context, req *v1.ListJdOrderReq) (res *v1.ListJdOrderRes, err error)
CheckJdOrderPayment(ctx context.Context, req *v1.CheckJdOrderPaymentReq) (res *v1.CheckJdOrderPaymentRes, err error)
CookieHistory(ctx context.Context, req *v1.CookieHistoryReq) (res *v1.CookieHistoryRes, err error)
OrderHistory(ctx context.Context, req *v1.OrderHistoryReq) (res *v1.OrderHistoryRes, err error)
GetJdOrderHistory(ctx context.Context, req *v1.GetJdOrderHistoryReq) (res *v1.GetJdOrderHistoryRes, err error)
}

127
api/jd_cookie/v1/account.go Normal file
View File

@@ -0,0 +1,127 @@
package v1
import (
"github.com/gogf/gf/v2/frame/g"
)
// ====================================================================================
// Cookie Account Management API
// ====================================================================================
type JdCookieAccountApi struct {
CreateAccountReq *CreateAccountReq `path:"/jd-cookie/account/create" method:"post" summary:"Create Cookie Account" tags:"JD Cookie Management"`
BatchCreateReq *BatchCreateReq `path:"/jd-cookie/account/batch-create" method:"post" summary:"Batch Create Cookie Accounts" tags:"JD Cookie Management"`
ListAccountReq *ListAccountReq `path:"/jd-cookie/account/list" method:"get" summary:"Query Cookie Account List" tags:"JD Cookie Management"`
GetAccountReq *GetAccountReq `path:"/jd-cookie/account/get" method:"get" summary:"Get Single Cookie Account" tags:"JD Cookie Management"`
UpdateAccountReq *UpdateAccountReq `path:"/jd-cookie/account/update" method:"put" summary:"Update Cookie Account" tags:"JD Cookie Management"`
DeleteAccountReq *DeleteAccountReq `path:"/jd-cookie/account/delete" method:"delete" summary:"Delete Cookie Account" tags:"JD Cookie Management"`
BatchCheckReq *BatchCheckReq `path:"/jd-cookie/account/batch-check" method:"post" summary:"Batch Check Cookie Status" tags:"JD Cookie Management"`
}
// ====================================================================================
// Cookie Account Management Request/Response Structures
// ====================================================================================
// CreateAccountReq Create Cookie Account Request
type CreateAccountReq struct {
g.Meta `path:"/jd-cookie/account/create" method:"post" summary:"Create Cookie Account" tags:"JD Cookie Management"`
CookieValue string `json:"cookieValue" v:"required#Cookie内容不能为空" dc:"Cookie内容"`
AccountName string `json:"accountName" dc:"账户名称"`
Remark string `json:"remark" dc:"备注信息"`
}
type CreateAccountRes struct {
g.Meta `mime:"application/json"`
CookieId string `json:"cookieId" dc:"Cookie唯一标识"`
Status int `json:"status" dc:"账户状态"`
}
// BatchCreateReq Batch Create Cookie Account Request
type BatchCreateReq struct {
g.Meta `path:"/jd-cookie/account/batch-create" method:"post" summary:"Batch Create Cookie Accounts" tags:"JD Cookie Management"`
Cookies []*CreateAccountReq `json:"cookies" v:"required#Cookie列表不能为空" dc:"Cookie列表"`
}
type BatchCreateRes struct {
g.Meta `mime:"application/json"`
SuccessIds []string `json:"successIds" dc:"成功创建的Cookie ID列表"`
FailedCount int `json:"failedCount" dc:"失败数量"`
}
// ListAccountReq Query Cookie Account List Request
type ListAccountReq struct {
g.Meta `path:"/jd-cookie/account/list" method:"get" summary:"Query Cookie Account List" tags:"JD Cookie Management"`
Page int `json:"page" d:"1" dc:"页码"`
Size int `json:"size" d:"20" dc:"每页大小"`
Status int `json:"status" dc:"状态筛选"`
Keyword string `json:"keyword" dc:"关键字搜索"`
}
type ListAccountRes struct {
g.Meta `mime:"application/json"`
List []*CookieAccountInfo `json:"list" dc:"Cookie列表"`
Total int `json:"total" dc:"总数"`
}
// GetAccountReq Get Single Cookie Account Request
type GetAccountReq struct {
g.Meta `path:"/jd-cookie/account/get" method:"get" summary:"Get Single Cookie Account" tags:"JD Cookie Management"`
CookieId string `json:"cookieId" v:"required#Cookie ID不能为空" dc:"Cookie ID"`
}
type GetAccountRes struct {
g.Meta `mime:"application/json"`
Account *CookieAccountInfo `json:"account" dc:"Cookie账户信息"`
}
type CookieAccountInfo struct {
CookieId string `json:"cookieId" dc:"Cookie ID"`
AccountName string `json:"accountName" dc:"账户名称"`
Status int `json:"status" dc:"状态1正常 2暂停 3失效"`
FailureCount int `json:"failureCount" dc:"连续失败次数"`
LastUsedAt string `json:"lastUsedAt" dc:"最后使用时间"`
SuspendUntil string `json:"suspendUntil" dc:"暂停解除时间"`
CreatedAt string `json:"createdAt" dc:"创建时间"`
Remark string `json:"remark" dc:"备注信息"`
}
// UpdateAccountReq Update Cookie Account Request
type UpdateAccountReq struct {
g.Meta `path:"/jd-cookie/account/update" method:"put" summary:"Update Cookie Account" tags:"JD Cookie Management"`
CookieId string `json:"cookieId" v:"required#Cookie ID不能为空" dc:"Cookie ID"`
CookieValue string `json:"cookieValue" dc:"Cookie内容"`
AccountName string `json:"accountName" dc:"账户名称"`
Status int `json:"status" dc:"状态"`
Remark string `json:"remark" dc:"备注信息"`
}
type UpdateAccountRes struct {
g.Meta `mime:"application/json"`
}
// DeleteAccountReq Delete Cookie Account Request
type DeleteAccountReq struct {
g.Meta `path:"/jd-cookie/account/delete" method:"delete" summary:"Delete Cookie Account" tags:"JD Cookie Management"`
CookieId string `json:"cookieId" v:"required#Cookie ID不能为空" dc:"Cookie ID"`
}
type DeleteAccountRes struct {
g.Meta `mime:"application/json"`
}
// BatchCheckReq Batch Check Cookie Status Request
type BatchCheckReq struct {
g.Meta `path:"/jd-cookie/account/batch-check" method:"post" summary:"Batch Check Cookie Status" tags:"JD Cookie Management"`
CookieIds []string `json:"cookieIds" v:"required#Cookie ID列表不能为空" dc:"Cookie ID列表"`
}
type BatchCheckRes struct {
g.Meta `mime:"application/json"`
Results []*CookieCheckResult `json:"results" dc:"检测结果"`
}
type CookieCheckResult struct {
CookieId string `json:"cookieId" dc:"Cookie ID"`
Status int `json:"status" dc:"状态"`
Message string `json:"message" dc:"检测信息"`
}

View File

@@ -1,274 +0,0 @@
package v1
import (
"github.com/gogf/gf/v2/frame/g"
)
// ====================================================================================
// Cookie账户管理API
// ====================================================================================
type JdCookieAccountApi struct {
CreateAccountReq *CreateAccountReq `path:"/jd-cookie/account/create" method:"post" summary:"创建Cookie账户" tags:"京东Cookie管理"`
BatchCreateReq *BatchCreateReq `path:"/jd-cookie/account/batch-create" method:"post" summary:"批量创建Cookie账户" tags:"京东Cookie管理"`
ListAccountReq *ListAccountReq `path:"/jd-cookie/account/list" method:"get" summary:"查询Cookie账户列表" tags:"京东Cookie管理"`
UpdateAccountReq *UpdateAccountReq `path:"/jd-cookie/account/update" method:"put" summary:"更新Cookie账户" tags:"京东Cookie管理"`
DeleteAccountReq *DeleteAccountReq `path:"/jd-cookie/account/delete" method:"delete" summary:"删除Cookie账户" tags:"京东Cookie管理"`
BatchCheckReq *BatchCheckReq `path:"/jd-cookie/account/batch-check" method:"post" summary:"批量检测Cookie状态" tags:"京东Cookie管理"`
}
// ====================================================================================
// 订单处理API
// ====================================================================================
type JdCookieOrderApi struct {
CreateOrderReq *CreateOrderReq `path:"/jd-cookie/order/create" method:"post" summary:"创建订单" tags:"京东订单管理"`
GetPaymentUrlReq *GetPaymentUrlReq `path:"/jd-cookie/order/payment-url" method:"post" summary:"获取支付链接" tags:"京东订单管理"`
GetOrderStatusReq *GetOrderStatusReq `path:"/jd-cookie/order/status" method:"get" summary:"查询订单状态" tags:"京东订单管理"`
ListOrderReq *ListOrderReq `path:"/jd-cookie/order/list" method:"get" summary:"订单列表查询" tags:"京东订单管理"`
CheckJdOrderPaymentReq *CheckJdOrderPaymentReq `path:"/jd-cookie/order/jd-payment-status" method:"post" summary:"检查京东订单支付状态" tags:"京东订单管理"`
}
// ====================================================================================
// 历史记录API
// ====================================================================================
type JdCookieHistoryApi struct {
CookieHistoryReq *CookieHistoryReq `path:"/jd-cookie/history/cookie" method:"get" summary:"Cookie变更历史" tags:"京东历史记录"`
OrderHistoryReq *OrderHistoryReq `path:"/jd-cookie/history/order" method:"get" summary:"订单变更历史" tags:"京东历史记录"`
}
// ====================================================================================
// Cookie账户管理请求/响应结构
// ====================================================================================
// CreateAccountReq 创建Cookie账户请求
type CreateAccountReq struct {
g.Meta `path:"/jd-cookie/account/create" method:"post" summary:"创建Cookie账户" tags:"京东Cookie管理"`
CookieValue string `json:"cookieValue" v:"required#Cookie内容不能为空" dc:"Cookie内容"`
AccountName string `json:"accountName" dc:"账户名称"`
Remark string `json:"remark" dc:"备注信息"`
}
type CreateAccountRes struct {
g.Meta `mime:"application/json"`
CookieId string `json:"cookieId" dc:"Cookie唯一标识"`
Status int `json:"status" dc:"账户状态"`
}
// BatchCreateReq 批量创建Cookie账户请求
type BatchCreateReq struct {
g.Meta `path:"/jd-cookie/account/batch-create" method:"post" summary:"批量创建Cookie账户" tags:"京东Cookie管理"`
Cookies []*CreateAccountReq `json:"cookies" v:"required#Cookie列表不能为空" dc:"Cookie列表"`
}
type BatchCreateRes struct {
g.Meta `mime:"application/json"`
SuccessIds []string `json:"successIds" dc:"成功创建的Cookie ID列表"`
FailedCount int `json:"failedCount" dc:"失败数量"`
}
// ListAccountReq 查询Cookie账户列表请求
type ListAccountReq struct {
g.Meta `path:"/jd-cookie/account/list" method:"get" summary:"查询Cookie账户列表" tags:"京东Cookie管理"`
Page int `json:"page" d:"1" dc:"页码"`
Size int `json:"size" d:"20" dc:"每页大小"`
Status int `json:"status" dc:"状态筛选"`
Keyword string `json:"keyword" dc:"关键字搜索"`
}
type ListAccountRes struct {
g.Meta `mime:"application/json"`
List []*CookieAccountInfo `json:"list" dc:"Cookie列表"`
Total int `json:"total" dc:"总数"`
}
type CookieAccountInfo struct {
CookieId string `json:"cookieId" dc:"Cookie ID"`
AccountName string `json:"accountName" dc:"账户名称"`
Status int `json:"status" dc:"状态1正常 2暂停 3失效"`
FailureCount int `json:"failureCount" dc:"连续失败次数"`
LastUsedAt string `json:"lastUsedAt" dc:"最后使用时间"`
SuspendUntil string `json:"suspendUntil" dc:"暂停解除时间"`
CreatedAt string `json:"createdAt" dc:"创建时间"`
Remark string `json:"remark" dc:"备注信息"`
}
// UpdateAccountReq 更新Cookie账户请求
type UpdateAccountReq struct {
g.Meta `path:"/jd-cookie/account/update" method:"put" summary:"更新Cookie账户" tags:"京东Cookie管理"`
CookieId string `json:"cookieId" v:"required#Cookie ID不能为空" dc:"Cookie ID"`
CookieValue string `json:"cookieValue" dc:"Cookie内容"`
AccountName string `json:"accountName" dc:"账户名称"`
Status int `json:"status" dc:"状态"`
Remark string `json:"remark" dc:"备注信息"`
}
type UpdateAccountRes struct {
g.Meta `mime:"application/json"`
}
// DeleteAccountReq 删除Cookie账户请求
type DeleteAccountReq struct {
g.Meta `path:"/jd-cookie/account/delete" method:"delete" summary:"删除Cookie账户" tags:"京东Cookie管理"`
CookieId string `json:"cookieId" v:"required#Cookie ID不能为空" dc:"Cookie ID"`
}
type DeleteAccountRes struct {
g.Meta `mime:"application/json"`
}
// BatchCheckReq 批量检测Cookie状态请求
type BatchCheckReq struct {
g.Meta `path:"/jd-cookie/account/batch-check" method:"post" summary:"批量检测Cookie状态" tags:"京东Cookie管理"`
CookieIds []string `json:"cookieIds" v:"required#Cookie ID列表不能为空" dc:"Cookie ID列表"`
}
type BatchCheckRes struct {
g.Meta `mime:"application/json"`
Results []*CookieCheckResult `json:"results" dc:"检测结果"`
}
type CookieCheckResult struct {
CookieId string `json:"cookieId" dc:"Cookie ID"`
Status int `json:"status" dc:"状态"`
Message string `json:"message" dc:"检测信息"`
}
// ====================================================================================
// 订单处理请求/响应结构
// ====================================================================================
// CreateOrderReq 创建订单请求
type CreateOrderReq struct {
g.Meta `path:"/jd-cookie/order/create" method:"post" summary:"创建订单" tags:"京东订单管理"`
OrderId string `json:"orderId" v:"required#订单号不能为空" dc:"订单号"`
Amount float64 `json:"amount" v:"required|min:0.01#订单金额不能为空|订单金额必须大于0" dc:"订单金额"`
Category string `json:"category" v:"required#商品品类不能为空" dc:"商品品类"`
}
type CreateOrderRes struct {
g.Meta `mime:"application/json"`
WxPayUrl string `json:"wxPayUrl" dc:"微信支付链接"`
ExpireTime string `json:"expireTime" dc:"链接过期时间"`
JdOrderId string `json:"jdOrderId" dc:"京东订单号"`
}
// GetPaymentUrlReq 获取支付链接请求
type GetPaymentUrlReq struct {
g.Meta `path:"/jd-cookie/order/payment-url" method:"post" summary:"获取支付链接" tags:"京东订单管理"`
OrderId string `json:"orderId" v:"required#订单号不能为空" dc:"订单号"`
}
type GetPaymentUrlRes struct {
g.Meta `mime:"application/json"`
WxPayUrl string `json:"wxPayUrl" dc:"微信支付链接"`
ExpireTime string `json:"expireTime" dc:"链接过期时间"`
}
// GetOrderStatusReq 查询订单状态请求
type GetOrderStatusReq struct {
g.Meta `path:"/jd-cookie/order/status" method:"get" summary:"查询订单状态" tags:"京东订单管理"`
OrderId string `json:"orderId" v:"required#订单号不能为空" dc:"订单号"`
}
type GetOrderStatusRes struct {
g.Meta `mime:"application/json"`
Order *OrderInfo `json:"order" dc:"订单信息"`
}
type OrderInfo struct {
OrderId string `json:"orderId" dc:"订单号"`
Amount float64 `json:"amount" dc:"订单金额"`
Category string `json:"category" dc:"商品品类"`
JdOrderId string `json:"jdOrderId" dc:"关联的京东订单号"`
Status int `json:"status" dc:"状态1待支付 2已支付 3已过期 4已取消"`
WxPayUrl string `json:"wxPayUrl" dc:"当前有效的微信支付链接"`
LastRequest string `json:"lastRequestAt" dc:"最后请求时间"`
CreatedAt string `json:"createdAt" dc:"创建时间"`
}
// ListOrderReq 订单列表查询请求
type ListOrderReq struct {
g.Meta `path:"/jd-cookie/order/list" method:"get" summary:"订单列表查询" tags:"京东订单管理"`
Page int `json:"page" d:"1" dc:"页码"`
Size int `json:"size" d:"20" dc:"每页大小"`
Status int `json:"status" dc:"状态筛选"`
StartTime string `json:"startTime" dc:"开始时间"`
EndTime string `json:"endTime" dc:"结束时间"`
}
type ListOrderRes struct {
g.Meta `mime:"application/json"`
List []*OrderInfo `json:"list" dc:"订单列表"`
Total int `json:"total" dc:"总数"`
}
// CheckJdOrderPaymentReq 检查京东订单支付状态请求
type CheckJdOrderPaymentReq struct {
g.Meta `path:"/jd-cookie/order/jd-payment-status" method:"post" summary:"检查京东订单支付状态" tags:"京东订单管理"`
JdOrderId string `json:"jd_order_id" v:"required#京东订单号不能为空" dc:"京东订单号"`
}
type CheckJdOrderPaymentRes struct {
g.Meta `mime:"application/json"`
JdOrderId string `json:"jd_order_id" dc:"京东订单号"`
IsPaid bool `json:"is_paid" dc:"是否已支付"`
PaymentStatus int `json:"payment_status" dc:"支付状态1待支付 2已支付 3已过期 4已取消"`
Message string `json:"message" dc:"状态描述"`
CanReuse bool `json:"can_reuse" dc:"是否可以复用"`
}
// ====================================================================================
// 历史记录请求/响应结构
// ====================================================================================
// CookieHistoryReq Cookie变更历史请求
type CookieHistoryReq struct {
g.Meta `path:"/jd-cookie/history/cookie" method:"get" summary:"Cookie变更历史" tags:"京东历史记录"`
CookieId string `json:"cookieId" v:"required#Cookie ID不能为空" dc:"Cookie ID"`
Page int `json:"page" d:"1" dc:"页码"`
Size int `json:"size" d:"20" dc:"每页大小"`
ChangeType string `json:"changeType" dc:"变更类型筛选"`
}
type CookieHistoryRes struct {
g.Meta `mime:"application/json"`
List []*CookieHistoryInfo `json:"list" dc:"变更历史列表"`
Total int `json:"total" dc:"总数"`
}
type CookieHistoryInfo struct {
HistoryUuid string `json:"historyUuid" dc:"历史记录唯一标识"`
CookieId string `json:"cookieId" dc:"Cookie ID"`
ChangeType string `json:"changeType" dc:"变更类型"`
StatusBefore int `json:"statusBefore" dc:"变更前状态"`
StatusAfter int `json:"statusAfter" dc:"变更后状态"`
UserOrderId string `json:"userOrderId" dc:"关联的订单号"`
FailureCount int `json:"failureCount" dc:"失败次数"`
CreatedAt string `json:"createdAt" dc:"创建时间"`
}
// OrderHistoryReq 订单变更历史请求
type OrderHistoryReq struct {
g.Meta `path:"/jd-cookie/history/order" method:"get" summary:"订单变更历史" tags:"京东历史记录"`
OrderId string `json:"orderId" v:"required#订单号不能为空" dc:"订单号"`
OrderType string `json:"orderType" v:"required|in:user,jd#订单类型不能为空|订单类型只能是user或jd" dc:"订单类型(user/jd)"`
Page int `json:"page" d:"1" dc:"页码"`
Size int `json:"size" d:"20" dc:"每页大小"`
}
type OrderHistoryRes struct {
g.Meta `mime:"application/json"`
List []*OrderHistoryInfo `json:"list" dc:"变更历史列表"`
Total int `json:"total" dc:"总数"`
}
type OrderHistoryInfo struct {
HistoryUuid string `json:"historyUuid" dc:"历史记录唯一标识"`
OrderId string `json:"orderId" dc:"订单号"`
ChangeType string `json:"changeType" dc:"变更类型"`
JdOrderId string `json:"jdOrderId" dc:"关联的京东订单号"`
WxPayUrl string `json:"wxPayUrl" dc:"微信支付链接"`
CreatedAt string `json:"createdAt" dc:"创建时间"`
}

View File

@@ -0,0 +1,68 @@
package v1
import (
"github.com/gogf/gf/v2/frame/g"
)
// ====================================================================================
// History API
// ====================================================================================
type JdCookieHistoryApi struct {
CookieHistoryReq *CookieHistoryReq `path:"/jd-cookie/history/cookie" method:"get" summary:"Cookie Change History" tags:"JD History"`
OrderHistoryReq *OrderHistoryReq `path:"/jd-cookie/history/order" method:"get" summary:"Order Change History" tags:"JD History"`
}
// ====================================================================================
// History Request/Response Structures
// ====================================================================================
// CookieHistoryReq Cookie Change History Request
type CookieHistoryReq struct {
g.Meta `path:"/jd-cookie/history/cookie" method:"get" summary:"Cookie Change History" tags:"JD History"`
CookieId string `json:"cookieId" v:"required#Cookie ID不能为空" dc:"Cookie ID"`
Page int `json:"page" d:"1" dc:"页码"`
Size int `json:"size" d:"20" dc:"每页大小"`
ChangeType string `json:"changeType" dc:"变更类型筛选"`
}
type CookieHistoryRes struct {
g.Meta `mime:"application/json"`
List []*CookieHistoryInfo `json:"list" dc:"变更历史列表"`
Total int `json:"total" dc:"总数"`
}
type CookieHistoryInfo struct {
HistoryUuid string `json:"historyUuid" dc:"历史记录唯一标识"`
CookieId string `json:"cookieId" dc:"Cookie ID"`
ChangeType string `json:"changeType" dc:"变更类型"`
StatusBefore int `json:"statusBefore" dc:"变更前状态"`
StatusAfter int `json:"statusAfter" dc:"变更后状态"`
UserOrderId string `json:"userOrderId" dc:"关联的订单号"`
FailureCount int `json:"failureCount" dc:"失败次数"`
CreatedAt string `json:"createdAt" dc:"创建时间"`
}
// OrderHistoryReq Order Change History Request
type OrderHistoryReq struct {
g.Meta `path:"/jd-cookie/history/order" method:"get" summary:"Order Change History" tags:"JD History"`
OrderId string `json:"orderId" v:"required#订单号不能为空" dc:"订单号"`
OrderType string `json:"orderType" v:"required|in:user,jd#订单类型不能为空|订单类型只能是user或jd" dc:"订单类型(user/jd)"`
Page int `json:"page" d:"1" dc:"页码"`
Size int `json:"size" d:"20" dc:"每页大小"`
}
type OrderHistoryRes struct {
g.Meta `mime:"application/json"`
List []*OrderHistoryInfo `json:"list" dc:"变更历史列表"`
Total int `json:"total" dc:"总数"`
}
type OrderHistoryInfo struct {
HistoryUuid string `json:"historyUuid" dc:"历史记录唯一标识"`
OrderId string `json:"orderId" dc:"订单号"`
ChangeType string `json:"changeType" dc:"变更类型"`
JdOrderId string `json:"jdOrderId" dc:"关联的京东订单号"`
WxPayUrl string `json:"wxPayUrl" dc:"微信支付链接"`
CreatedAt string `json:"createdAt" dc:"创建时间"`
}

178
api/jd_cookie/v1/order.go Normal file
View File

@@ -0,0 +1,178 @@
package v1
import (
"github.com/gogf/gf/v2/frame/g"
)
// ====================================================================================
// Order Processing API
// ====================================================================================
type JdCookieOrderApi struct {
CreateOrderReq *CreateOrderReq `path:"/jd-cookie/order/create" method:"post" summary:"Create Order" tags:"JD Order Management"`
GetPaymentUrlReq *GetPaymentUrlReq `path:"/jd-cookie/order/payment-url" method:"post" summary:"Get Payment URL" tags:"JD Order Management"`
GetOrderStatusReq *GetOrderStatusReq `path:"/jd-cookie/order/status" method:"get" summary:"Query Order Status" tags:"JD Order Management"`
GetOrderReq *GetOrderReq `path:"/jd-cookie/order/get" method:"get" summary:"Get Single Order" tags:"JD Order Management"`
GetJdOrderReq *GetJdOrderReq `path:"/jd-cookie/order/jd-order" method:"get" summary:"Get Single JD Order" tags:"JD Order Management"`
ListOrderReq *ListOrderReq `path:"/jd-cookie/order/list" method:"get" summary:"Order List Query" tags:"JD Order Management"`
ListJdOrderReq *ListJdOrderReq `path:"/jd-cookie/order/jd-list" method:"get" summary:"JD Order List Query" tags:"JD Order Management"`
CheckJdOrderPaymentReq *CheckJdOrderPaymentReq `path:"/jd-cookie/order/jd-payment-status" method:"post" summary:"Check JD Order Payment Status" tags:"JD Order Management"`
GetJdOrderHistoryReq *GetJdOrderHistoryReq `path:"/jd-cookie/order/jd-order-history" method:"get" summary:"Get JD Order History" tags:"JD Order Management"`
}
// ====================================================================================
// Order Processing Request/Response Structures
// ====================================================================================
// CreateOrderReq Create Order Request
type CreateOrderReq struct {
g.Meta `path:"/jd-cookie/order/create" method:"post" summary:"Create Order" tags:"JD Order Management"`
OrderId string `json:"orderId" v:"required#订单号不能为空" dc:"订单号"`
Amount float64 `json:"amount" v:"required|min:0.01#订单金额不能为空|订单金额必须大于0" dc:"订单金额"`
Category string `json:"category" v:"required#商品品类不能为空" dc:"商品品类"`
}
type CreateOrderRes struct {
g.Meta `mime:"application/json"`
WxPayUrl string `json:"wxPayUrl" dc:"微信支付链接"`
ExpireTime string `json:"expireTime" dc:"链接过期时间"`
JdOrderId string `json:"jdOrderId" dc:"京东订单号"`
}
// GetPaymentUrlReq Get Payment URL Request
type GetPaymentUrlReq struct {
g.Meta `path:"/jd-cookie/order/payment-url" method:"post" summary:"Get Payment URL" tags:"JD Order Management"`
OrderId string `json:"orderId" v:"required#订单号不能为空" dc:"订单号"`
}
type GetPaymentUrlRes struct {
g.Meta `mime:"application/json"`
WxPayUrl string `json:"wxPayUrl" dc:"微信支付链接"`
ExpireTime string `json:"expireTime" dc:"链接过期时间"`
}
// GetOrderStatusReq Query Order Status Request
type GetOrderStatusReq struct {
g.Meta `path:"/jd-cookie/order/status" method:"get" summary:"Query Order Status" tags:"JD Order Management"`
OrderId string `json:"orderId" v:"required#订单号不能为空" dc:"订单号"`
}
type GetOrderStatusRes struct {
g.Meta `mime:"application/json"`
Order *OrderInfo `json:"order" dc:"订单信息"`
}
// GetOrderReq Get Single Order Request
type GetOrderReq struct {
g.Meta `path:"/jd-cookie/order/get" method:"get" summary:"Get Single Order" tags:"JD Order Management"`
OrderId string `json:"orderId" v:"required#订单号不能为空" dc:"订单号"`
}
type GetOrderRes struct {
g.Meta `mime:"application/json"`
Order *OrderInfo `json:"order" dc:"订单详情"`
}
// GetJdOrderReq Get Single JD Order Request
type GetJdOrderReq struct {
g.Meta `path:"/jd-cookie/order/jd-order" method:"get" summary:"Get Single JD Order" tags:"JD Order Management"`
JdOrderId string `json:"jdOrderId" v:"required#京东订单号不能为空" dc:"京东订单号"`
}
type GetJdOrderRes struct {
g.Meta `mime:"application/json"`
Order *JdOrderInfo `json:"order" dc:"京东订单详情"`
}
type OrderInfo struct {
OrderId string `json:"orderId" dc:"订单号"`
Amount float64 `json:"amount" dc:"订单金额"`
Category string `json:"category" dc:"商品品类"`
JdOrderId string `json:"jdOrderId" dc:"关联的京东订单号"`
Status int `json:"status" dc:"状态1待支付 2已支付 3已过期 4已取消"`
WxPayUrl string `json:"wxPayUrl" dc:"当前有效的微信支付链接"`
LastRequest string `json:"lastRequestAt" dc:"最后请求时间"`
CreatedAt string `json:"createdAt" dc:"创建时间"`
}
type JdOrderInfo struct {
JdOrderId string `json:"jdOrderId" dc:"京东订单号"`
OrderId string `json:"orderId" dc:"关联的内部订单号"`
Amount float64 `json:"amount" dc:"订单金额"`
Category string `json:"category" dc:"商品品类"`
Status int `json:"status" dc:"状态1待支付 2已支付 3已过期 4已取消"`
PaidAt string `json:"paidAt" dc:"支付时间"`
CreatedAt string `json:"createdAt" dc:"创建时间"`
UpdatedAt string `json:"updatedAt" dc:"更新时间"`
}
// ListOrderReq Order List Query Request
type ListOrderReq struct {
g.Meta `path:"/jd-cookie/order/list" method:"get" summary:"Order List Query" tags:"JD Order Management"`
Page int `json:"page" d:"1" dc:"页码"`
Size int `json:"size" d:"20" dc:"每页大小"`
Status int `json:"status" dc:"状态筛选"`
StartTime string `json:"startTime" dc:"开始时间"`
EndTime string `json:"endTime" dc:"结束时间"`
}
type ListOrderRes struct {
g.Meta `mime:"application/json"`
List []*OrderInfo `json:"list" dc:"订单列表"`
Total int `json:"total" dc:"总数"`
}
// ListJdOrderReq JD Order List Query Request
type ListJdOrderReq struct {
g.Meta `path:"/jd-cookie/order/jd-list" method:"get" summary:"JD Order List Query" tags:"JD Order Management"`
Page int `json:"page" d:"1" dc:"页码"`
Size int `json:"size" d:"20" dc:"每页大小"`
Status int `json:"status" dc:"状态筛选1待支付 2已支付 3已过期 4已取消"`
StartTime string `json:"startTime" dc:"开始时间"`
EndTime string `json:"endTime" dc:"结束时间"`
OrderId string `json:"orderId" dc:"关联的内部订单号筛选"`
}
type ListJdOrderRes struct {
g.Meta `mime:"application/json"`
List []*JdOrderInfo `json:"list" dc:"京东订单列表"`
Total int `json:"total" dc:"总数"`
}
// CheckJdOrderPaymentReq Check JD Order Payment Status Request
type CheckJdOrderPaymentReq struct {
g.Meta `path:"/jd-cookie/order/jd-payment-status" method:"post" summary:"Check JD Order Payment Status" tags:"JD Order Management"`
JdOrderId string `json:"jd_order_id" v:"required#京东订单号不能为空" dc:"京东订单号"`
}
type CheckJdOrderPaymentRes struct {
g.Meta `mime:"application/json"`
JdOrderId string `json:"jd_order_id" dc:"京东订单号"`
IsPaid bool `json:"is_paid" dc:"是否已支付"`
PaymentStatus int `json:"payment_status" dc:"支付状态1待支付 2已支付 3已过期 4已取消"`
Message string `json:"message" dc:"状态描述"`
CanReuse bool `json:"can_reuse" dc:"是否可以复用"`
}
// GetJdOrderHistoryReq Get JD Order History Request
type GetJdOrderHistoryReq struct {
g.Meta `path:"/jd-cookie/order/jd-order-history" method:"get" summary:"Get JD Order History" tags:"JD Order Management"`
OrderId string `json:"orderId" v:"required#订单号不能为空" dc:"订单号"`
Page int `json:"page" d:"1" dc:"页码"`
Size int `json:"size" d:"20" dc:"每页大小"`
}
type GetJdOrderHistoryRes struct {
g.Meta `mime:"application/json"`
List []*JdOrderHistoryInfo `json:"list" dc:"京东订单历史列表"`
Total int `json:"total" dc:"总数"`
}
type JdOrderHistoryInfo struct {
HistoryUuid string `json:"historyUuid" dc:"历史记录唯一标识"`
JdOrderId string `json:"jdOrderId" dc:"京东订单号"`
ChangeType string `json:"changeType" dc:"变更类型create,bind,unbind,pay,expire,invalid,replace"`
OrderId string `json:"orderId" dc:"关联的订单号"`
WxPayUrl string `json:"wxPayUrl" dc:"微信支付链接"`
CreatedAt string `json:"createdAt" dc:"创建时间"`
}

View File

@@ -8,7 +8,6 @@ import (
"kami/internal/controller/card_info_original_jd"
"kami/internal/controller/card_info_t_mall_game"
"kami/internal/controller/card_info_walmart"
"kami/internal/controller/card_redeem_jd"
"kami/internal/controller/jd_cookie"
monitorCtrl "kami/internal/controller/monitor"
"kami/internal/controller/order"
@@ -69,7 +68,6 @@ var Main = gcmd.Command{
group.Bind(card_info_walmart.NewV1())
group.Bind(card_info_original_jd.NewV1())
group.Bind(card_info_c_trip.NewV1())
group.Bind(card_redeem_jd.NewV1())
group.Bind(jd_cookie.NewV1())
})
monitor.Register(ctx) // 注册监控任务

View File

@@ -71,6 +71,8 @@ const (
CookieChangeTypeUse CookieChangeType = "use" // 使用
CookieChangeTypeRefreshFail CookieChangeType = "refresh_fail" // 刷新失败
CookieChangeTypeReplaced CookieChangeType = "replaced" // 被替换
CookieChangeTypeDelete CookieChangeType = "delete" // 删除
CookieChangeTypeUpdate CookieChangeType = "update" // 更新
)
// JdOrderChangeType 京东订单变更类型
@@ -118,7 +120,7 @@ const (
OrderReuseTimeout = 15
// JdOrderReuseTimeout 京东订单复用超时时间(分钟)
JdOrderReuseTimeout = 15
JdOrderReuseTimeout = 30
// CookieRotationKey Redis中Cookie轮询索引的键名
CookieRotationKey = "jd_cookie:rotation:index"

View File

@@ -1,5 +0,0 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package card_redeem_jd

View File

@@ -1,15 +0,0 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package card_redeem_jd
import (
"kami/api/card_redeem_jd"
)
type ControllerV1 struct{}
func NewV1() card_redeem_jd.ICardRedeemJdV1 {
return &ControllerV1{}
}

View File

@@ -1,21 +0,0 @@
package card_redeem_jd
import (
"context"
v1 "kami/api/card_redeem_jd/v1"
"kami/internal/consts"
"kami/internal/model"
"kami/internal/service"
"github.com/gogf/gf/v2/text/gstr"
)
func (c *ControllerV1) AccountAdd(ctx context.Context, req *v1.AccountAddReq) (res *v1.AccountAddRes, err error) {
req.Cookie = gstr.TrimAll(req.Cookie)
req.Name = gstr.TrimAll(req.Name)
err = service.CardRedeemCookie().Save(ctx, &model.CardRedeemCookieCreatedInput{
Category: consts.CardRedeemCookieCategoryJD,
AccountEntity: req.AccountEntity,
}, nil)
return
}

View File

@@ -1,16 +0,0 @@
package card_redeem_jd
import (
"context"
v1 "kami/api/card_redeem_jd/v1"
"kami/internal/model"
"kami/internal/service"
)
func (c *ControllerV1) AccountDelete(ctx context.Context, req *v1.AccountDeleteReq) (res *v1.AccountDeleteRes, err error) {
err = service.CardRedeemCookie().Delete(ctx, &model.CardRedeemCookieDeleteInput{
Id: req.ID,
}, nil)
return
}

View File

@@ -1,29 +0,0 @@
package card_redeem_jd
import (
"context"
v1 "kami/api/card_redeem_jd/v1"
"kami/internal/consts"
"kami/internal/errHandler"
"kami/internal/model"
"kami/internal/service"
"github.com/gogf/gf/v2/errors/gcode"
)
func (c *ControllerV1) AccountGet(ctx context.Context, req *v1.AccountGetReq) (res *v1.AccountGetRes, err error) {
res = &v1.AccountGetRes{}
CookieEntity, err := service.CardRedeemCookie().GetOne(ctx, &model.CardRedeemCookieGetInput{
Id: req.ID,
Category: consts.CardRedeemCookieCategoryJD,
}, nil)
if err != nil {
err = errHandler.WrapError(ctx, gcode.CodeNotFound, err, "未找到该ck")
}
res.CookieInfo = &v1.CookieInfo{
V1CardRedeemCookieInfo: CookieEntity,
Status: consts.CardRedeemCookieStatus(CookieEntity.Status),
}
return
}

View File

@@ -1,63 +0,0 @@
package card_redeem_jd
import (
"context"
v1 "kami/api/card_redeem_jd/v1"
"kami/internal/consts"
"kami/internal/errHandler"
"kami/internal/model"
"kami/internal/model/entity"
"kami/internal/service"
"github.com/duke-git/lancet/v2/slice"
"github.com/gogf/gf/v2/errors/gcode"
)
func (c *ControllerV1) AccountList(ctx context.Context, req *v1.AccountListReq) (res *v1.AccountListRes, err error) {
res = &v1.AccountListRes{}
res.List = make([]*v1.CookieInfo, 0)
res.Total = 0
list, total, err := service.CardRedeemCookie().AccountList(ctx, &model.CardRedeemCookieGetListInput{
AccountListReq: req,
Category: consts.CardRedeemCookieCategoryJD,
}, nil)
if err != nil {
return nil, errHandler.WrapError(ctx, gcode.CodeInternalError, err, "获取列表失败")
}
statistic, err := service.CardRedeemCookie().AccountStatistic(ctx, &model.CardRedeemCookieStatisticInput{
AccountIds: slice.Map(list, func(index int, item *entity.V1CardRedeemCookieInfo) uint {
return uint(item.Id)
}),
}, nil)
if err != nil {
return nil, errHandler.WrapError(ctx, gcode.CodeInternalError, err, "获取统计失败")
}
slice.ForEach(list, func(index int, item *entity.V1CardRedeemCookieInfo) {
statisticItem, ok := slice.FindBy(statistic, func(index int, item2 *model.CardRedeemCookieStatisticOutput) bool {
return item2.CookieId == item.Id
})
if ok {
res.List = append(res.List, &v1.CookieInfo{
V1CardRedeemCookieInfo: item,
Status: consts.CardRedeemCookieStatus(item.Status),
TotalCount: statisticItem.TotalCount,
SuccessCount: statisticItem.SuccessCount,
TotalAmount: statisticItem.TotalAmount,
SuccessAmount: statisticItem.SuccessAmount,
})
} else {
res.List = append(res.List, &v1.CookieInfo{
V1CardRedeemCookieInfo: item,
Status: consts.CardRedeemCookieStatus(item.Status),
TotalCount: 0,
SuccessCount: 0,
TotalAmount: 0,
SuccessAmount: 0,
})
}
})
res.Total = total
return
}

View File

@@ -1,19 +0,0 @@
package card_redeem_jd
import (
"context"
v1 "kami/api/card_redeem_jd/v1"
"kami/internal/consts"
"kami/internal/model"
"kami/internal/service"
)
func (c *ControllerV1) AccountStatus(ctx context.Context, req *v1.AccountStatusReq) (res *v1.AccountStatusRes, err error) {
err = service.CardRedeemCookie().UpdateStatus(ctx, &model.CardRedeemCookieStatusInput{
Id: req.ID,
Status: req.Status,
Category: consts.CardRedeemCookieCategoryJD,
}, nil)
return
}

View File

@@ -1,21 +0,0 @@
package card_redeem_jd
import (
"context"
"github.com/gogf/gf/v2/text/gstr"
v1 "kami/api/card_redeem_jd/v1"
"kami/internal/model"
"kami/internal/service"
)
func (c *ControllerV1) AccountUpdate(ctx context.Context, req *v1.AccountUpdateReq) (res *v1.AccountUpdateRes, err error) {
req.Cookie = gstr.TrimAll(req.Cookie)
req.Name = gstr.TrimAll(req.Name)
err = service.CardRedeemCookie().Update(ctx, &model.CardRedeemCookieUpdatedInput{
Id: req.ID,
AccountEntity: req.AccountEntity,
}, nil)
return
}

View File

@@ -1,22 +0,0 @@
package card_redeem_jd
import (
"context"
v1 "kami/api/card_redeem_jd/v1"
"kami/internal/model"
"kami/internal/service"
)
func (c *ControllerV1) OrderList(ctx context.Context, req *v1.OrderListReq) (res *v1.OrderListRes, err error) {
orderList, err := service.CardRedeemCookie().OrderList(ctx, &model.CardRedeemCookieOrderListInput{
OrderListReq: req,
}, nil)
if err != nil {
return nil, err
}
res = &v1.OrderListRes{}
res.Total = orderList.Total
res.List = orderList.List
return
}

View File

@@ -1,44 +0,0 @@
package card_redeem_jd
import (
"context"
v1 "kami/api/card_redeem_jd/v1"
"kami/internal/consts"
"kami/internal/model"
"kami/internal/service"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/glog"
)
func (c *ControllerV1) PlaceOrder(ctx context.Context, req *v1.PlaceOrderReq) (res *v1.PlaceOrderRes, err error) {
// 下单
orderInfo, err := service.CardRedeemCookie().PlaceOrder(ctx, &model.CardRedeemCookiePlaceOrderInput{
OrderId: req.MerchantOrderId,
OrderAmount: req.OrderAmount,
UserAgent: req.UserAgent,
Category: req.Category,
}, nil)
if err != nil {
glog.Error(ctx, "下单失败", req.MerchantOrderId, err)
return res, gerror.NewCode(gcode.CodeOperationFailed, "下单失败")
}
if orderInfo.JdOrder.WebPayLink == "" {
glog.Error(ctx, "下单失败", req.MerchantOrderId)
return res, gerror.NewCode(gcode.CodeOperationFailed, "下单失败")
}
glog.Info(ctx, "下单成功", req.MerchantOrderId, orderInfo)
res = &v1.PlaceOrderRes{
WxPay: orderInfo.JdOrder.WebPayLink,
MerchantOrder: req.MerchantOrderId,
OrderNo: orderInfo.OrderNo,
OrderAmount: orderInfo.OrderAmount,
OrderStatus: consts.CardRedeemCookieOrderStatus(orderInfo.Status),
}
return
}

View File

@@ -0,0 +1,21 @@
package jd_cookie
import (
"context"
"kami/api/jd_cookie/v1"
"kami/internal/service"
)
func (c *ControllerV1) GetAccount(ctx context.Context, req *v1.GetAccountReq) (res *v1.GetAccountRes, err error) {
account, err := service.JdCookie().GetAccount(ctx, req.CookieId)
if err != nil {
return nil, err
}
res = &v1.GetAccountRes{
Account: account,
}
return res, nil
}

View File

@@ -0,0 +1,21 @@
package jd_cookie
import (
"context"
"kami/api/jd_cookie/v1"
"kami/internal/service"
)
func (c *ControllerV1) GetJdOrder(ctx context.Context, req *v1.GetJdOrderReq) (res *v1.GetJdOrderRes, err error) {
order, err := service.JdCookie().GetJdOrder(ctx, req.JdOrderId)
if err != nil {
return nil, err
}
res = &v1.GetJdOrderRes{
Order: order,
}
return res, nil
}

View File

@@ -0,0 +1,22 @@
package jd_cookie
import (
"context"
"kami/api/jd_cookie/v1"
"kami/internal/service"
)
func (c *ControllerV1) GetJdOrderHistory(ctx context.Context, req *v1.GetJdOrderHistoryReq) (res *v1.GetJdOrderHistoryRes, err error) {
list, total, err := service.JdCookie().GetJdOrderHistoryByOrderId(ctx, req.OrderId, req.Page, req.Size)
if err != nil {
return nil, err
}
res = &v1.GetJdOrderHistoryRes{
List: list,
Total: total,
}
return res, nil
}

View File

@@ -0,0 +1,21 @@
package jd_cookie
import (
"context"
"kami/api/jd_cookie/v1"
"kami/internal/service"
)
func (c *ControllerV1) GetOrder(ctx context.Context, req *v1.GetOrderReq) (res *v1.GetOrderRes, err error) {
order, err := service.JdCookie().GetOrder(ctx, req.OrderId)
if err != nil {
return nil, err
}
res = &v1.GetOrderRes{
Order: order,
}
return res, nil
}

View File

@@ -0,0 +1,21 @@
package jd_cookie
import (
"context"
"kami/api/jd_cookie/v1"
"kami/internal/service"
)
func (c *ControllerV1) ListJdOrder(ctx context.Context, req *v1.ListJdOrderReq) (res *v1.ListJdOrderRes, err error) {
list, total, err := service.JdCookie().ListJdOrder(ctx, req.Page, req.Size, req.Status, req.StartTime, req.EndTime, req.OrderId)
if err != nil {
return nil, err
}
res = &v1.ListJdOrderRes{
List: list,
Total: total,
}
return
}

View File

@@ -1,97 +0,0 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// V1CardRedeemCookieInfoDao is the data access object for the table card_redeem_cookie_info.
type V1CardRedeemCookieInfoDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of the current DAO.
columns V1CardRedeemCookieInfoColumns // columns contains all the column names of Table for convenient usage.
handlers []gdb.ModelHandler // handlers for customized model modification.
}
// V1CardRedeemCookieInfoColumns defines and stores column names for the table card_redeem_cookie_info.
type V1CardRedeemCookieInfoColumns struct {
Id string //
Name string //
Cookie string //
Notes string //
Status string //
Category string //
FailCount string // 调用次数
CreatedAt string //
UpdatedAt string //
DeletedAt string //
}
// v1CardRedeemCookieInfoColumns holds the columns for the table card_redeem_cookie_info.
var v1CardRedeemCookieInfoColumns = V1CardRedeemCookieInfoColumns{
Id: "id",
Name: "name",
Cookie: "cookie",
Notes: "notes",
Status: "status",
Category: "category",
FailCount: "fail_count",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
DeletedAt: "deleted_at",
}
// NewV1CardRedeemCookieInfoDao creates and returns a new DAO object for table data access.
func NewV1CardRedeemCookieInfoDao(handlers ...gdb.ModelHandler) *V1CardRedeemCookieInfoDao {
return &V1CardRedeemCookieInfoDao{
group: "default",
table: "card_redeem_cookie_info",
columns: v1CardRedeemCookieInfoColumns,
handlers: handlers,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *V1CardRedeemCookieInfoDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *V1CardRedeemCookieInfoDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *V1CardRedeemCookieInfoDao) Columns() V1CardRedeemCookieInfoColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *V1CardRedeemCookieInfoDao) Group() string {
return dao.group
}
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
func (dao *V1CardRedeemCookieInfoDao) Ctx(ctx context.Context) *gdb.Model {
model := dao.DB().Model(dao.table)
for _, handler := range dao.handlers {
model = handler(model)
}
return model.Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// It rolls back the transaction and returns the error if function f returns a non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note: Do not commit or roll back the transaction in function f,
// as it is automatically handled by this function.
func (dao *V1CardRedeemCookieInfoDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@@ -1,99 +0,0 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// V1CardRedeemCookieOrderDao is the data access object for the table card_redeem_cookie_order.
type V1CardRedeemCookieOrderDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of the current DAO.
columns V1CardRedeemCookieOrderColumns // columns contains all the column names of Table for convenient usage.
handlers []gdb.ModelHandler // handlers for customized model modification.
}
// V1CardRedeemCookieOrderColumns defines and stores column names for the table card_redeem_cookie_order.
type V1CardRedeemCookieOrderColumns struct {
Id string //
BankOrderId string // 订单id
OrderAmount string // 订单金额
CookieId string //
OrderNo string // 订单编号
JdOrderNo string //
Status string //
Note string //
DeletedAt string //
CreatedAt string //
UpdatedAt string //
}
// v1CardRedeemCookieOrderColumns holds the columns for the table card_redeem_cookie_order.
var v1CardRedeemCookieOrderColumns = V1CardRedeemCookieOrderColumns{
Id: "id",
BankOrderId: "bank_order_id",
OrderAmount: "order_amount",
CookieId: "cookie_id",
OrderNo: "order_no",
JdOrderNo: "jd_order_no",
Status: "status",
Note: "note",
DeletedAt: "deleted_at",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
}
// NewV1CardRedeemCookieOrderDao creates and returns a new DAO object for table data access.
func NewV1CardRedeemCookieOrderDao(handlers ...gdb.ModelHandler) *V1CardRedeemCookieOrderDao {
return &V1CardRedeemCookieOrderDao{
group: "default",
table: "card_redeem_cookie_order",
columns: v1CardRedeemCookieOrderColumns,
handlers: handlers,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *V1CardRedeemCookieOrderDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *V1CardRedeemCookieOrderDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *V1CardRedeemCookieOrderDao) Columns() V1CardRedeemCookieOrderColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *V1CardRedeemCookieOrderDao) Group() string {
return dao.group
}
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
func (dao *V1CardRedeemCookieOrderDao) Ctx(ctx context.Context) *gdb.Model {
model := dao.DB().Model(dao.table)
for _, handler := range dao.handlers {
model = handler(model)
}
return model.Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// It rolls back the transaction and returns the error if function f returns a non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note: Do not commit or roll back the transaction in function f,
// as it is automatically handled by this function.
func (dao *V1CardRedeemCookieOrderDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@@ -1,95 +0,0 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// V1CardRedeemCookieOrderHistoryDao is the data access object for the table card_redeem_cookie_order_history.
type V1CardRedeemCookieOrderHistoryDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of the current DAO.
columns V1CardRedeemCookieOrderHistoryColumns // columns contains all the column names of Table for convenient usage.
handlers []gdb.ModelHandler // handlers for customized model modification.
}
// V1CardRedeemCookieOrderHistoryColumns defines and stores column names for the table card_redeem_cookie_order_history.
type V1CardRedeemCookieOrderHistoryColumns struct {
Id string // 主键ID
OrderId string // 关联的订单ID
OrderNo string // 订单号
BankOrderId string // 银行订单号
Action string // 订单动作
Status string // 订单状态
Amount string // 订单金额
Remark string // 备注信息
CreatedAt string // 创建时间
}
// v1CardRedeemCookieOrderHistoryColumns holds the columns for the table card_redeem_cookie_order_history.
var v1CardRedeemCookieOrderHistoryColumns = V1CardRedeemCookieOrderHistoryColumns{
Id: "id",
OrderId: "order_id",
OrderNo: "order_no",
BankOrderId: "bank_order_id",
Action: "action",
Status: "status",
Amount: "amount",
Remark: "remark",
CreatedAt: "created_at",
}
// NewV1CardRedeemCookieOrderHistoryDao creates and returns a new DAO object for table data access.
func NewV1CardRedeemCookieOrderHistoryDao(handlers ...gdb.ModelHandler) *V1CardRedeemCookieOrderHistoryDao {
return &V1CardRedeemCookieOrderHistoryDao{
group: "default",
table: "card_redeem_cookie_order_history",
columns: v1CardRedeemCookieOrderHistoryColumns,
handlers: handlers,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *V1CardRedeemCookieOrderHistoryDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *V1CardRedeemCookieOrderHistoryDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *V1CardRedeemCookieOrderHistoryDao) Columns() V1CardRedeemCookieOrderHistoryColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *V1CardRedeemCookieOrderHistoryDao) Group() string {
return dao.group
}
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
func (dao *V1CardRedeemCookieOrderHistoryDao) Ctx(ctx context.Context) *gdb.Model {
model := dao.DB().Model(dao.table)
for _, handler := range dao.handlers {
model = handler(model)
}
return model.Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// It rolls back the transaction and returns the error if function f returns a non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note: Do not commit or roll back the transaction in function f,
// as it is automatically handled by this function.
func (dao *V1CardRedeemCookieOrderHistoryDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@@ -1,113 +0,0 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// V1CardRedeemCookieOrderJdDao is the data access object for the table card_redeem_cookie_order_jd.
type V1CardRedeemCookieOrderJdDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of the current DAO.
columns V1CardRedeemCookieOrderJdColumns // columns contains all the column names of Table for convenient usage.
handlers []gdb.ModelHandler // handlers for customized model modification.
}
// V1CardRedeemCookieOrderJdColumns defines and stores column names for the table card_redeem_cookie_order_jd.
type V1CardRedeemCookieOrderJdColumns struct {
Id string //
CookieOrderId string // 订单 id
CookieAccountId string // cookieid
ResponseData string // 返回值
Status string //
PayId string //
WebPayLink string //
ClientPayLink string //
OrderNo string //
UserAgent string //
UserClient string //
Note string //
CreatedAt string //
UpdatedAt string //
DeletedAt string //
CardNo string //
CardPassword string //
Category string // 添加不同种类
}
// v1CardRedeemCookieOrderJdColumns holds the columns for the table card_redeem_cookie_order_jd.
var v1CardRedeemCookieOrderJdColumns = V1CardRedeemCookieOrderJdColumns{
Id: "id",
CookieOrderId: "cookie_order_id",
CookieAccountId: "cookie_account_id",
ResponseData: "response_data",
Status: "status",
PayId: "pay_id",
WebPayLink: "web_pay_link",
ClientPayLink: "client_pay_link",
OrderNo: "order_no",
UserAgent: "user_agent",
UserClient: "user_client",
Note: "note",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
DeletedAt: "deleted_at",
CardNo: "card_no",
CardPassword: "card_password",
Category: "category",
}
// NewV1CardRedeemCookieOrderJdDao creates and returns a new DAO object for table data access.
func NewV1CardRedeemCookieOrderJdDao(handlers ...gdb.ModelHandler) *V1CardRedeemCookieOrderJdDao {
return &V1CardRedeemCookieOrderJdDao{
group: "default",
table: "card_redeem_cookie_order_jd",
columns: v1CardRedeemCookieOrderJdColumns,
handlers: handlers,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *V1CardRedeemCookieOrderJdDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *V1CardRedeemCookieOrderJdDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *V1CardRedeemCookieOrderJdDao) Columns() V1CardRedeemCookieOrderJdColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *V1CardRedeemCookieOrderJdDao) Group() string {
return dao.group
}
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
func (dao *V1CardRedeemCookieOrderJdDao) Ctx(ctx context.Context) *gdb.Model {
model := dao.DB().Model(dao.table)
for _, handler := range dao.handlers {
model = handler(model)
}
return model.Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// It rolls back the transaction and returns the error if function f returns a non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note: Do not commit or roll back the transaction in function f,
// as it is automatically handled by this function.
func (dao *V1CardRedeemCookieOrderJdDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@@ -1,93 +0,0 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// V1CardRedeemCookieOrderJdHistoryDao is the data access object for the table card_redeem_cookie_order_jd_history.
type V1CardRedeemCookieOrderJdHistoryDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of the current DAO.
columns V1CardRedeemCookieOrderJdHistoryColumns // columns contains all the column names of Table for convenient usage.
handlers []gdb.ModelHandler // handlers for customized model modification.
}
// V1CardRedeemCookieOrderJdHistoryColumns defines and stores column names for the table card_redeem_cookie_order_jd_history.
type V1CardRedeemCookieOrderJdHistoryColumns struct {
Id string // 主键ID
OrderId string // 关联的订单ID
OrderNo string // 订单号
Action string // 订单动作
Status string // 订单状态
Amount string // 订单金额
Remark string // 备注信息
CreatedAt string // 创建时间
}
// v1CardRedeemCookieOrderJdHistoryColumns holds the columns for the table card_redeem_cookie_order_jd_history.
var v1CardRedeemCookieOrderJdHistoryColumns = V1CardRedeemCookieOrderJdHistoryColumns{
Id: "id",
OrderId: "order_id",
OrderNo: "order_no",
Action: "action",
Status: "status",
Amount: "amount",
Remark: "remark",
CreatedAt: "created_at",
}
// NewV1CardRedeemCookieOrderJdHistoryDao creates and returns a new DAO object for table data access.
func NewV1CardRedeemCookieOrderJdHistoryDao(handlers ...gdb.ModelHandler) *V1CardRedeemCookieOrderJdHistoryDao {
return &V1CardRedeemCookieOrderJdHistoryDao{
group: "default",
table: "card_redeem_cookie_order_jd_history",
columns: v1CardRedeemCookieOrderJdHistoryColumns,
handlers: handlers,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *V1CardRedeemCookieOrderJdHistoryDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *V1CardRedeemCookieOrderJdHistoryDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *V1CardRedeemCookieOrderJdHistoryDao) Columns() V1CardRedeemCookieOrderJdHistoryColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *V1CardRedeemCookieOrderJdHistoryDao) Group() string {
return dao.group
}
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
func (dao *V1CardRedeemCookieOrderJdHistoryDao) Ctx(ctx context.Context) *gdb.Model {
model := dao.DB().Model(dao.table)
for _, handler := range dao.handlers {
model = handler(model)
}
return model.Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// It rolls back the transaction and returns the error if function f returns a non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note: Do not commit or roll back the transaction in function f,
// as it is automatically handled by this function.
func (dao *V1CardRedeemCookieOrderJdHistoryDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@@ -32,6 +32,7 @@ type V1JdCookieJdOrderColumns struct {
WxPayExpireAt string // 微信支付链接过期时间
OrderExpireAt string // 订单过期时间(默认24小时)
CurrentOrderId string // 当前关联的订单ID
PaidAt string //
CreatedAt string // 创建时间
UpdatedAt string // 更新时间
DeletedAt string //
@@ -50,6 +51,7 @@ var v1JdCookieJdOrderColumns = V1JdCookieJdOrderColumns{
WxPayExpireAt: "wx_pay_expire_at",
OrderExpireAt: "order_expire_at",
CurrentOrderId: "current_order_id",
PaidAt: "paid_at",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
DeletedAt: "deleted_at",

View File

@@ -1,22 +0,0 @@
// =================================================================================
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
// =================================================================================
package dao
import (
"kami/internal/dao/internal"
)
// v1CardRedeemCookieInfoDao is the data access object for the table card_redeem_cookie_info.
// You can define custom methods on it to extend its functionality as needed.
type v1CardRedeemCookieInfoDao struct {
*internal.V1CardRedeemCookieInfoDao
}
var (
// V1CardRedeemCookieInfo is a globally accessible object for table card_redeem_cookie_info operations.
V1CardRedeemCookieInfo = v1CardRedeemCookieInfoDao{internal.NewV1CardRedeemCookieInfoDao()}
)
// Add your custom methods and functionality below.

View File

@@ -1,22 +0,0 @@
// =================================================================================
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
// =================================================================================
package dao
import (
"kami/internal/dao/internal"
)
// v1CardRedeemCookieOrderDao is the data access object for the table card_redeem_cookie_order.
// You can define custom methods on it to extend its functionality as needed.
type v1CardRedeemCookieOrderDao struct {
*internal.V1CardRedeemCookieOrderDao
}
var (
// V1CardRedeemCookieOrder is a globally accessible object for table card_redeem_cookie_order operations.
V1CardRedeemCookieOrder = v1CardRedeemCookieOrderDao{internal.NewV1CardRedeemCookieOrderDao()}
)
// Add your custom methods and functionality below.

View File

@@ -1,22 +0,0 @@
// =================================================================================
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
// =================================================================================
package dao
import (
"kami/internal/dao/internal"
)
// v1CardRedeemCookieOrderHistoryDao is the data access object for the table card_redeem_cookie_order_history.
// You can define custom methods on it to extend its functionality as needed.
type v1CardRedeemCookieOrderHistoryDao struct {
*internal.V1CardRedeemCookieOrderHistoryDao
}
var (
// V1CardRedeemCookieOrderHistory is a globally accessible object for table card_redeem_cookie_order_history operations.
V1CardRedeemCookieOrderHistory = v1CardRedeemCookieOrderHistoryDao{internal.NewV1CardRedeemCookieOrderHistoryDao()}
)
// Add your custom methods and functionality below.

View File

@@ -1,22 +0,0 @@
// =================================================================================
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
// =================================================================================
package dao
import (
"kami/internal/dao/internal"
)
// v1CardRedeemCookieOrderJdDao is the data access object for the table card_redeem_cookie_order_jd.
// You can define custom methods on it to extend its functionality as needed.
type v1CardRedeemCookieOrderJdDao struct {
*internal.V1CardRedeemCookieOrderJdDao
}
var (
// V1CardRedeemCookieOrderJd is a globally accessible object for table card_redeem_cookie_order_jd operations.
V1CardRedeemCookieOrderJd = v1CardRedeemCookieOrderJdDao{internal.NewV1CardRedeemCookieOrderJdDao()}
)
// Add your custom methods and functionality below.

View File

@@ -1,22 +0,0 @@
// =================================================================================
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
// =================================================================================
package dao
import (
"kami/internal/dao/internal"
)
// v1CardRedeemCookieOrderJdHistoryDao is the data access object for the table card_redeem_cookie_order_jd_history.
// You can define custom methods on it to extend its functionality as needed.
type v1CardRedeemCookieOrderJdHistoryDao struct {
*internal.V1CardRedeemCookieOrderJdHistoryDao
}
var (
// V1CardRedeemCookieOrderJdHistory is a globally accessible object for table card_redeem_cookie_order_jd_history operations.
V1CardRedeemCookieOrderJdHistory = v1CardRedeemCookieOrderJdHistoryDao{internal.NewV1CardRedeemCookieOrderJdHistoryDao()}
)
// Add your custom methods and functionality below.

View File

@@ -1,152 +0,0 @@
package cardredeemcookie
import (
"context"
"fmt"
"kami/internal/consts"
"kami/internal/dao"
"kami/internal/model"
"kami/internal/model/do"
"kami/internal/model/entity"
"kami/utility/config"
"kami/utility/utils"
"github.com/duke-git/lancet/v2/strutil"
"github.com/gogf/gf/v2/database/gdb"
)
// Save 保存cookie
func (s *sCardRedeemCookie) Save(ctx context.Context, input *model.CardRedeemCookieCreatedInput, tx gdb.TX) (err error) {
m := dao.V1CardRedeemCookieInfo.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
_, err = m.Save(&do.V1CardRedeemCookieInfo{
Category: input.Category,
Name: strutil.Trim(input.Name),
Status: input.Status,
Cookie: strutil.Trim(input.Cookie),
})
return
}
// Update 更新cookie
func (s *sCardRedeemCookie) Update(ctx context.Context, input *model.CardRedeemCookieUpdatedInput, tx gdb.TX) (err error) {
m := dao.V1CardRedeemCookieInfo.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
_, err = m.Where(dao.V1CardRedeemCookieInfo.Columns().Id, input.Id).Update(&do.V1CardRedeemCookieInfo{
Name: strutil.Trim(input.Name),
Status: input.Status,
Cookie: strutil.Trim(input.Cookie),
})
return
}
// UpdateStatus 更新cookie状态
func (s *sCardRedeemCookie) UpdateStatus(ctx context.Context, input *model.CardRedeemCookieStatusInput, tx gdb.TX) (err error) {
m := dao.V1CardRedeemCookieInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
Where(dao.V1CardRedeemCookieInfo.Columns().Id, input.Id)
if tx != nil {
m = m.TX(tx)
}
if input.Status == consts.CardRedeemCookieStatusTmpDisable {
data := entity.V1CardRedeemCookieInfo{}
if err = m.Scan(&data); err != nil {
return err
}
if _, err = m.Increment(dao.V1CardRedeemCookieInfo.Columns().FailCount, 1); err != nil {
return
}
if data.FailCount >= consts.CardRedeemCookieMaxScheduledFailedCount {
input.Status = consts.CardRedeemCookieStatusDailyDisable
}
}
if input.Status == consts.CardRedeemCookieStatusNormal {
if _, err = m.Update(&do.V1CardRedeemCookieInfo{
FailCount: 0,
}); err != nil {
return
}
}
_, err = m.Update(&do.V1CardRedeemCookieInfo{
Status: input.Status,
})
return
}
// GetOne 获取一个cookie
func (s *sCardRedeemCookie) GetOne(ctx context.Context, input *model.CardRedeemCookieGetInput, tx gdb.TX) (res *entity.V1CardRedeemCookieInfo, err error) {
m := dao.V1CardRedeemCookieInfo.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
err = m.Where(dao.V1CardRedeemCookieInfo.Columns().Id, input.Id).
Where(dao.V1CardRedeemCookieInfo.Columns().Category, input.Category).
Scan(&res)
return
}
// AccountList 获取ck列表
func (s *sCardRedeemCookie) AccountList(ctx context.Context, input *model.CardRedeemCookieGetListInput, tx gdb.TX) (res []*entity.V1CardRedeemCookieInfo, total int, err error) {
res = make([]*entity.V1CardRedeemCookieInfo, 0)
total = 0
m := dao.V1CardRedeemCookieInfo.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
if input.Cookie != "" {
m = m.WhereLike(dao.V1CardRedeemCookieInfo.Columns().Cookie, utils.OrmLike(input.Cookie))
}
if input.Status != "" {
m = m.Where(dao.V1CardRedeemCookieInfo.Columns().Status, input.Status)
}
if input.Name != "" {
m = m.WhereLike(dao.V1CardRedeemCookieInfo.Columns().Name, utils.OrmLike(input.Name))
}
err = m.Where(dao.V1CardRedeemCookieInfo.Columns().Category, input.Category).
ScanAndCount(&res, &total, false)
return
}
// AccountStatistic 账户统计
func (s *sCardRedeemCookie) AccountStatistic(ctx context.Context, input *model.CardRedeemCookieStatisticInput, tx gdb.TX) (res []*model.CardRedeemCookieStatisticOutput, err error) {
m := dao.V1CardRedeemCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
err = m.FieldCount(dao.V1CardRedeemCookieOrder.Columns().CookieId, "total_count").
FieldSum(fmt.Sprintf("CASE WHEN `%s` = 'placeSuccess' THEN 1 ELSE 0 END", dao.V1CardRedeemCookieOrder.Columns().Status), "success_count").
FieldSum(fmt.Sprintf("CASE WHEN `%s` = 'placeSuccess' THEN %s ELSE 0 END", dao.V1CardRedeemCookieOrder.Columns().Status, dao.V1CardRedeemCookieOrder.Columns().OrderAmount), "success_amount").
FieldSum(dao.V1CardRedeemCookieOrder.Columns().OrderAmount, "total_amount").
Fields(dao.V1CardRedeemCookieOrder.Columns().CookieId).
Group(dao.V1CardRedeemCookieOrder.Columns().CookieId).
WhereIn(dao.V1CardRedeemCookieOrder.Columns().CookieId, input.AccountIds).
Scan(&res)
return
}
// Delete 删除一个cookie
func (s *sCardRedeemCookie) Delete(ctx context.Context, input *model.CardRedeemCookieDeleteInput, tx gdb.TX) (err error) {
m := dao.V1CardRedeemCookieInfo.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
_, err = m.Where(dao.V1CardRedeemCookieInfo.Columns().Id, input.Id).Delete()
return
}
// GetOrderEndCookie 获取已下单的ck
func (s *sCardRedeemCookie) GetOrderEndCookie(ctx context.Context, tx gdb.TX) (res *entity.V1CardRedeemCookieInfo, err error) {
m := dao.V1CardRedeemCookieInfo.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
//按照更新更新升序排列
err = m.Where(dao.V1CardRedeemCookieInfo.Columns().Status, consts.CardRedeemCookieStatusNormal).
OrderAsc(dao.V1CardRedeemCookieInfo.Columns().UpdatedAt).
Scan(&res)
return
}

View File

@@ -1,55 +0,0 @@
package cardredeemcookie
import (
"context"
"kami/internal/consts"
"kami/internal/dao"
"kami/internal/model/do"
"kami/internal/model/entity"
"kami/utility/config"
"time"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/os/gtime"
"github.com/duke-git/lancet/v2/pointer"
"github.com/gogf/gf/v2/database/gdb"
)
// ScheduleAccount 调度账号
func (s *sCardRedeemCookie) ScheduleAccount(ctx context.Context, tx gdb.TX) (output *entity.V1CardRedeemCookieInfo, err error) {
// 尝试解封账号
s.unlockAccount(ctx, tx)
cookie, err := s.GetOrderEndCookie(ctx, tx)
if err != nil {
return nil, gerror.Wrap(err, "获取随机账号失败")
}
if pointer.IsNil(cookie) || cookie.Id <= 0 {
return nil, gerror.New("没有可用的账号")
}
return cookie, nil
}
// unlockAccount 解封临时封禁的账号
func (s *sCardRedeemCookie) unlockAccount(ctx context.Context, tx gdb.TX) {
m := dao.V1CardRedeemCookieInfo.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
if _, err := m.Where(dao.V1CardRedeemCookieInfo.Columns().Status, consts.CardRedeemCookieStatusDailyDisable).
WhereLT(dao.V1CardRedeemCookieInfo.Columns().UpdatedAt, gtime.Now().StartOfDay()).Update(do.V1CardRedeemCookieInfo{
Status: consts.CardRedeemCookieStatusNormal,
}); err != nil {
glog.Error(ctx, "解封今日封禁的账号失败", err)
}
if _, err := m.Where(dao.V1CardRedeemCookieInfo.Columns().Status, consts.CardRedeemCookieStatusTmpDisable).
WhereLT(dao.V1CardRedeemCookieInfo.Columns().UpdatedAt, gtime.Now().Add(-time.Minute*10)).Update(do.V1CardRedeemCookieInfo{
Status: consts.CardRedeemCookieStatusNormal,
}); err != nil {
glog.Error(ctx, "解封临时封禁的账号失败", err)
}
return
}

View File

@@ -1,22 +0,0 @@
package cardredeemcookie
import (
"context"
"kami/internal/model"
"testing"
_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
)
func Test_sCardReddemCookie_AccountStatistic(t *testing.T) {
s := &sCardRedeemCookie{}
ctx := context.Background()
input := &model.CardRedeemCookieStatisticInput{
AccountIds: []uint{1, 2, 3},
}
res, err := s.AccountStatistic(ctx, input, nil)
if err != nil {
t.Errorf("AccountStatistic() error = %v", err)
}
t.Logf("AccountStatistic() = %v", res)
}

View File

@@ -1,16 +0,0 @@
package cardredeemcookie
import (
"kami/internal/service"
)
func init() {
service.RegisterCardRedeemCookie(New())
}
func New() *sCardRedeemCookie {
return &sCardRedeemCookie{}
}
type sCardRedeemCookie struct {
}

View File

@@ -1,209 +0,0 @@
package cardredeemcookie
import (
"context"
v1 "kami/api/card_redeem_jd/v1"
"kami/internal/consts"
"kami/internal/dao"
"kami/internal/model"
"kami/internal/model/do"
"kami/internal/model/entity"
"kami/utility/config"
"kami/utility/integration/originalJd"
"kami/utility/utils"
"github.com/duke-git/lancet/v2/pointer"
"github.com/duke-git/lancet/v2/slice"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/os/gmlock"
)
// PlaceOrder 下单
func (s *sCardRedeemCookie) PlaceOrder(ctx context.Context, input *model.CardRedeemCookiePlaceOrderInput, tx gdb.TX) (output *model.CardRedeemCookePlaceOrderOutput, err error) {
gmlock.Lock("card_redeem_cookie_order_place_order_" + input.OrderId)
defer gmlock.Unlock("card_redeem_cookie_order_place_order_" + input.OrderId)
output = &model.CardRedeemCookePlaceOrderOutput{}
orderInfo, _ := s.GetOrderByBankOrderId(ctx, input.OrderId, tx)
if pointer.IsNil(orderInfo) || orderInfo.Id <= 0 {
orderInfo, _ = s.placeNewOrder(ctx, input, input.Category, nil)
}
if consts.CardRedeemCookieOrderStatus(orderInfo.Status) == consts.CardRedeemCookieOrderStatusPlaceSuccess {
output.V1CardRedeemCookieOrder = *orderInfo
jdOrder, _ := s.GetLatestJdOrder(ctx, orderInfo.Id, tx)
output.JdOrder = *jdOrder
return
}
orderInfo, _ = s.placeExistOrder(ctx, input.UserAgent, orderInfo, input.Category, tx)
output.V1CardRedeemCookieOrder = *orderInfo
return
}
// 处理已有订单
func (s *sCardRedeemCookie) placeExistOrder(ctx context.Context, userAgent string, input *entity.V1CardRedeemCookieOrder, category consts.RedeemOrderCardCategory, tx gdb.TX) (output *entity.V1CardRedeemCookieOrder, err error) {
cookieInfo, jdOrder, err := s.placeJdOrder(ctx, input.OrderNo, userAgent, input.OrderAmount, category, tx)
if pointer.IsNil(cookieInfo) {
cookieInfo = &entity.V1CardRedeemCookieInfo{}
}
if pointer.IsNil(jdOrder) {
jdOrder = &originalJd.AppleRechargeResp{}
}
note := ""
status := consts.CardRedeemCookieOrderStatusPlaceSuccess
if err != nil {
note = err.Error()
status = consts.CardRedeemCookieOrderStatusPlaceFail
}
m := dao.V1CardRedeemCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
_, err = m.Where(dao.V1CardRedeemCookieOrder.Columns().Id, input.Id).Update(do.V1CardRedeemCookieOrder{
CookieId: cookieInfo.Id,
JdOrderNo: jdOrder.OrderId,
Status: status,
Note: note,
})
if err != nil {
return nil, err
}
err = m.Where(dao.V1CardRedeemCookieOrder.Columns().OrderNo, input.OrderNo).Scan(&output)
return
}
// 处理新订单
func (s *sCardRedeemCookie) placeNewOrder(ctx context.Context, input *model.CardRedeemCookiePlaceOrderInput, category consts.RedeemOrderCardCategory, tx gdb.TX) (output *entity.V1CardRedeemCookieOrder, err error) {
orderNo := utils.GenerateRandomUUID()
m := dao.V1CardRedeemCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
err = m.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
status := consts.CardRedeemCookieOrderStatusInit
_, err = m.Ctx(ctx).TX(tx).Insert(do.V1CardRedeemCookieOrder{
OrderNo: orderNo,
Status: status,
BankOrderId: input.OrderId,
OrderAmount: input.OrderAmount,
})
if err != nil {
glog.Error(ctx, "下单失败", err)
return err
}
return err
})
if err != nil {
return nil, err
}
orderInfo := do.V1CardRedeemCookieOrder{}
accountInfo, jdOrder, err := s.placeJdOrder(ctx, orderNo, input.UserAgent, input.OrderAmount, category, tx)
if err != nil {
orderInfo.Note = err.Error()
glog.Error(ctx, "下单失败", err)
orderInfo.Status = consts.CardRedeemCookieOrderStatusPlaceFail
} else if pointer.IsNil(jdOrder) || pointer.IsNil(accountInfo) {
glog.Error(ctx, "下单失败", jdOrder)
orderInfo.Status = consts.CardRedeemCookieOrderStatusPlaceFail
} else {
orderInfo.Status = consts.CardRedeemCookieOrderStatusPlaceSuccess
}
if pointer.IsNil(accountInfo) {
accountInfo = &entity.V1CardRedeemCookieInfo{}
}
if pointer.IsNil(jdOrder) {
jdOrder = &originalJd.AppleRechargeResp{}
}
orderInfo.JdOrderNo = jdOrder.OrderId
orderInfo.CookieId = accountInfo.Id
_, err = m.Where(
dao.V1CardRedeemCookieOrder.Columns().OrderNo, orderNo,
).Update(orderInfo)
if err != nil {
return nil, err
}
err = m.Where(dao.V1CardRedeemCookieOrder.Columns().OrderNo, orderNo).Scan(&output)
return
}
// OrderList 查询订单
func (s *sCardRedeemCookie) OrderList(ctx context.Context, input *model.CardRedeemCookieOrderListInput, tx gdb.TX) (output *model.CardRedeemCookieOrderListOutput, err error) {
m := dao.V1CardRedeemCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
if input.CookieId > 0 {
m = m.Where(dao.V1CardRedeemCookieOrder.Columns().CookieId, input.CookieId)
}
if input.Status != "" {
m = m.Where(dao.V1CardRedeemCookieOrder.Columns().Status, input.Status)
}
if input.Cookie != "" {
accountInfos := make([]*entity.V1CardRedeemCookieInfo, 0)
_ = dao.V1CardRedeemCookieInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
WhereLike(dao.V1CardRedeemCookieInfo.Columns().Cookie, utils.OrmLike(input.Cookie)).
Scan(&accountInfos)
m = m.WhereIn(dao.V1CardRedeemCookieOrder.Columns().CookieId, slice.Map(accountInfos, func(index int, item *entity.V1CardRedeemCookieInfo) int {
return item.Id
}))
}
data := make([]*entity.V1CardRedeemCookieOrder, 0)
total := 0
err = m.Page(input.Current, input.PageSize).OrderDesc(dao.V1CardRedeemCookieOrder.Columns().CreatedAt).
ScanAndCount(&data, &total, false)
if err != nil {
return
}
cookieIds := slice.Map(data, func(index int, item *entity.V1CardRedeemCookieOrder) int {
return item.CookieId
})
cookieData := make([]*entity.V1CardRedeemCookieInfo, 0)
m = dao.V1CardRedeemCookieInfo.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
err = m.WhereIn(dao.V1CardRedeemCookieInfo.Columns().Id, cookieIds).Scan(&cookieData)
if err != nil {
return
}
output = &model.CardRedeemCookieOrderListOutput{
List: make([]*v1.OrderListSchema, 0),
Total: total,
}
for _, item := range data {
cookie, _ := slice.FindBy(cookieData, func(index int, item2 *entity.V1CardRedeemCookieInfo) bool {
return item2.Id == item.CookieId
})
jdOrder, _ := s.GetLatestJdOrder(ctx, item.Id, tx)
output.List = append(output.List, &v1.OrderListSchema{
V1CardRedeemCookieOrder: item,
JdOrder: jdOrder,
Cookie: cookie,
})
}
return
}
// GetOrderByBankOrderId 根据bankOrderId查询订单
func (s *sCardRedeemCookie) GetOrderByBankOrderId(ctx context.Context, bankOrderId string, tx gdb.TX) (output *entity.V1CardRedeemCookieOrder, err error) {
m := dao.V1CardRedeemCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
err = m.Where(dao.V1CardRedeemCookieOrder.Columns().BankOrderId, bankOrderId).
OrderDesc(dao.V1CardRedeemCookieOrder.Columns().CreatedAt).Scan(&output)
return
}

View File

@@ -1,200 +0,0 @@
package cardredeemcookie
import (
"context"
v1 "kami/api/card_info_apple/v1"
"kami/internal/consts"
"kami/internal/dao"
"kami/internal/model"
"kami/internal/model/do"
"kami/internal/model/entity"
"kami/internal/service"
"kami/utility/config"
"kami/utility/integration/originalJd"
"kami/utility/utils"
"time"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/os/gtime"
"github.com/duke-git/lancet/v2/pointer"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/util/gconv"
)
// 京东订单相关
func (s *sCardRedeemCookie) placeJdOrder(ctx context.Context, orderNo string, userAgent string, orderAmount float64, category consts.RedeemOrderCardCategory, tx gdb.TX) (accountInfo *entity.V1CardRedeemCookieInfo, output *originalJd.AppleRechargeResp, err error) {
accountInfo, err = s.ScheduleAccount(ctx, tx)
if err != nil {
return accountInfo, output, err
}
orderDao := dao.V1CardRedeemCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
orderDao = orderDao.TX(tx)
}
cookieOrder := entity.V1CardRedeemCookieOrder{}
if err = orderDao.Where(dao.V1CardRedeemCookieOrder.Columns().OrderNo, orderNo).Scan(&cookieOrder); err != nil {
return accountInfo, output, err
}
if cookieOrder.Id <= 0 {
return accountInfo, output, gerror.New("订单不存在")
}
m := dao.V1CardRedeemCookieOrderJd.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
jdCookieInfo := do.V1CardRedeemCookieOrderJd{
CookieOrderId: cookieOrder.Id,
CookieAccountId: accountInfo.Id,
UserAgent: userAgent,
UserClient: utils.GetClientTypeFromUserAgent(userAgent),
}
defer func() {
_, _ = m.Insert(jdCookieInfo)
}()
glog.Info(ctx, "开始下单", accountInfo, orderNo, orderAmount, category)
// 下单
jdOrder, err := originalJd.NewClient().AppleRecharge(ctx, &originalJd.AppleRechargeReq{
FacePrice: orderAmount,
OrderNum: orderNo,
Category: category,
UserClient: utils.GetClientTypeFromUserAgent(userAgent),
Cookies: accountInfo.Cookie,
})
glog.Info(ctx, jdOrder)
if pointer.IsNil(jdOrder) || jdOrder == nil {
jdOrder = &originalJd.AppleRechargeResp{
Code: consts.CardCookieJDStatusNormalFailed,
Msg: "京东返回订单信息为空",
}
return
}
jdCookieInfo.ResponseData = gconv.String(jdOrder)
jdCookieInfo.Status = jdOrder.Code
switch jdOrder.Code {
case consts.CardCookieJDStatusNormalFailed:
_ = s.UpdateStatus(ctx, &model.CardRedeemCookieStatusInput{
Id: uint(accountInfo.Id),
Status: consts.CardRedeemCookieStatusTmpDisable,
}, nil)
return accountInfo, jdOrder, gerror.New(jdOrder.Msg)
case consts.CardCookieJDStatusWrongFacePrice, consts.CardCookieJDStatusExpired:
_ = s.UpdateStatus(ctx, &model.CardRedeemCookieStatusInput{
Id: uint(accountInfo.Id),
Status: consts.CardRedeemCookieStatusTmpDisable,
}, nil)
return accountInfo, jdOrder, gerror.New(jdOrder.Msg)
case consts.CardCookieJDStatusCkFailed:
_ = s.UpdateStatus(ctx, &model.CardRedeemCookieStatusInput{
Id: uint(accountInfo.Id),
Status: consts.CardRedeemCookieStatusExpired,
}, nil)
return accountInfo, jdOrder, gerror.New(jdOrder.Msg)
case consts.CardCookieJDStatusSuccess:
jdCookieInfo.PayId = jdOrder.PayId
jdCookieInfo.OrderNo = jdOrder.OrderId
jdCookieInfo.WebPayLink = jdOrder.Deeplink
default:
_ = s.UpdateStatus(ctx, &model.CardRedeemCookieStatusInput{
Id: uint(accountInfo.Id),
Status: consts.CardRedeemCookieStatusTmpDisable,
}, nil)
return accountInfo, jdOrder, gerror.New(jdOrder.Msg)
}
return accountInfo, jdOrder, nil
}
// GetLatestJdOrder 获取最新的京东订单
func (s *sCardRedeemCookie) GetLatestJdOrder(ctx context.Context, orderId int, tx gdb.TX) (output *entity.V1CardRedeemCookieOrderJd, err error) {
m := dao.V1CardRedeemCookieOrderJd.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
err = m.Where(dao.V1CardRedeemCookieOrderJd.Columns().CookieOrderId, orderId).
Scan(&output)
return
}
// CheckPaySuccess 检测用户是否支付成功
func (s *sCardRedeemCookie) CheckPaySuccess(ctx context.Context, tx gdb.TX) {
m := dao.V1CardRedeemCookieOrderJd.Ctx(ctx).DB(config.GetDatabaseV1())
if tx != nil {
m = m.TX(tx)
}
jdOrderInfos := make([]*entity.V1CardRedeemCookieOrderJd, 0)
err := m.WhereGTE(dao.V1CardRedeemCookieOrderJd.Columns().CreatedAt, gtime.Now().Add(-time.Minute*10)).
WhereLTE(dao.V1CardRedeemCookieOrderJd.Columns().CreatedAt, gtime.Now().Add(-time.Second*30)).
Where(dao.V1CardRedeemCookieOrderJd.Columns().Status, consts.CardCookieJDStatusSuccess).
WhereNull(dao.V1CardRedeemCookieOrderJd.Columns().CardNo).
Scan(&jdOrderInfos)
if err != nil {
glog.Error(ctx, "检测用户是否支付成功失败", err)
return
}
orderInfoM := dao.V1CardRedeemCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1()).Unscoped()
if tx != nil {
orderInfoM = orderInfoM.TX(tx)
}
cookieInfoM := dao.V1CardRedeemCookieInfo.Ctx(ctx).DB(config.GetDatabaseV1()).Unscoped()
if tx != nil {
cookieInfoM = cookieInfoM.TX(tx)
}
for _, info := range jdOrderInfos {
if info.CardNo != "" {
continue
}
glog.Info(ctx, "开始检测用户是否支付成功", "info", info)
//查询关联订单
orderInfo := entity.V1CardRedeemCookieOrder{}
if err = orderInfoM.Where(dao.V1CardRedeemCookieOrder.Columns().Id, info.CookieOrderId).
Scan(&orderInfo); err != nil {
glog.Error(ctx, "查询关联ck失败", "err", err)
return
}
//查询ck
cookieInfo := entity.V1CardRedeemCookieInfo{}
if err = cookieInfoM.Where(dao.V1CardRedeemCookieInfo.Columns().Id, orderInfo.CookieId).
Scan(&cookieInfo); err != nil {
glog.Error(ctx, "查询关联ck失败", "err", err)
return
}
if cardInfo, err2 := originalJd.NewClient().GetCardInfo(ctx, &originalJd.AppleRechargeCardInfoReq{
OrderNo: orderInfo.BankOrderId,
JdOrderNo: info.OrderNo,
Cookies: cookieInfo.Cookie,
}); err2 == nil {
_, _ = m.Where(dao.V1CardRedeemCookieOrderJd.Columns().Id, info.Id).Update(do.V1CardRedeemCookieOrderJd{
CardNo: cardInfo.CardNo,
CardPassword: cardInfo.CardPassword,
})
if _, err3 := service.AppleOrder().AddRechargeOrder(ctx, &model.AppleCardRechargeInput{
Amount: orderInfo.OrderAmount,
Balance: orderInfo.OrderAmount,
RechargeSubmitReq: &v1.RechargeSubmitReq{
CardNo: cardInfo.CardNo,
CardPass: cardInfo.CardPassword,
FaceValue: int64(orderInfo.OrderAmount),
CallbackUrl: "http://kami_shop:12305/shop/notify",
Attach: orderInfo.BankOrderId,
TimeStamp: int(gtime.Timestamp()),
MerchantId: orderInfo.OrderNo,
},
}); err3 != nil {
glog.Error(ctx, "添加充值订单失败", "err", err3)
}
} else {
glog.Error(ctx, "获取京东卡信息失败", "err", err2)
}
}
}

View File

@@ -1,11 +0,0 @@
package cardredeemcookie
import (
"context"
"testing"
)
func Test_sCardRedeemCookie_CheckPaySuccess(t *testing.T) {
orderInfo := sCardRedeemCookie{}
orderInfo.CheckPaySuccess(context.Background(), nil)
}

View File

@@ -9,18 +9,19 @@ import (
"kami/internal/model/do"
"kami/internal/model/entity"
"kami/utility/config"
"kami/utility/utils"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/guid"
)
// CreateAccount 创建Cookie账户
func (s *sJdCookie) CreateAccount(ctx context.Context, cookieValue, accountName, remark string) (cookieId string, status int, err error) {
// 生成唯一的Cookie ID
cookieId = fmt.Sprintf("jd_%s_%d", gstr.SubStr(guid.S(), 0, 8), gtime.Timestamp())
cookieId = fmt.Sprintf("jd_%s_%d", gstr.SubStr(utils.GenerateRandomUUID(), 0, 8), gtime.Timestamp())
// 清理输入数据
cookieValue = gstr.Trim(cookieValue)
@@ -86,8 +87,8 @@ func (s *sJdCookie) ListAccount(ctx context.Context, page, size, status int, key
}
if keyword != "" {
keyword = "%" + keyword + "%"
m = m.WhereOr(dao.V1JdCookieAccount.Columns().CookieId+" LIKE ?", keyword).
WhereOr(dao.V1JdCookieAccount.Columns().AccountName+" LIKE ?", keyword)
m = m.WhereOrLike(dao.V1JdCookieAccount.Columns().CookieId, keyword).
WhereOrLike(dao.V1JdCookieAccount.Columns().AccountName, keyword)
}
// 查询总数
@@ -175,16 +176,35 @@ func (s *sJdCookie) UpdateAccount(ctx context.Context, cookieId, cookieValue, ac
return gerror.Wrap(err, "更新Cookie账户失败")
}
// 记录状态变更历史
// 记录变更历史
var changeType consts.CookieChangeType
var statusAfter int
shouldRecordHistory := false
if status > 0 && status != statusBefore {
changeType := consts.CookieChangeTypeResume
// 状态变更
shouldRecordHistory = true
if status == int(consts.JdCookieStatusSuspend) {
changeType = consts.CookieChangeTypeSuspend
} else if status == int(consts.JdCookieStatusNormal) {
changeType = consts.CookieChangeTypeResume
} else if status == int(consts.JdCookieStatusExpired) {
changeType = consts.CookieChangeTypeFail
}
statusAfter = status
} else if (cookieValue != "" && cookieValue != currentAccount.CookieValue) ||
(accountName != "" && accountName != currentAccount.AccountName) ||
(remark != "" && remark != currentAccount.Remark) {
// 非状态变更(内容更新)
shouldRecordHistory = true
changeType = consts.CookieChangeTypeUpdate
statusAfter = currentAccount.Status
}
err = s.RecordCookieHistory(ctx, cookieId, string(changeType), statusBefore, status, "", currentAccount.FailureCount)
if shouldRecordHistory {
err = s.RecordCookieHistory(ctx, cookieId, string(changeType), statusBefore, statusAfter, "", currentAccount.FailureCount)
if err != nil {
glog.Error(ctx, "记录Cookie状态变更历史失败", err)
glog.Error(ctx, "记录Cookie变更历史失败", err)
}
}
@@ -197,7 +217,18 @@ func (s *sJdCookie) DeleteAccount(ctx context.Context, cookieId string) (err err
return gerror.New("Cookie ID不能为空")
}
// 获取当前账户信息用于记录历史
m := dao.V1JdCookieAccount.Ctx(ctx).DB(config.GetDatabaseV1())
var currentAccount *entity.V1JdCookieAccount
err = m.Where(dao.V1JdCookieAccount.Columns().CookieId, cookieId).Scan(&currentAccount)
if err != nil {
return gerror.Wrap(err, "查询当前账户信息失败")
}
if currentAccount == nil {
return gerror.New(consts.ErrCodeCookieNotFound)
}
// 执行删除操作
result, err := m.Where(dao.V1JdCookieAccount.Columns().CookieId, cookieId).Delete()
if err != nil {
return gerror.Wrap(err, "删除Cookie账户失败")
@@ -208,6 +239,72 @@ func (s *sJdCookie) DeleteAccount(ctx context.Context, cookieId string) (err err
return gerror.New(consts.ErrCodeCookieNotFound)
}
// 记录删除历史
_ = s.RecordCookieHistory(ctx, cookieId, string(consts.CookieChangeTypeDelete),
currentAccount.Status, 0, "", currentAccount.FailureCount)
return
}
// BatchDeleteAccount 批量删除Cookie账户
func (s *sJdCookie) BatchDeleteAccount(ctx context.Context, cookieIds []string) (successIds []string, failedCount int, err error) {
if len(cookieIds) == 0 {
return []string{}, 0, nil
}
successIds = make([]string, 0)
failedCount = 0
for _, cookieId := range cookieIds {
deleteErr := s.DeleteAccount(ctx, cookieId)
if deleteErr != nil {
failedCount++
glog.Warning(ctx, "批量删除Cookie失败", g.Map{
"cookieId": cookieId,
"error": deleteErr,
})
continue
}
successIds = append(successIds, cookieId)
}
return
}
// GetAccount 获取单个Cookie账户
func (s *sJdCookie) GetAccount(ctx context.Context, cookieId string) (account *v1.CookieAccountInfo, err error) {
if cookieId == "" {
return nil, gerror.New("Cookie ID不能为空")
}
m := dao.V1JdCookieAccount.Ctx(ctx).DB(config.GetDatabaseV1())
var accountEntity *entity.V1JdCookieAccount
err = m.Where(dao.V1JdCookieAccount.Columns().CookieId, cookieId).Scan(&accountEntity)
if err != nil {
return nil, gerror.Wrap(err, "查询Cookie账户失败")
}
if accountEntity == nil {
return nil, gerror.New(consts.ErrCodeCookieNotFound)
}
account = &v1.CookieAccountInfo{
CookieId: accountEntity.CookieId,
AccountName: accountEntity.AccountName,
Status: accountEntity.Status,
FailureCount: accountEntity.FailureCount,
Remark: accountEntity.Remark,
}
if accountEntity.LastUsedAt != nil {
account.LastUsedAt = accountEntity.LastUsedAt.Format("2006-01-02 15:04:05")
}
if accountEntity.SuspendUntil != nil {
account.SuspendUntil = accountEntity.SuspendUntil.Format("2006-01-02 15:04:05")
}
if accountEntity.CreatedAt != nil {
account.CreatedAt = accountEntity.CreatedAt.Format("2006-01-02 15:04:05")
}
return
}

View File

@@ -158,4 +158,49 @@ func (s *sJdCookie) getJdOrderHistory(ctx context.Context, jdOrderId string, pag
}
return
}
}
// GetJdOrderHistoryByOrderId 根据订单ID获取所有关联的京东订单历史
func (s *sJdCookie) GetJdOrderHistoryByOrderId(ctx context.Context, orderId string, page, size int) (list []*v1.JdOrderHistoryInfo, total int, err error) {
if orderId == "" {
return nil, 0, gerror.New("订单号不能为空")
}
if page <= 0 {
page = 1
}
if size <= 0 {
size = 20
}
m := dao.V1JdCookieJdOrderChangeHistory.Ctx(ctx).DB(config.GetDatabaseV1())
m = m.Where(dao.V1JdCookieJdOrderChangeHistory.Columns().OrderId, orderId)
// 查询总数
total, err = m.Count()
if err != nil {
return nil, 0, gerror.Wrap(err, "查询总数失败")
}
// 查询列表数据
var histories []*entity.V1JdCookieJdOrderChangeHistory
err = m.Page(page, size).OrderDesc(dao.V1JdCookieJdOrderChangeHistory.Columns().CreatedAt).Scan(&histories)
if err != nil {
return nil, 0, gerror.Wrap(err, "查询京东订单历史失败")
}
// 转换为响应格式
list = make([]*v1.JdOrderHistoryInfo, 0, len(histories))
for _, history := range histories {
info := &v1.JdOrderHistoryInfo{
HistoryUuid: history.HistoryUuid,
JdOrderId: history.JdOrderId,
ChangeType: history.ChangeType,
OrderId: history.OrderId,
WxPayUrl: history.WxPayUrl,
CreatedAt: history.CreatedAt.Format("2006-01-02 15:04:05"),
}
list = append(list, info)
}
return
}

View File

@@ -21,6 +21,8 @@ import (
// CreateOrder 创建订单
func (s *sJdCookie) CreateOrder(ctx context.Context, orderId string, amount float64, category string) (wxPayUrl, expireTime, jdOrderId string, err error) {
_ = s.ReleaseExpiredJdOrders(ctx)
if orderId == "" {
return "", "", "", gerror.New("订单号不能为空")
}
@@ -162,6 +164,76 @@ func (s *sJdCookie) GetPaymentUrl(ctx context.Context, orderId string) (wxPayUrl
return
}
// GetOrder 获取单个订单
func (s *sJdCookie) GetOrder(ctx context.Context, orderId string) (order *v1.OrderInfo, err error) {
if orderId == "" {
return nil, gerror.New("订单号不能为空")
}
orderEntity, err := s.getOrderByOrderId(ctx, orderId)
if err != nil {
return nil, gerror.Wrap(err, "查询订单失败")
}
if orderEntity == nil {
return nil, gerror.New(consts.ErrCodeOrderNotFound)
}
order = &v1.OrderInfo{
OrderId: orderEntity.OrderId,
Amount: gconv.Float64(orderEntity.Amount),
Category: orderEntity.Category,
JdOrderId: orderEntity.JdOrderId,
Status: orderEntity.Status,
WxPayUrl: orderEntity.WxPayUrl,
LastRequest: orderEntity.LastRequestAt.Format("2006-01-02 15:04:05"),
CreatedAt: orderEntity.CreatedAt.Format("2006-01-02 15:04:05"),
}
return
}
// GetJdOrder 获取单个京东订单
func (s *sJdCookie) GetJdOrder(ctx context.Context, jdOrderId string) (order *v1.JdOrderInfo, err error) {
if jdOrderId == "" {
return nil, gerror.New("京东订单号不能为空")
}
jdOrderEntity, err := s.getJdOrderByJdOrderId(ctx, jdOrderId)
if err != nil {
return nil, gerror.Wrap(err, "查询京东订单失败")
}
if jdOrderEntity == nil {
return nil, gerror.New(consts.ErrCodeJdOrderNotFound)
}
order = &v1.JdOrderInfo{
JdOrderId: jdOrderEntity.JdOrderId,
Amount: gconv.Float64(jdOrderEntity.Amount),
Category: jdOrderEntity.Category,
Status: jdOrderEntity.Status,
CreatedAt: jdOrderEntity.CreatedAt.Format("2006-01-02 15:04:05"),
UpdatedAt: jdOrderEntity.UpdatedAt.Format("2006-01-02 15:04:05"),
}
// 获取关联的用户订单信息
if jdOrderEntity.CurrentOrderId > 0 {
var userOrder *entity.V1JdCookieOrder
_ = dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
Where(dao.V1JdCookieOrder.Columns().Id, jdOrderEntity.CurrentOrderId).
Scan(&userOrder)
if userOrder != nil {
order.OrderId = userOrder.OrderId
}
}
// 如果订单已支付,设置支付时间
if jdOrderEntity.Status == int(consts.JdOrderStatusPaid) && jdOrderEntity.PaidAt != nil {
order.PaidAt = jdOrderEntity.PaidAt.Format("2006-01-02 15:04:05")
}
return
}
// GetOrderStatus 查询订单状态
func (s *sJdCookie) GetOrderStatus(ctx context.Context, orderId string) (order *v1.OrderInfo, err error) {
if orderId == "" {
@@ -244,6 +316,88 @@ func (s *sJdCookie) ListOrder(ctx context.Context, page, size, status int, start
return
}
// ListJdOrder 京东订单列表查询
func (s *sJdCookie) ListJdOrder(ctx context.Context, page, size, status int, startTime, endTime, orderId string) (list []*v1.JdOrderInfo, total int, err error) {
if page <= 0 {
page = 1
}
if size <= 0 {
size = 20
}
m := dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1())
// 构建查询条件
if status > 0 {
m = m.Where(dao.V1JdCookieJdOrder.Columns().Status, status)
}
if startTime != "" {
m = m.WhereGTE(dao.V1JdCookieJdOrder.Columns().CreatedAt, startTime)
}
if endTime != "" {
m = m.WhereLTE(dao.V1JdCookieJdOrder.Columns().CreatedAt, endTime)
}
if orderId != "" {
// 先查询对应的内部订单ID然后筛选
var userOrder *entity.V1JdCookieOrder
err := dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
Where(dao.V1JdCookieOrder.Columns().OrderId, orderId).
Scan(&userOrder)
if err == nil && userOrder != nil {
m = m.Where(dao.V1JdCookieJdOrder.Columns().CurrentOrderId, userOrder.Id)
} else {
// 如果找不到对应的内部订单,返回空结果
return []*v1.JdOrderInfo{}, 0, nil
}
}
// 查询总数
total, err = m.Count()
if err != nil {
return nil, 0, gerror.Wrap(err, "查询京东订单总数失败")
}
// 查询列表数据
var jdOrders []*entity.V1JdCookieJdOrder
err = m.Page(page, size).OrderDesc(dao.V1JdCookieJdOrder.Columns().CreatedAt).Scan(&jdOrders)
if err != nil {
return nil, 0, gerror.Wrap(err, "查询京东订单列表失败")
}
// 转换为响应格式
list = make([]*v1.JdOrderInfo, 0, len(jdOrders))
for _, jdOrderEntity := range jdOrders {
info := &v1.JdOrderInfo{
JdOrderId: jdOrderEntity.JdOrderId,
Amount: gconv.Float64(jdOrderEntity.Amount),
Category: jdOrderEntity.Category,
Status: jdOrderEntity.Status,
CreatedAt: jdOrderEntity.CreatedAt.Format("2006-01-02 15:04:05"),
UpdatedAt: jdOrderEntity.UpdatedAt.Format("2006-01-02 15:04:05"),
}
// 获取关联的用户订单信息
if jdOrderEntity.CurrentOrderId > 0 {
var userOrder *entity.V1JdCookieOrder
_ = dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
Where(dao.V1JdCookieOrder.Columns().Id, jdOrderEntity.CurrentOrderId).
Scan(&userOrder)
if userOrder != nil {
info.OrderId = userOrder.OrderId
}
}
// 如果订单已支付,设置支付时间
if jdOrderEntity.Status == int(consts.JdOrderStatusPaid) && jdOrderEntity.PaidAt != nil {
info.PaidAt = jdOrderEntity.PaidAt.Format("2006-01-02 15:04:05")
}
list = append(list, info)
}
return
}
// ====================================================================================
// 内部辅助方法
// ====================================================================================
@@ -403,6 +557,7 @@ func (s *sJdCookie) CheckJdOrderPayment(ctx context.Context, jdOrderId string) (
if err != nil {
glog.Warning(ctx, "更新京东订单状态失败", err)
}
// 记录状态变更历史
var changeType string
if paymentResp.IsPaid {
@@ -412,7 +567,28 @@ func (s *sJdCookie) CheckJdOrderPayment(ctx context.Context, jdOrderId string) (
} else {
changeType = string(consts.JdOrderChangeTypeInvalid)
}
_ = s.RecordJdOrderHistory(ctx, jdOrderId, changeType, "", "")
// 获取关联的用户订单ID
orderId := ""
if jdOrder.CurrentOrderId > 0 {
var order *entity.V1JdCookieOrder
_ = dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
Where(dao.V1JdCookieOrder.Columns().Id, jdOrder.CurrentOrderId).
Scan(&order)
if order != nil {
orderId = order.OrderId
// 同时记录用户订单的状态变更历史
var orderChangeType string
if paymentResp.IsPaid {
orderChangeType = string(consts.OrderChangeTypePay)
} else if paymentResp.PaymentStatus == int(consts.JdOrderStatusExpired) {
orderChangeType = string(consts.OrderChangeTypeExpire)
}
_ = s.RecordOrderHistory(ctx, orderId, orderChangeType, jdOrderId)
}
}
_ = s.RecordJdOrderHistory(ctx, jdOrderId, changeType, orderId, jdOrder.WxPayUrl)
}
// 判断是否可以复用:未支付且在超时时间内
@@ -437,7 +613,7 @@ func (s *sJdCookie) CheckJdOrderPayment(ctx context.Context, jdOrderId string) (
// findReusableJdOrder 查找可复用的京东订单
func (s *sJdCookie) findReusableJdOrder(ctx context.Context, amount float64, category string) (jdOrder *entity.V1JdCookieJdOrder, err error) {
m := dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1())
// 查找符合条件的京东订单:
// 1. 金额和品类相同
// 2. 状态为待支付
@@ -451,24 +627,52 @@ func (s *sJdCookie) findReusableJdOrder(ctx context.Context, amount float64, cat
OrderAsc(dao.V1JdCookieJdOrder.Columns().CreatedAt).
Limit(1).
Scan(&jdOrder)
return
}
// updateJdOrderPaymentUrl 更新京东订单的支付链接
func (s *sJdCookie) updateJdOrderPaymentUrl(ctx context.Context, jdOrderId, wxPayUrl string) error {
m := dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1())
_, err := m.Where(dao.V1JdCookieJdOrder.Columns().JdOrderId, jdOrderId).Update(&do.V1JdCookieJdOrder{
// 获取更新前的订单信息
var oldOrder *entity.V1JdCookieJdOrder
err := m.Where(dao.V1JdCookieJdOrder.Columns().JdOrderId, jdOrderId).Scan(&oldOrder)
if err != nil || oldOrder == nil {
glog.Warning(ctx, "查询京东订单失败,无法记录历史", err)
// 即使查询失败也继续更新
}
_, err = m.Where(dao.V1JdCookieJdOrder.Columns().JdOrderId, jdOrderId).Update(&do.V1JdCookieJdOrder{
WxPayUrl: wxPayUrl,
WxPayExpireAt: gtime.Now().Add(time.Minute * consts.WxPayUrlExpireDuration),
})
if err != nil {
return err
}
// 记录支付链接更新历史
if oldOrder != nil && oldOrder.WxPayUrl != wxPayUrl {
orderId := ""
if oldOrder.CurrentOrderId > 0 {
var order *entity.V1JdCookieOrder
_ = dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
Where(dao.V1JdCookieOrder.Columns().Id, oldOrder.CurrentOrderId).
Scan(&order)
if order != nil {
orderId = order.OrderId
}
}
_ = s.RecordJdOrderHistory(ctx, jdOrderId, string(consts.JdOrderChangeTypeReplace), orderId, wxPayUrl)
}
return err
}
// updateJdOrderCurrentOrderId 更新京东订单的当前关联订单ID
func (s *sJdCookie) updateJdOrderCurrentOrderId(ctx context.Context, jdOrderId, orderId string) error {
m := dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1())
// 查找订单ID对应的内部ID
var order *entity.V1JdCookieOrder
err := dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
@@ -477,10 +681,43 @@ func (s *sJdCookie) updateJdOrderCurrentOrderId(ctx context.Context, jdOrderId,
if err != nil || order == nil {
return gerror.New("订单不存在")
}
// 获取更新前的京东订单信息
var oldJdOrder *entity.V1JdCookieJdOrder
err = m.Where(dao.V1JdCookieJdOrder.Columns().JdOrderId, jdOrderId).Scan(&oldJdOrder)
if err != nil || oldJdOrder == nil {
glog.Warning(ctx, "查询京东订单失败,无法记录历史", err)
// 即使查询失败也继续更新
}
_, err = m.Where(dao.V1JdCookieJdOrder.Columns().JdOrderId, jdOrderId).Update(&do.V1JdCookieJdOrder{
CurrentOrderId: order.Id,
})
if err != nil {
return err
}
// 记录订单绑定历史
var changeType string
if oldJdOrder != nil {
if oldJdOrder.CurrentOrderId == 0 {
changeType = string(consts.JdOrderChangeTypeBind) // 首次绑定
} else if oldJdOrder.CurrentOrderId != order.Id {
changeType = string(consts.JdOrderChangeTypeReplace) // 更换绑定
}
} else {
changeType = string(consts.JdOrderChangeTypeBind) // 首次绑定
}
if changeType != "" {
// 获取京东订单的支付链接
wxPayUrl := ""
if oldJdOrder != nil {
wxPayUrl = oldJdOrder.WxPayUrl
}
_ = s.RecordJdOrderHistory(ctx, jdOrderId, changeType, orderId, wxPayUrl)
}
return err
}
@@ -495,16 +732,16 @@ func (s *sJdCookie) getCookieById(ctx context.Context, cookieId string) (cookie
func (s *sJdCookie) callJdCheckPayment(ctx context.Context, jdOrderId, cookieValue string) (*originalJd.CheckOrderPaymentResp, error) {
// TODO: 这里需要实际调用京东接口
// 现在只是模拟实现
// 创建京东客户端
client := originalJd.NewClient()
// 调用检查支付状态接口
req := &originalJd.CheckOrderPaymentReq{
JdOrderId: jdOrderId,
Cookies: cookieValue,
}
resp, err := client.CheckOrderPayment(ctx, req)
if err != nil {
glog.Error(ctx, "调用京东检查支付状态接口失败", g.Map{
@@ -513,14 +750,14 @@ func (s *sJdCookie) callJdCheckPayment(ctx context.Context, jdOrderId, cookieVal
})
return nil, err
}
glog.Info(ctx, "京东检查支付状态成功", g.Map{
"jdOrderId": jdOrderId,
"paymentStatus": resp.PaymentStatus,
"isPaid": resp.IsPaid,
"canReuse": resp.CanReuse,
})
return resp, nil
}
@@ -532,7 +769,20 @@ func (s *sJdCookie) callJdCheckPayment(ctx context.Context, jdOrderId, cookieVal
func (s *sJdCookie) CleanupExpiredOrders(ctx context.Context) error {
// 清理过期的京东订单
jdOrderModel := dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1())
_, err := jdOrderModel.
// 先查询即将过期的京东订单,用于记录历史
var expiredJdOrders []*entity.V1JdCookieJdOrder
err := jdOrderModel.
Where(dao.V1JdCookieJdOrder.Columns().Status, int(consts.JdOrderStatusPending)).
WhereLT(dao.V1JdCookieJdOrder.Columns().OrderExpireAt, gtime.Now()).
Scan(&expiredJdOrders)
if err != nil {
glog.Error(ctx, "查询过期京东订单失败", err)
return err
}
// 批量更新过期状态
_, err = jdOrderModel.
Where(dao.V1JdCookieJdOrder.Columns().Status, int(consts.JdOrderStatusPending)).
WhereLT(dao.V1JdCookieJdOrder.Columns().OrderExpireAt, gtime.Now()).
Update(&do.V1JdCookieJdOrder{
@@ -543,8 +793,38 @@ func (s *sJdCookie) CleanupExpiredOrders(ctx context.Context) error {
return err
}
// 为每个过期的京东订单记录历史
for _, jdOrder := range expiredJdOrders {
orderId := ""
if jdOrder.CurrentOrderId > 0 {
var order *entity.V1JdCookieOrder
_ = dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
Where(dao.V1JdCookieOrder.Columns().Id, jdOrder.CurrentOrderId).
Scan(&order)
if order != nil {
orderId = order.OrderId
// 同时记录用户订单的历史
_ = s.RecordOrderHistory(ctx, orderId, string(consts.OrderChangeTypeExpire), jdOrder.JdOrderId)
}
}
_ = s.RecordJdOrderHistory(ctx, jdOrder.JdOrderId, string(consts.JdOrderChangeTypeExpire), orderId, jdOrder.WxPayUrl)
}
// 清理过期的用户订单
orderModel := dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1())
// 查询即将过期的用户订单
var expiredOrders []*entity.V1JdCookieOrder
err = orderModel.
Where(dao.V1JdCookieOrder.Columns().Status, int(consts.OrderStatusPending)).
WhereLT(dao.V1JdCookieOrder.Columns().CreatedAt, gtime.Now().Add(-time.Hour*24)).
Scan(&expiredOrders)
if err != nil {
glog.Error(ctx, "查询过期用户订单失败", err)
return err
}
// 批量更新过期状态
_, err = orderModel.
Where(dao.V1JdCookieOrder.Columns().Status, int(consts.OrderStatusPending)).
WhereLT(dao.V1JdCookieOrder.Columns().CreatedAt, gtime.Now().Add(-time.Hour*24)).
@@ -556,7 +836,15 @@ func (s *sJdCookie) CleanupExpiredOrders(ctx context.Context) error {
return err
}
glog.Info(ctx, "清理过期订单完成")
// 为每个过期的用户订单记录历史
for _, order := range expiredOrders {
_ = s.RecordOrderHistory(ctx, order.OrderId, string(consts.OrderChangeTypeExpire), order.JdOrderId)
}
glog.Info(ctx, "清理过期订单完成", g.Map{
"expiredJdOrderCount": len(expiredJdOrders),
"expiredOrderCount": len(expiredOrders),
})
return nil
}
@@ -564,7 +852,7 @@ func (s *sJdCookie) CleanupExpiredOrders(ctx context.Context) error {
func (s *sJdCookie) ReleaseExpiredJdOrders(ctx context.Context) error {
// 查找超过15分钟未支付的京东订单
expireTime := gtime.Now().Add(-time.Minute * consts.JdOrderReuseTimeout)
// 释放这些订单的关联
jdOrderModel := dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1())
_, err := jdOrderModel.

View File

@@ -59,8 +59,19 @@ func (s *sJdCookie) GetAvailableCookie(ctx context.Context) (cookieId string, er
func (s *sJdCookie) unlockExpiredCookies(ctx context.Context) {
m := dao.V1JdCookieAccount.Ctx(ctx).DB(config.GetDatabaseV1())
// 解锁暂停时间已过的Cookie
_, err := m.Where(dao.V1JdCookieAccount.Columns().Status, int(consts.JdCookieStatusSuspend)).
// 先查询即将解锁的Cookie用于记录历史
var expiredCookies []*entity.V1JdCookieAccount
err := m.Where(dao.V1JdCookieAccount.Columns().Status, int(consts.JdCookieStatusSuspend)).
WhereLTE(dao.V1JdCookieAccount.Columns().SuspendUntil, gtime.Now()).
WhereNotNull(dao.V1JdCookieAccount.Columns().SuspendUntil).
Scan(&expiredCookies)
if err != nil {
glog.Error(ctx, "查询过期暂停Cookie失败", err)
return
}
// 批量解锁暂停时间已过的Cookie
_, err = m.Where(dao.V1JdCookieAccount.Columns().Status, int(consts.JdCookieStatusSuspend)).
WhereLTE(dao.V1JdCookieAccount.Columns().SuspendUntil, gtime.Now()).
WhereNotNull(dao.V1JdCookieAccount.Columns().SuspendUntil).
Update(&do.V1JdCookieAccount{
@@ -69,6 +80,19 @@ func (s *sJdCookie) unlockExpiredCookies(ctx context.Context) {
})
if err != nil {
glog.Error(ctx, "解锁暂停Cookie失败", err)
return
}
// 为每个解锁的Cookie记录历史
for _, cookie := range expiredCookies {
_ = s.RecordCookieHistory(ctx, cookie.CookieId, string(consts.CookieChangeTypeResume),
int(consts.JdCookieStatusSuspend), int(consts.JdCookieStatusNormal), "", cookie.FailureCount)
}
if len(expiredCookies) > 0 {
glog.Info(ctx, "自动解锁过期暂停Cookie", g.Map{
"unlockedCount": len(expiredCookies),
})
}
}
@@ -83,6 +107,17 @@ func (s *sJdCookie) UpdateCookieStatus(ctx context.Context, cookieId string, sta
}
m := dao.V1JdCookieAccount.Ctx(ctx).DB(config.GetDatabaseV1())
// 获取更新前的Cookie信息
var oldCookie *entity.V1JdCookieAccount
err = m.Where(dao.V1JdCookieAccount.Columns().CookieId, cookieId).Scan(&oldCookie)
if err != nil {
return gerror.Wrap(err, "查询Cookie信息失败")
}
if oldCookie == nil {
return gerror.New("Cookie不存在")
}
updateData := &do.V1JdCookieAccount{
Status: status,
FailureCount: failureCount,
@@ -103,6 +138,23 @@ func (s *sJdCookie) UpdateCookieStatus(ctx context.Context, cookieId string, sta
return gerror.Wrap(err, "更新Cookie状态失败")
}
// 记录状态变更历史
if oldCookie.Status != status || oldCookie.FailureCount != failureCount {
var changeType string
switch status {
case int(consts.JdCookieStatusNormal):
changeType = string(consts.CookieChangeTypeResume)
case int(consts.JdCookieStatusSuspend):
changeType = string(consts.CookieChangeTypeSuspend)
case int(consts.JdCookieStatusExpired):
changeType = string(consts.CookieChangeTypeFail)
default:
changeType = string(consts.CookieChangeTypeUpdate)
}
_ = s.RecordCookieHistory(ctx, cookieId, changeType, oldCookie.Status, status, "", failureCount)
}
return
}
@@ -131,6 +183,9 @@ func (s *sJdCookie) CreateJdOrder(ctx context.Context, jdOrderId, payId, cookieI
return gerror.Wrap(err, "创建京东订单失败")
}
// 记录京东订单创建历史
_ = s.RecordJdOrderHistory(ctx, jdOrderId, string(consts.JdOrderChangeTypeCreate), payId, "")
return
}
@@ -141,6 +196,17 @@ func (s *sJdCookie) UpdateJdOrderStatus(ctx context.Context, jdOrderId string, s
}
m := dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1())
// 获取更新前的订单信息
var oldOrder *entity.V1JdCookieJdOrder
err = m.Where(dao.V1JdCookieJdOrder.Columns().JdOrderId, jdOrderId).Scan(&oldOrder)
if err != nil {
return gerror.Wrap(err, "查询京东订单失败")
}
if oldOrder == nil {
return gerror.New("京东订单不存在")
}
updateData := &do.V1JdCookieJdOrder{
Status: status,
}
@@ -155,6 +221,40 @@ func (s *sJdCookie) UpdateJdOrderStatus(ctx context.Context, jdOrderId string, s
return gerror.Wrap(err, "更新京东订单状态失败")
}
// 记录状态变更历史
if oldOrder.Status != status {
var changeType string
switch status {
case int(consts.JdOrderStatusPaid):
changeType = string(consts.JdOrderChangeTypePay)
case int(consts.JdOrderStatusExpired):
changeType = string(consts.JdOrderChangeTypeExpire)
case int(consts.JdOrderStatusCanceled):
changeType = string(consts.JdOrderChangeTypeInvalid)
default:
changeType = string(consts.JdOrderChangeTypeReplace)
}
// 获取当前关联的订单ID
orderId := ""
if oldOrder.CurrentOrderId > 0 {
// 查询订单表获取订单号
var order *entity.V1JdCookieOrder
_ = dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
Where(dao.V1JdCookieOrder.Columns().Id, oldOrder.CurrentOrderId).
Scan(&order)
if order != nil {
orderId = order.OrderId
}
}
payUrl := wxPayUrl
if payUrl == "" {
payUrl = oldOrder.WxPayUrl
}
_ = s.RecordJdOrderHistory(ctx, jdOrderId, changeType, orderId, payUrl)
}
return
}

View File

@@ -11,7 +11,6 @@ import (
_ "kami/internal/logic/card_apple_account"
_ "kami/internal/logic/card_apple_order"
_ "kami/internal/logic/card_redeem_account"
_ "kami/internal/logic/card_redeem_cookie"
_ "kami/internal/logic/card_redeem_order"
_ "kami/internal/logic/card_t_mall_account"
_ "kami/internal/logic/card_t_mall_order"

View File

@@ -1,70 +0,0 @@
package model
import (
v1 "kami/api/card_redeem_jd/v1"
"kami/internal/consts"
"kami/internal/model/entity"
)
type CardRedeemCookieCreatedInput struct {
v1.AccountEntity
Category consts.CardRedeemCookieCategory
}
type CardRedeemCookieUpdatedInput struct {
Id uint
v1.AccountEntity
}
type CardRedeemCookieStatusInput struct {
Id uint
Status consts.CardRedeemCookieStatus
Category consts.CardRedeemCookieCategory
}
type CardRedeemCookieGetInput struct {
Id uint
Category consts.CardRedeemCookieCategory
}
type CardRedeemCookieGetListInput struct {
*v1.AccountListReq
Category consts.CardRedeemCookieCategory
}
type CardRedeemCookieStatisticInput struct {
AccountIds []uint
}
type CardRedeemCookieStatisticOutput struct {
TotalCount int `orm:"total_count"`
SuccessCount int `orm:"success_count"`
TotalAmount int `orm:"total_amount"`
SuccessAmount int `orm:"success_amount"`
CookieId int `orm:"cookie_id"`
}
type CardRedeemCookieDeleteInput struct {
Id uint
}
type CardRedeemCookiePlaceOrderInput struct {
Category consts.RedeemOrderCardCategory
OrderId string `json:"orderId"`
OrderAmount float64 `json:"orderAmount"`
UserAgent string `json:"userAgent"`
}
type CardRedeemCookieOrderListInput struct {
*v1.OrderListReq
}
type CardRedeemCookieOrderListOutput struct {
List []*v1.OrderListSchema
Total int
}
type CardRedeemCookePlaceOrderOutput struct {
entity.V1CardRedeemCookieOrder
JdOrder entity.V1CardRedeemCookieOrderJd
}

View File

@@ -1,25 +0,0 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// V1CardRedeemCookieInfo is the golang structure of table card_redeem_cookie_info for DAO operations like Where/Data.
type V1CardRedeemCookieInfo struct {
g.Meta `orm:"table:card_redeem_cookie_info, do:true"`
Id any //
Name any //
Cookie any //
Notes any //
Status any //
Category any //
FailCount any // 调用次数
CreatedAt *gtime.Time //
UpdatedAt *gtime.Time //
DeletedAt *gtime.Time //
}

View File

@@ -1,26 +0,0 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// V1CardRedeemCookieOrder is the golang structure of table card_redeem_cookie_order for DAO operations like Where/Data.
type V1CardRedeemCookieOrder struct {
g.Meta `orm:"table:card_redeem_cookie_order, do:true"`
Id any //
BankOrderId any // 订单id
OrderAmount any // 订单金额
CookieId any //
OrderNo any // 订单编号
JdOrderNo any //
Status any //
Note any //
DeletedAt *gtime.Time //
CreatedAt *gtime.Time //
UpdatedAt *gtime.Time //
}

View File

@@ -1,24 +0,0 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// V1CardRedeemCookieOrderHistory is the golang structure of table card_redeem_cookie_order_history for DAO operations like Where/Data.
type V1CardRedeemCookieOrderHistory struct {
g.Meta `orm:"table:card_redeem_cookie_order_history, do:true"`
Id any // 主键ID
OrderId any // 关联的订单ID
OrderNo any // 订单号
BankOrderId any // 银行订单号
Action any // 订单动作
Status any // 订单状态
Amount any // 订单金额
Remark any // 备注信息
CreatedAt *gtime.Time // 创建时间
}

View File

@@ -1,33 +0,0 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// V1CardRedeemCookieOrderJd is the golang structure of table card_redeem_cookie_order_jd for DAO operations like Where/Data.
type V1CardRedeemCookieOrderJd struct {
g.Meta `orm:"table:card_redeem_cookie_order_jd, do:true"`
Id any //
CookieOrderId any // 订单 id
CookieAccountId any // cookieid
ResponseData any // 返回值
Status any //
PayId any //
WebPayLink any //
ClientPayLink any //
OrderNo any //
UserAgent any //
UserClient any //
Note any //
CreatedAt *gtime.Time //
UpdatedAt *gtime.Time //
DeletedAt *gtime.Time //
CardNo any //
CardPassword any //
Category any // 添加不同种类
}

View File

@@ -1,23 +0,0 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// V1CardRedeemCookieOrderJdHistory is the golang structure of table card_redeem_cookie_order_jd_history for DAO operations like Where/Data.
type V1CardRedeemCookieOrderJdHistory struct {
g.Meta `orm:"table:card_redeem_cookie_order_jd_history, do:true"`
Id any // 主键ID
OrderId any // 关联的订单ID
OrderNo any // 订单号
Action any // 订单动作
Status any // 订单状态
Amount any // 订单金额
Remark any // 备注信息
CreatedAt *gtime.Time // 创建时间
}

View File

@@ -23,6 +23,7 @@ type V1JdCookieJdOrder struct {
WxPayExpireAt *gtime.Time // 微信支付链接过期时间
OrderExpireAt *gtime.Time // 订单过期时间(默认24小时)
CurrentOrderId any // 当前关联的订单ID
PaidAt *gtime.Time //
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
DeletedAt *gtime.Time //

View File

@@ -1,23 +0,0 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// V1CardRedeemCookieInfo is the golang structure for table v1card_redeem_cookie_info.
type V1CardRedeemCookieInfo struct {
Id int `json:"id" orm:"id" description:""`
Name string `json:"name" orm:"name" description:""`
Cookie string `json:"cookie" orm:"cookie" description:""`
Notes string `json:"notes" orm:"notes" description:""`
Status string `json:"status" orm:"status" description:""`
Category string `json:"category" orm:"category" description:""`
FailCount uint `json:"failCount" orm:"fail_count" description:"调用次数"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""`
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""`
}

View File

@@ -1,24 +0,0 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// V1CardRedeemCookieOrder is the golang structure for table v1card_redeem_cookie_order.
type V1CardRedeemCookieOrder struct {
Id int `json:"id" orm:"id" description:""`
BankOrderId string `json:"bankOrderId" orm:"bank_order_id" description:"订单id"`
OrderAmount float64 `json:"orderAmount" orm:"order_amount" description:"订单金额"`
CookieId int `json:"cookieId" orm:"cookie_id" description:""`
OrderNo string `json:"orderNo" orm:"order_no" description:"订单编号"`
JdOrderNo string `json:"jdOrderNo" orm:"jd_order_no" description:""`
Status string `json:"status" orm:"status" description:""`
Note string `json:"note" orm:"note" description:""`
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""`
}

View File

@@ -1,23 +0,0 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
"github.com/shopspring/decimal"
)
// V1CardRedeemCookieOrderHistory is the golang structure for table v1card_redeem_cookie_order_history.
type V1CardRedeemCookieOrderHistory struct {
Id uint64 `json:"id" orm:"id" description:"主键ID"`
OrderId int `json:"orderId" orm:"order_id" description:"关联的订单ID"`
OrderNo string `json:"orderNo" orm:"order_no" description:"订单号"`
BankOrderId string `json:"bankOrderId" orm:"bank_order_id" description:"银行订单号"`
Action string `json:"action" orm:"action" description:"订单动作"`
Status string `json:"status" orm:"status" description:"订单状态"`
Amount decimal.Decimal `json:"amount" orm:"amount" description:"订单金额"`
Remark string `json:"remark" orm:"remark" description:"备注信息"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
}

View File

@@ -1,31 +0,0 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// V1CardRedeemCookieOrderJd is the golang structure for table v1card_redeem_cookie_order_jd.
type V1CardRedeemCookieOrderJd struct {
Id uint `json:"id" orm:"id" description:""`
CookieOrderId int `json:"cookieOrderId" orm:"cookie_order_id" description:"订单 id"`
CookieAccountId int `json:"cookieAccountId" orm:"cookie_account_id" description:"cookieid"`
ResponseData string `json:"responseData" orm:"response_data" description:"返回值"`
Status string `json:"status" orm:"status" description:""`
PayId string `json:"payId" orm:"pay_id" description:""`
WebPayLink string `json:"webPayLink" orm:"web_pay_link" description:""`
ClientPayLink string `json:"clientPayLink" orm:"client_pay_link" description:""`
OrderNo string `json:"orderNo" orm:"order_no" description:""`
UserAgent string `json:"userAgent" orm:"user_agent" description:""`
UserClient string `json:"userClient" orm:"user_client" description:""`
Note string `json:"note" orm:"note" description:""`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""`
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""`
CardNo string `json:"cardNo" orm:"card_no" description:""`
CardPassword string `json:"cardPassword" orm:"card_password" description:""`
Category string `json:"category" orm:"category" description:"添加不同种类"`
}

View File

@@ -1,22 +0,0 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
"github.com/shopspring/decimal"
)
// V1CardRedeemCookieOrderJdHistory is the golang structure for table v1card_redeem_cookie_order_jd_history.
type V1CardRedeemCookieOrderJdHistory struct {
Id uint64 `json:"id" orm:"id" description:"主键ID"`
OrderId uint `json:"orderId" orm:"order_id" description:"关联的订单ID"`
OrderNo string `json:"orderNo" orm:"order_no" description:"订单号"`
Action string `json:"action" orm:"action" description:"订单动作"`
Status string `json:"status" orm:"status" description:"订单状态"`
Amount decimal.Decimal `json:"amount" orm:"amount" description:"订单金额"`
Remark string `json:"remark" orm:"remark" description:"备注信息"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
}

View File

@@ -22,6 +22,7 @@ type V1JdCookieJdOrder struct {
WxPayExpireAt *gtime.Time `json:"wxPayExpireAt" orm:"wx_pay_expire_at" description:"微信支付链接过期时间"`
OrderExpireAt *gtime.Time `json:"orderExpireAt" orm:"order_expire_at" description:"订单过期时间(默认24小时)"`
CurrentOrderId int64 `json:"currentOrderId" orm:"current_order_id" description:"当前关联的订单ID"`
PaidAt *gtime.Time `json:"paidAt" orm:"paid_at" description:""`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""`

View File

@@ -1,62 +0,0 @@
// ================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
import (
"context"
"kami/internal/model"
"kami/internal/model/entity"
"github.com/gogf/gf/v2/database/gdb"
)
type (
ICardRedeemCookie interface {
// Save 保存cookie
Save(ctx context.Context, input *model.CardRedeemCookieCreatedInput, tx gdb.TX) (err error)
// Update 更新cookie
Update(ctx context.Context, input *model.CardRedeemCookieUpdatedInput, tx gdb.TX) (err error)
// UpdateStatus 更新cookie状态
UpdateStatus(ctx context.Context, input *model.CardRedeemCookieStatusInput, tx gdb.TX) (err error)
// GetOne 获取一个cookie
GetOne(ctx context.Context, input *model.CardRedeemCookieGetInput, tx gdb.TX) (res *entity.V1CardRedeemCookieInfo, err error)
// AccountList 获取ck列表
AccountList(ctx context.Context, input *model.CardRedeemCookieGetListInput, tx gdb.TX) (res []*entity.V1CardRedeemCookieInfo, total int, err error)
// AccountStatistic 账户统计
AccountStatistic(ctx context.Context, input *model.CardRedeemCookieStatisticInput, tx gdb.TX) (res []*model.CardRedeemCookieStatisticOutput, err error)
// Delete 删除一个cookie
Delete(ctx context.Context, input *model.CardRedeemCookieDeleteInput, tx gdb.TX) (err error)
// GetOrderEndCookie 获取已下单的ck
GetOrderEndCookie(ctx context.Context, tx gdb.TX) (res *entity.V1CardRedeemCookieInfo, err error)
// ScheduleAccount 调度账号
ScheduleAccount(ctx context.Context, tx gdb.TX) (output *entity.V1CardRedeemCookieInfo, err error)
// PlaceOrder 下单
PlaceOrder(ctx context.Context, input *model.CardRedeemCookiePlaceOrderInput, tx gdb.TX) (output *model.CardRedeemCookePlaceOrderOutput, err error)
// OrderList 查询订单
OrderList(ctx context.Context, input *model.CardRedeemCookieOrderListInput, tx gdb.TX) (output *model.CardRedeemCookieOrderListOutput, err error)
// GetOrderByBankOrderId 根据bankOrderId查询订单
GetOrderByBankOrderId(ctx context.Context, bankOrderId string, tx gdb.TX) (output *entity.V1CardRedeemCookieOrder, err error)
// GetLatestJdOrder 获取最新的京东订单
GetLatestJdOrder(ctx context.Context, orderId int, tx gdb.TX) (output *entity.V1CardRedeemCookieOrderJd, err error)
// CheckPaySuccess 检测用户是否支付成功
CheckPaySuccess(ctx context.Context, tx gdb.TX)
}
)
var (
localCardRedeemCookie ICardRedeemCookie
)
func CardRedeemCookie() ICardRedeemCookie {
if localCardRedeemCookie == nil {
panic("implement not found for interface ICardRedeemCookie, forgot register?")
}
return localCardRedeemCookie
}
func RegisterCardRedeemCookie(i ICardRedeemCookie) {
localCardRedeemCookie = i
}

View File

@@ -22,20 +22,32 @@ type (
UpdateAccount(ctx context.Context, cookieId string, cookieValue string, accountName string, status int, remark string) (err error)
// DeleteAccount 删除Cookie账户
DeleteAccount(ctx context.Context, cookieId string) (err error)
// BatchDeleteAccount 批量删除Cookie账户
BatchDeleteAccount(ctx context.Context, cookieIds []string) (successIds []string, failedCount int, err error)
// GetAccount 获取单个Cookie账户
GetAccount(ctx context.Context, cookieId string) (account *v1.CookieAccountInfo, err error)
// BatchCheckAccount 批量检测Cookie状态
BatchCheckAccount(ctx context.Context, cookieIds []string) (results []*v1.CookieCheckResult, err error)
// GetCookieHistory Cookie变更历史
GetCookieHistory(ctx context.Context, cookieId string, page int, size int, changeType string) (list []*v1.CookieHistoryInfo, total int, err error)
// GetOrderHistory 订单变更历史
GetOrderHistory(ctx context.Context, orderId string, orderType string, page int, size int) (list []*v1.OrderHistoryInfo, total int, err error)
// GetJdOrderHistoryByOrderId 根据订单ID获取所有关联的京东订单历史
GetJdOrderHistoryByOrderId(ctx context.Context, orderId string, page int, size int) (list []*v1.JdOrderHistoryInfo, total int, err error)
// CreateOrder 创建订单
CreateOrder(ctx context.Context, orderId string, amount float64, category string) (wxPayUrl string, expireTime string, jdOrderId string, err error)
// GetPaymentUrl 获取支付链接
GetPaymentUrl(ctx context.Context, orderId string) (wxPayUrl string, expireTime string, jdOrderId string, err error)
// GetOrder 获取单个订单
GetOrder(ctx context.Context, orderId string) (order *v1.OrderInfo, err error)
// GetJdOrder 获取单个京东订单
GetJdOrder(ctx context.Context, jdOrderId string) (order *v1.JdOrderInfo, err error)
// GetOrderStatus 查询订单状态
GetOrderStatus(ctx context.Context, orderId string) (order *v1.OrderInfo, err error)
// ListOrder 订单列表查询
ListOrder(ctx context.Context, page int, size int, status int, startTime string, endTime string) (list []*v1.OrderInfo, total int, err error)
// ListJdOrder 京东订单列表查询
ListJdOrder(ctx context.Context, page int, size int, status int, startTime string, endTime string, orderId string) (list []*v1.JdOrderInfo, total int, err error)
// CheckJdOrderPayment 检查京东订单支付状态
CheckJdOrderPayment(ctx context.Context, jdOrderId string) (isPaid bool, paymentStatus int, message string, canReuse bool, err error)
// CleanupExpiredOrders 清理过期订单(定时任务)

View File

@@ -47,6 +47,6 @@ func Register(ctx context.Context) {
_, _ = gcron.AddSingleton(ctx, "@every 5s", func(ctx context.Context) {
_ = service.CardRedeemOrder().TriggerConsumeWithContext(ctx)
service.CardRedeemCookie().CheckPaySuccess(ctx, nil)
//service.CardRedeemCookie().CheckPaySuccess(ctx, nil)
})
}