完成合并:解决代码冲突

This commit is contained in:
Mrx
2026-02-06 16:12:02 +08:00
27 changed files with 1228 additions and 219 deletions

View File

@@ -83,9 +83,9 @@ service main {
@handler AdminGetInviteCodeList
get /invite_code/list (AdminGetInviteCodeListReq) returns (AdminGetInviteCodeListResp)
// 平台升级代理等级(免费升级,遵守代理系统逻辑规则)
// 平台升级代理等级
@handler AdminUpgradeAgent
post /upgrade (AdminUpgradeAgentReq) returns (AdminUpgradeAgentResp)
post /upgrade/agent (AdminUpgradeAgentReq) returns (AdminUpgradeAgentResp)
}
type (
@@ -128,14 +128,6 @@ type (
AdminAuditAgentResp {
Success bool `json:"success"`
}
// 平台升级代理等级
AdminUpgradeAgentReq {
AgentId string `json:"agent_id"` // 代理ID
ToLevel int64 `json:"to_level"` // 目标等级2=黄金3=钻石
}
AdminUpgradeAgentResp {
Success bool `json:"success"`
}
// 推广链接分页查询
AdminGetAgentLinkListReq {
Page int64 `form:"page"` // 页码
@@ -165,6 +157,7 @@ type (
AgentId *string `form:"agent_id,optional"` // 代理ID可选
OrderId *string `form:"order_id,optional"` // 订单ID可选
ProcessStatus *int64 `form:"process_status,optional"` // 处理状态(可选)
OrderStatus *string `form:"order_status,optional"` // 订单状态可选pending-待支付paid-已支付refunded-已退款closed-已关闭failed-支付失败
}
AgentOrderListItem {
Id string `json:"id"` // 主键
@@ -177,7 +170,8 @@ type (
ActualBasePrice float64 `json:"actual_base_price"` // 实际底价
PriceCost float64 `json:"price_cost"` // 提价成本
AgentProfit float64 `json:"agent_profit"` // 代理收益
ProcessStatus int64 `json:"process_status"` // 处理状态
ProcessStatus int64 `json:"process_status"` // 处理状态(保留用于筛选,前端不显示)
OrderStatus string `json:"order_status"` // 订单状态pending-待支付paid-已支付refunded-已退款closed-已关闭failed-支付失败
CreateTime string `json:"create_time"` // 创建时间
}
AdminGetAgentOrderListResp {
@@ -212,6 +206,7 @@ type (
AgentId *string `form:"agent_id,optional"` // 代理ID可选
SourceAgentId *string `form:"source_agent_id,optional"` // 来源代理ID可选
RebateType *int64 `form:"rebate_type,optional"` // 返佣类型(可选)
Status *int64 `form:"status,optional"` // 状态可选1=已发放2=已冻结3=已取消(已退款)
}
AgentRebateListItem {
Id string `json:"id"` // 主键
@@ -220,6 +215,7 @@ type (
OrderId string `json:"order_id"` // 订单ID
RebateType int64 `json:"rebate_type"` // 返佣类型
Amount float64 `json:"amount"` // 金额
Status int64 `json:"status"` // 状态1=已发放2=已冻结3=已取消(已退款)
CreateTime string `json:"create_time"` // 创建时间
}
AdminGetAgentRebateListResp {
@@ -258,17 +254,20 @@ type (
WithdrawNo *string `form:"withdraw_no,optional"` // 提现单号(可选)
}
AgentWithdrawalListItem {
Id string `json:"id"` // 主键
AgentId string `json:"agent_id"` // 代理ID
WithdrawNo string `json:"withdraw_no"` // 提现单号
Amount float64 `json:"amount"` // 金额
TaxAmount float64 `json:"tax_amount"` // 税费金额
ActualAmount float64 `json:"actual_amount"` // 实际到账金额
Status int64 `json:"status"` // 状态
PayeeAccount string `json:"payee_account"` // 收款账户
PayeeName string `json:"payee_name"` // 收款人姓名
Remark string `json:"remark"` // 备注
CreateTime string `json:"create_time"` // 创建时间
Id string `json:"id"` // 主键
AgentId string `json:"agent_id"` // 代理ID
WithdrawNo string `json:"withdraw_no"` // 提现单号
Amount float64 `json:"amount"` // 金额
TaxAmount float64 `json:"tax_amount"` // 税费金额
ActualAmount float64 `json:"actual_amount"` // 实际到账金额
Status int64 `json:"status"` // 状态
WithdrawalType int64 `json:"withdrawal_type"` // 提现方式1=支付宝2=银行卡
PayeeAccount string `json:"payee_account"` // 收款账户(支付宝账号或银行卡号)
PayeeName string `json:"payee_name"` // 收款人姓名
BankCardNo string `json:"bank_card_no"` // 银行卡号(银行卡提现时使用)
BankName string `json:"bank_name"` // 开户行名称(银行卡提现时使用)
Remark string `json:"remark"` // 备注
CreateTime string `json:"create_time"` // 创建时间
}
AdminGetAgentWithdrawalListResp {
Total int64 `json:"total"` // 总数
@@ -434,5 +433,13 @@ type (
Total int64 `json:"total"` // 总数
Items []InviteCodeListItem `json:"items"` // 列表数据
}
// 平台升级代理等级
AdminUpgradeAgentReq {
AgentId string `json:"agent_id"` // 代理ID
ToLevel int64 `json:"to_level"` // 目标等级2=黄金3=钻石
}
AdminUpgradeAgentResp {
Success bool `json:"success"` // 是否成功
}
)

View File

@@ -1,5 +1,7 @@
syntax = "v1"
import "product.api"
info (
title: "代理服务"
desc: "新代理系统接口"
@@ -224,6 +226,10 @@ service main {
@handler ApplyWithdrawal
post /withdrawal/apply (ApplyWithdrawalReq) returns (ApplyWithdrawalResp)
// 获取上次提现信息(用于前端预填)
@handler GetLastWithdrawalInfo
get /withdrawal/last_info (GetLastWithdrawalInfoReq) returns (GetLastWithdrawalInfoResp)
// 实名认证
@handler RealNameAuth
post /real_name (RealNameAuthReq) returns (RealNameAuthResp)
@@ -251,6 +257,32 @@ service main {
// 获取推广查询报告列表
@handler GetPromotionQueryList
get /promotion/query/list (GetPromotionQueryListReq) returns (GetPromotionQueryListResp)
// ============================================
// 用户模块白名单相关接口
// ============================================
@handler GetWhitelistFeatures
get /whitelist/features (GetWhitelistFeaturesReq) returns (GetWhitelistFeaturesResp)
// 创建白名单订单
@handler CreateWhitelistOrder
post /whitelist/order/create (CreateWhitelistOrderReq) returns (CreateWhitelistOrderResp)
// 获取用户白名单列表
@handler GetWhitelistList
get /whitelist/list (GetWhitelistListReq) returns (GetWhitelistListResp)
// 检查模块是否已下架(用于显示下架按钮状态)
@handler CheckFeatureWhitelistStatus
get /whitelist/check (CheckFeatureWhitelistStatusReq) returns (CheckFeatureWhitelistStatusResp)
// 下架单个模块(创建订单并支付)
@handler OfflineFeature
post /whitelist/offline (OfflineFeatureReq) returns (OfflineFeatureResp)
// 检查订单是否属于当前代理推广
@handler CheckOrderAgent
get /order/agent (CheckOrderAgentReq) returns (CheckOrderAgentResp)
}
type (
@@ -413,28 +445,30 @@ type (
LevelName string `json:"level_name"` // 等级名称
Mobile string `json:"mobile"` // 手机号
CreateTime string `json:"create_time"` // 加入团队时间
TotalRebateAmount float64 `json:"total_rebate_amount"` // 返佣给我的总金额
TodayRebateAmount float64 `json:"today_rebate_amount"` // 返佣给我的今日金额
TodayInvites int64 `json:"today_invites"` // 邀请加入团队的今日人数
MonthInvites int64 `json:"month_invites"` // 邀请加入团队的本月人数
TotalInvites int64 `json:"total_invites"` // 邀请加入团队的总人数
TodayQueries int64 `json:"today_queries"` // 当日查询量
MonthQueries int64 `json:"month_queries"` // 本月查询量
TotalQueries int64 `json:"total_queries"` // 总查询量
TotalRebateAmount float64 `json:"total_rebate_amount"` // 返佣给我的总金额
TodayRebateAmount float64 `json:"today_rebate_amount"` // 返佣给我的今日金额
TotalInvites int64 `json:"total_invites"` // 邀请加入团队的总人数
TodayInvites int64 `json:"today_invites"` // 邀请加入团队的今日人数
MonthInvites int64 `json:"month_invites"` // 邀请加入团队的本月人数
IsDirect bool `json:"is_direct"` // 是否直接下级
}
// 收益信息
GetRevenueInfoResp {
Balance float64 `json:"balance"` // 可用余额
FrozenBalance float64 `json:"frozen_balance"` // 冻结余额
TotalEarnings float64 `json:"total_earnings"` // 累计收益(钱包总收益)
WithdrawnAmount float64 `json:"withdrawn_amount"` // 累计提现
CommissionTotal float64 `json:"commission_total"` // 佣金累计总收益(推广订单获得的佣金)
CommissionToday float64 `json:"commission_today"` // 佣金今日收益
CommissionMonth float64 `json:"commission_month"` // 佣金本月收益
RebateTotal float64 `json:"rebate_total"` // 返佣累计总收益(包括推广返佣和升级返佣)
RebateToday float64 `json:"rebate_today"` // 返佣今日收益
RebateMonth float64 `json:"rebate_month"` // 返佣本月收益
Balance float64 `json:"balance"` // 可用余额
FrozenBalance float64 `json:"frozen_balance"` // 冻结余额
TotalEarnings float64 `json:"total_earnings"` // 累计收益(钱包总收益)
WithdrawnAmount float64 `json:"withdrawn_amount"` // 累计提现
CommissionTotal float64 `json:"commission_total"` // 佣金累计总收益(推广订单获得的佣金)
CommissionToday float64 `json:"commission_today"` // 佣金今日收益
CommissionMonth float64 `json:"commission_month"` // 佣金本月收益
RebateTotal float64 `json:"rebate_total"` // 返佣累计总收益(包括推广返佣和升级返佣)
RebateToday float64 `json:"rebate_today"` // 返佣今日收益
RebateMonth float64 `json:"rebate_month"` // 返佣本月收益
AlipayMonthQuota float64 `json:"alipay_month_quota"` // 支付宝每月提现总额度
AlipayMonthUsed float64 `json:"alipay_month_used"` // 本月已使用的支付宝提现额度
}
// 佣金记录
GetCommissionListReq {
@@ -473,6 +507,7 @@ type (
OrderNo string `json:"order_no"` // 订单号
RebateType int64 `json:"rebate_type"` // 返佣类型1=直接上级2=钻石上级3=黄金上级
Amount float64 `json:"amount"` // 返佣金额
Status int64 `json:"status"` // 状态1=已发放2=已冻结3=已取消(已退款)
CreateTime string `json:"create_time"` // 创建时间
}
// 升级返佣记录
@@ -539,28 +574,46 @@ type (
Total int64 `json:"total"` // 总数
List []WithdrawalItem `json:"list"` // 列表
}
// 提现记录
WithdrawalItem {
Id string `json:"id"` // 记录ID
WithdrawalNo string `json:"withdrawal_no"` // 提现单号
Amount float64 `json:"amount"` // 提现金额
TaxAmount float64 `json:"tax_amount"` // 税费金额
ActualAmount float64 `json:"actual_amount"` // 实际到账金额
Status int64 `json:"status"` // 状态1=待审核2=审核通过3=审核拒绝4=提现中5=提现成功6=提现失败
PayeeAccount string `json:"payee_account"` // 收款账户
PayeeName string `json:"payee_name"` // 收款人姓名
Remark string `json:"remark"` // 备注
CreateTime string `json:"create_time"` // 创建时间
Id string `json:"id"` // 记录ID
WithdrawalNo string `json:"withdrawal_no"` // 提现单号
Amount float64 `json:"amount"` // 提现金额
TaxAmount float64 `json:"tax_amount"` // 税费金额
ActualAmount float64 `json:"actual_amount"` // 实际到账金额
Status int64 `json:"status"` // 状态1=待审核2=审核通过3=审核拒绝4=提现中5=提现成功6=提现失败
WithdrawalType int64 `json:"withdrawal_type"` // 提现方式1=支付宝2=银行卡
PayeeAccount string `json:"payee_account"` // 收款账户(支付宝账号或银行卡号)
PayeeName string `json:"payee_name"` // 收款人姓名
BankCardNo string `json:"bank_card_no"` // 银行卡号(银行卡提现时填写)
BankName string `json:"bank_name"` // 开户行名称(银行卡提现时填写)
Remark string `json:"remark"` // 备注
CreateTime string `json:"create_time"` // 创建时间
}
// 申请提现
ApplyWithdrawalReq {
Amount float64 `json:"amount"` // 提现金额
PayeeAccount string `json:"payee_account"` // 收款账户
PayeeName string `json:"payee_name"` // 收款人姓名
Amount float64 `json:"amount"` // 提现金额
WithdrawalType int64 `json:"withdrawal_type"` // 提现方式1=支付宝2=银行卡
PayeeAccount string `json:"payee_account"` // 收款账户(支付宝账号或银行卡号)
PayeeName string `json:"payee_name"` // 收款人姓名
BankCardNo string `json:"bank_card_no,optional"` // 银行卡号(银行卡提现必填)
BankName string `json:"bank_name,optional"` // 开户行名称(银行卡提现必填)
}
ApplyWithdrawalResp {
WithdrawalId string `json:"withdrawal_id"` // 提现记录ID
WithdrawalNo string `json:"withdrawal_no"` // 提现单号
}
// 获取上次提现信息(用于前端预填)
GetLastWithdrawalInfoReq {
WithdrawalType int64 `form:"withdrawal_type"` // 提现方式1=支付宝2=银行卡
}
GetLastWithdrawalInfoResp {
WithdrawalType int64 `json:"withdrawal_type"` // 提现方式
PayeeAccount string `json:"payee_account"` // 收款账户(支付宝账号或银行卡号)
PayeeName string `json:"payee_name"` // 收款人姓名
BankCardNo string `json:"bank_card_no"` // 银行卡号
BankName string `json:"bank_name"` // 开户行名称
}
// 实名认证
RealNameAuthReq {
Name string `json:"name"` // 姓名
@@ -581,11 +634,88 @@ type (
List []PromotionQueryItem `json:"list"` // 列表
}
PromotionQueryItem {
Id string `json:"id"` // 查询ID
OrderId string `json:"order_id"` // 订单ID
ProductName string `json:"product_name"` // 产品名称
CreateTime string `json:"create_time"` // 创建时间
QueryState string `json:"query_state"` // 查询状态
Id string `json:"id"` // 查询ID
OrderId string `json:"order_id"` // 订单ID
ProductName string `json:"product_name"` // 产品名称
CreateTime string `json:"create_time"` // 创建时间
QueryState string `json:"query_state"` // 查询状态
Params map[string]interface{} `json:"params"` // 查询参数(已脱敏)
Price float64 `json:"price"` // 查询价格
}
// ============================================
// 用户模块白名单相关类型
// ============================================
GetWhitelistFeaturesReq {}
GetWhitelistFeaturesResp {
List []WhitelistFeatureItem `json:"list"` // 可屏蔽的feature列表
}
WhitelistFeatureItem {
FeatureId string `json:"feature_id"` // Feature的UUID
FeatureApiId string `json:"feature_api_id"` // Feature的API标识
FeatureName string `json:"feature_name"` // Feature的名称
WhitelistPrice float64 `json:"whitelist_price"` // 屏蔽价格(单位:元)
}
CreateWhitelistOrderReq {
IdCard string `json:"id_card"` // 身份证号(查询对象标识)
FeatureIds []string `json:"feature_ids"` // 要屏蔽的feature ID列表
OrderId string `json:"order_id,optional"` // 关联的查询订单ID可选
}
CreateWhitelistOrderResp {
OrderId string `json:"order_id"` // 订单ID
OrderNo string `json:"order_no"` // 订单号
TotalAmount float64 `json:"total_amount"` // 总金额
}
GetWhitelistListReq {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"page_size"` // 每页数量
IdCard string `form:"id_card,optional"` // 身份证号(可选,用于筛选)
}
GetWhitelistListResp {
Total int64 `json:"total"` // 总数
List []WhitelistItem `json:"list"` // 列表
}
WhitelistItem {
Id string `json:"id"` // 白名单记录ID
IdCard string `json:"id_card"` // 身份证号
FeatureId string `json:"feature_id"` // Feature的UUID
FeatureApiId string `json:"feature_api_id"` // Feature的API标识
FeatureName string `json:"feature_name"` // Feature的名称
Amount float64 `json:"amount"` // 费用
Status int64 `json:"status"` // 状态1=生效2=已失效
StatusText string `json:"status_text"` // 状态文本
CreateTime string `json:"create_time"` // 创建时间
}
// 检查模块白名单状态请求
CheckFeatureWhitelistStatusReq {
IdCard string `form:"id_card"` // 身份证号
FeatureApiId string `form:"feature_api_id"` // Feature的API标识
QueryId string `form:"query_id,optional"` // 查询记录ID可选用于检查报告数据是否已删除
}
// 检查模块白名单状态响应
CheckFeatureWhitelistStatusResp {
IsWhitelisted bool `json:"is_whitelisted"` // 是否在白名单中
WhitelistPrice float64 `json:"whitelist_price"` // 屏蔽价格单位如果为0表示不支持下架
FeatureId string `json:"feature_id"` // Feature的UUID
DataDeleted bool `json:"data_deleted"` // 报告数据是否已删除仅当提供了query_id时有效
}
// 下架单个模块请求
OfflineFeatureReq {
FeatureApiId string `json:"feature_api_id"` // Feature的API标识
QueryId string `json:"query_id"` // 查询记录IDQuery表的ID必选
}
// 下架单个模块响应
OfflineFeatureResp {
Success bool `json:"success"` // 是否已完成下架
NeedPay bool `json:"need_pay"` // 是否需要发起支付
Amount float64 `json:"amount"` // 需要支付的金额单位0表示无需支付
}
// 检查订单是否属于当前代理请求
CheckOrderAgentReq {
OrderId string `form:"order_id"` // 订单ID
}
// 检查订单是否属于当前代理响应
CheckOrderAgentResp {
IsAgentOrder bool `json:"is_agent_order"` // 是否是当前代理推广的订单
}
)

View File

@@ -0,0 +1,29 @@
package agent
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"qnc-server/app/main/api/internal/logic/agent"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"qnc-server/common/result"
"qnc-server/pkg/lzkit/validator"
)
func CheckFeatureWhitelistStatusHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.CheckFeatureWhitelistStatusReq
if err := httpx.Parse(r, &req); err != nil {
result.ParamErrorResult(r, w, err)
return
}
if err := validator.Validate(req); err != nil {
result.ParamValidateErrorResult(r, w, err)
return
}
l := agent.NewCheckFeatureWhitelistStatusLogic(r.Context(), svcCtx)
resp, err := l.CheckFeatureWhitelistStatus(&req)
result.HttpResult(r, w, resp, err)
}
}

View File

@@ -0,0 +1,29 @@
package agent
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"qnc-server/app/main/api/internal/logic/agent"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"qnc-server/common/result"
"qnc-server/pkg/lzkit/validator"
)
func CheckOrderAgentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.CheckOrderAgentReq
if err := httpx.Parse(r, &req); err != nil {
result.ParamErrorResult(r, w, err)
return
}
if err := validator.Validate(req); err != nil {
result.ParamValidateErrorResult(r, w, err)
return
}
l := agent.NewCheckOrderAgentLogic(r.Context(), svcCtx)
resp, err := l.CheckOrderAgent(&req)
result.HttpResult(r, w, resp, err)
}
}

View File

@@ -0,0 +1,29 @@
package agent
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"qnc-server/app/main/api/internal/logic/agent"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"qnc-server/common/result"
"qnc-server/pkg/lzkit/validator"
)
func CreateWhitelistOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.CreateWhitelistOrderReq
if err := httpx.Parse(r, &req); err != nil {
result.ParamErrorResult(r, w, err)
return
}
if err := validator.Validate(req); err != nil {
result.ParamValidateErrorResult(r, w, err)
return
}
l := agent.NewCreateWhitelistOrderLogic(r.Context(), svcCtx)
resp, err := l.CreateWhitelistOrder(&req)
result.HttpResult(r, w, resp, err)
}
}

View File

@@ -0,0 +1,30 @@
package agent
import (
"net/http"
"qnc-server/app/main/api/internal/logic/agent"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"qnc-server/common/result"
"qnc-server/pkg/lzkit/validator"
"github.com/zeromicro/go-zero/rest/httpx"
)
func GetLastWithdrawalInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GetLastWithdrawalInfoReq
if err := httpx.Parse(r, &req); err != nil {
result.ParamErrorResult(r, w, err)
return
}
if err := validator.Validate(req); err != nil {
result.ParamValidateErrorResult(r, w, err)
return
}
l := agent.NewGetLastWithdrawalInfoLogic(r.Context(), svcCtx)
resp, err := l.GetLastWithdrawalInfo(&req)
result.HttpResult(r, w, resp, err)
}
}

View File

@@ -0,0 +1,29 @@
package agent
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"qnc-server/app/main/api/internal/logic/agent"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"qnc-server/common/result"
"qnc-server/pkg/lzkit/validator"
)
func GetWhitelistFeaturesHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GetWhitelistFeaturesReq
if err := httpx.Parse(r, &req); err != nil {
result.ParamErrorResult(r, w, err)
return
}
if err := validator.Validate(req); err != nil {
result.ParamValidateErrorResult(r, w, err)
return
}
l := agent.NewGetWhitelistFeaturesLogic(r.Context(), svcCtx)
resp, err := l.GetWhitelistFeatures(&req)
result.HttpResult(r, w, resp, err)
}
}

View File

@@ -0,0 +1,29 @@
package agent
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"qnc-server/app/main/api/internal/logic/agent"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"qnc-server/common/result"
"qnc-server/pkg/lzkit/validator"
)
func GetWhitelistListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GetWhitelistListReq
if err := httpx.Parse(r, &req); err != nil {
result.ParamErrorResult(r, w, err)
return
}
if err := validator.Validate(req); err != nil {
result.ParamValidateErrorResult(r, w, err)
return
}
l := agent.NewGetWhitelistListLogic(r.Context(), svcCtx)
resp, err := l.GetWhitelistList(&req)
result.HttpResult(r, w, resp, err)
}
}

View File

@@ -0,0 +1,29 @@
package agent
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"qnc-server/app/main/api/internal/logic/agent"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"qnc-server/common/result"
"qnc-server/pkg/lzkit/validator"
)
func OfflineFeatureHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.OfflineFeatureReq
if err := httpx.Parse(r, &req); err != nil {
result.ParamErrorResult(r, w, err)
return
}
if err := validator.Validate(req); err != nil {
result.ParamValidateErrorResult(r, w, err)
return
}
l := agent.NewOfflineFeatureLogic(r.Context(), svcCtx)
resp, err := l.OfflineFeature(&req)
result.HttpResult(r, w, resp, err)
}
}

View File

@@ -103,7 +103,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
},
{
Method: http.MethodPost,
Path: "/upgrade",
Path: "/upgrade/agent",
Handler: admin_agent.AdminUpgradeAgentHandler(serverCtx),
},
{
@@ -671,6 +671,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/level/privilege",
Handler: agent.GetLevelPrivilegeHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/order/agent",
Handler: agent.CheckOrderAgentHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/product_config",
@@ -736,11 +741,41 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/upgrade/subordinate",
Handler: agent.UpgradeSubordinateHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/whitelist/check",
Handler: agent.CheckFeatureWhitelistStatusHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/whitelist/features",
Handler: agent.GetWhitelistFeaturesHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/whitelist/list",
Handler: agent.GetWhitelistListHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/whitelist/offline",
Handler: agent.OfflineFeatureHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/whitelist/order/create",
Handler: agent.CreateWhitelistOrderHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/withdrawal/apply",
Handler: agent.ApplyWithdrawalHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/withdrawal/last_info",
Handler: agent.GetLastWithdrawalInfoHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/withdrawal/list",

View File

@@ -4,10 +4,10 @@ import (
"context"
"database/sql"
"fmt"
"time"
"qnc-server/common/globalkey"
"os"
"qnc-server/common/xerr"
"qnc-server/pkg/lzkit/lzUtils"
"time"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/sqlx"
@@ -32,6 +32,13 @@ func NewAdminAuditWithdrawalLogic(ctx context.Context, svcCtx *svc.ServiceContex
}
}
// parseFloat 解析配置中的浮点数
func (l *AdminAuditWithdrawalLogic) parseFloat(s string) (float64, error) {
var result float64
_, err := fmt.Sscanf(s, "%f", &result)
return result, err
}
func (l *AdminAuditWithdrawalLogic) AdminAuditWithdrawal(req *types.AdminAuditWithdrawalReq) (resp *types.AdminAuditWithdrawalResp, err error) {
// 1. 查询提现记录
withdrawal, err := l.svcCtx.AgentWithdrawalModel.FindOne(l.ctx, req.WithdrawalId)
@@ -46,39 +53,126 @@ func (l *AdminAuditWithdrawalLogic) AdminAuditWithdrawal(req *types.AdminAuditWi
// 4. 使用事务处理审核
err = l.svcCtx.AgentWithdrawalModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
if req.Status == 2 { // 审核通过
// 4.1 更新提现记录状态为提现中
withdrawal.Status = 4 // 提现中
withdrawal.Remark = sql.NullString{String: req.Remark, Valid: true}
if err := l.svcCtx.AgentWithdrawalModel.UpdateWithVersion(transCtx, session, withdrawal); err != nil {
return errors.Wrapf(err, "更新提现记录失败")
}
switch req.Status {
case 2: // 审核通过
// 4.1 根据提现方式处理
switch withdrawal.WithdrawalType {
case 1:
// 支付宝提现:审核通过前再次校验月度额度,避免一次性通过多笔超限
now := time.Now()
monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
nextMonthStart := monthStart.AddDate(0, 1, 0)
// 4.2 调用支付宝转账接口
outBizNo := withdrawal.WithdrawNo
transferResp, err := l.svcCtx.AlipayService.AliTransfer(transCtx, withdrawal.PayeeAccount, withdrawal.PayeeName, withdrawal.ActualAmount, "代理提现", outBizNo)
if err != nil {
// 转账失败,更新状态为失败
withdrawal.Status = 6 // 提现失败
withdrawal.Remark = sql.NullString{String: fmt.Sprintf("转账失败: %v", err), Valid: true}
l.svcCtx.AgentWithdrawalModel.UpdateWithVersion(transCtx, session, withdrawal)
// 解冻余额
wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(transCtx, withdrawal.AgentId)
if err == nil {
wallet.FrozenBalance -= withdrawal.Amount
wallet.Balance += withdrawal.Amount
l.svcCtx.AgentWalletModel.UpdateWithVersion(transCtx, session, wallet)
// 获取支付宝月度额度配置(默认 800 元)
alipayQuota := 800.0
if cfg, cfgErr := l.svcCtx.AgentConfigModel.FindOneByConfigKey(transCtx, "alipay_month_quota"); cfgErr == nil {
if parsed, parseErr := l.parseFloat(cfg.ConfigValue); parseErr == nil && parsed > 0 {
alipayQuota = parsed
}
}
return errors.Wrapf(err, "支付宝转账失败")
}
// 统计本月已成功的支付宝提现金额status=5
withdrawBuilder := l.svcCtx.AgentWithdrawalModel.SelectBuilder().
Where("agent_id = ? AND withdrawal_type = ? AND status = ? AND create_time >= ? AND create_time < ?",
withdrawal.AgentId, 1, 5, monthStart, nextMonthStart)
usedAmount, sumErr := l.svcCtx.AgentWithdrawalModel.FindSum(transCtx, withdrawBuilder, "amount")
if sumErr != nil {
return errors.Wrapf(sumErr, "查询本月支付宝提现额度使用情况失败")
}
// 4.3 根据转账结果更新状态
switch transferResp.Status {
case "SUCCESS":
// 转账成功
if usedAmount+withdrawal.Amount > alipayQuota {
// 超出额度,不允许通过,保持待审核状态并提示原因
withdrawal.Status = 1
withdrawal.Remark = sql.NullString{
String: fmt.Sprintf("超过本月支付宝提现额度(限额:%.2f 元,已用:%.2f 元),请使用银行卡提现或调整金额", alipayQuota, usedAmount),
Valid: true,
}
if err := l.svcCtx.AgentWithdrawalModel.UpdateWithVersion(transCtx, session, withdrawal); err != nil {
return errors.Wrapf(err, "更新提现记录失败")
}
return errors.Wrapf(xerr.NewErrMsg("超过本月支付宝提现额度,无法通过该笔提现"), "")
}
// 支付宝提现:开发环境下做模拟,不调用真实支付宝转账
mockTransferStatus := "SUCCESS"
var transferResp struct {
Status string
SubCode string
}
if os.Getenv("ENV") == "development" {
transferResp.Status = mockTransferStatus
logx.Infof("【DEV】模拟支付宝转账成功withdrawNo=%s, amount=%.2f, payee=%s",
withdrawal.WithdrawNo, withdrawal.ActualAmount, withdrawal.PayeeAccount)
} else {
// 生产环境:同步调用支付宝转账接口
outBizNo := withdrawal.WithdrawNo
resp, err := l.svcCtx.AlipayService.AliTransfer(transCtx, withdrawal.PayeeAccount, withdrawal.PayeeName, withdrawal.ActualAmount, "代理提现", outBizNo)
if err != nil {
// 调用失败保持状态为待审核1只记录备注方便管理员重试
withdrawal.Status = 1 // 待审核
withdrawal.Remark = sql.NullString{String: fmt.Sprintf("支付宝转账调用失败: %v", err), Valid: true}
_ = l.svcCtx.AgentWithdrawalModel.UpdateWithVersion(transCtx, session, withdrawal)
return errors.Wrapf(err, "支付宝转账失败")
}
transferResp.Status = resp.Status
transferResp.SubCode = resp.SubCode
}
// 4.2 根据转账结果更新状态
switch transferResp.Status {
case "SUCCESS":
// 转账成功
withdrawal.Status = 5 // 提现成功
if err := l.svcCtx.AgentWithdrawalModel.UpdateWithVersion(transCtx, session, withdrawal); err != nil {
return errors.Wrapf(err, "更新提现记录失败")
}
// 更新钱包(解冻并扣除)
wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(transCtx, withdrawal.AgentId)
if err != nil {
return errors.Wrapf(err, "查询钱包失败")
}
wallet.FrozenBalance -= withdrawal.Amount
wallet.WithdrawnAmount += withdrawal.Amount
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(transCtx, session, wallet); err != nil {
return errors.Wrapf(err, "更新钱包失败")
}
// 更新扣税记录状态
taxBuilder := l.svcCtx.AgentWithdrawalTaxModel.SelectBuilder().
Where("withdrawal_id = ?", withdrawal.Id)
taxRecords, err := l.svcCtx.AgentWithdrawalTaxModel.FindAll(transCtx, taxBuilder, "")
if err == nil && len(taxRecords) > 0 {
taxRecord := taxRecords[0]
taxRecord.TaxStatus = 2 // 已扣税
taxRecord.TaxTime = lzUtils.TimeToNullTime(time.Now())
l.svcCtx.AgentWithdrawalTaxModel.UpdateWithVersion(transCtx, session, taxRecord)
}
case "FAIL":
// 转账失败:保持待审核状态,方便人工处理或重试
withdrawal.Status = 1 // 待审核
errorMsg := l.mapAlipayError(transferResp.SubCode)
withdrawal.Remark = sql.NullString{String: errorMsg, Valid: true}
if err := l.svcCtx.AgentWithdrawalModel.UpdateWithVersion(transCtx, session, withdrawal); err != nil {
return errors.Wrapf(err, "更新提现记录失败")
}
case "DEALING":
// 处理中同样保持待审核状态1由管理员后续确认
withdrawal.Status = 1
withdrawal.Remark = sql.NullString{String: "支付宝处理中,请稍后重试或联系平台", Valid: true}
if err := l.svcCtx.AgentWithdrawalModel.UpdateWithVersion(transCtx, session, withdrawal); err != nil {
return errors.Wrapf(err, "更新提现记录失败")
}
}
case 2:
// 银行卡提现:审核通过即视为提现成功(线下已/将立即打款)
withdrawal.Status = 5 // 提现成功
withdrawal.Remark = sql.NullString{String: req.Remark, Valid: true}
if err := l.svcCtx.AgentWithdrawalModel.UpdateWithVersion(transCtx, session, withdrawal); err != nil {
return errors.Wrapf(err, "更新提现记录失败")
}
@@ -96,7 +190,7 @@ func (l *AdminAuditWithdrawalLogic) AdminAuditWithdrawal(req *types.AdminAuditWi
// 更新扣税记录状态
taxBuilder := l.svcCtx.AgentWithdrawalTaxModel.SelectBuilder().
Where("withdrawal_id = ? AND del_state = ?", withdrawal.Id, globalkey.DelStateNo)
Where("withdrawal_id = ?", withdrawal.Id)
taxRecords, err := l.svcCtx.AgentWithdrawalTaxModel.FindAll(transCtx, taxBuilder, "")
if err == nil && len(taxRecords) > 0 {
taxRecord := taxRecords[0]
@@ -104,30 +198,9 @@ func (l *AdminAuditWithdrawalLogic) AdminAuditWithdrawal(req *types.AdminAuditWi
taxRecord.TaxTime = lzUtils.TimeToNullTime(time.Now())
l.svcCtx.AgentWithdrawalTaxModel.UpdateWithVersion(transCtx, session, taxRecord)
}
case "FAIL":
// 转账失败
withdrawal.Status = 6 // 提现失败
errorMsg := l.mapAlipayError(transferResp.SubCode)
withdrawal.Remark = sql.NullString{String: errorMsg, Valid: true}
if err := l.svcCtx.AgentWithdrawalModel.UpdateWithVersion(transCtx, session, withdrawal); err != nil {
return errors.Wrapf(err, "更新提现记录失败")
}
// 解冻余额
wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(transCtx, withdrawal.AgentId)
if err == nil {
wallet.FrozenBalance -= withdrawal.Amount
wallet.Balance += withdrawal.Amount
l.svcCtx.AgentWalletModel.UpdateWithVersion(transCtx, session, wallet)
}
case "DEALING":
// 处理中,保持提现中状态,后续通过轮询更新
// 状态已经是4提现中无需更新
}
} else if req.Status == 3 { // 审核拒绝
case 3: // 审核拒绝
// 4.1 更新提现记录状态为拒绝
withdrawal.Status = 3 // 审核拒绝
withdrawal.Remark = sql.NullString{String: req.Remark, Valid: true}

View File

@@ -49,6 +49,17 @@ func (l *AdminGetAgentWithdrawalListLogic) AdminGetAgentWithdrawalList(req *type
item.Remark = v.Remark.String
}
item.CreateTime = v.CreateTime.Format("2006-01-02 15:04:05")
// 如果是银行卡提现,填充银行卡信息
if v.WithdrawalType == 2 {
if v.BankCardNo.Valid {
item.BankCardNo = v.BankCardNo.String
}
if v.BankName.Valid {
item.BankName = v.BankName.String
}
}
items = append(items, item)
}
resp = &types.AdminGetAgentWithdrawalListResp{

View File

@@ -3,12 +3,11 @@ package agent
import (
"context"
"fmt"
"time"
"qnc-server/app/main/model"
"qnc-server/common/ctxdata"
"qnc-server/common/globalkey"
"qnc-server/common/xerr"
"qnc-server/pkg/lzkit/lzUtils"
"time"
"github.com/google/uuid"
"github.com/pkg/errors"
@@ -62,53 +61,138 @@ func (l *ApplyWithdrawalLogic) ApplyWithdrawal(req *types.ApplyWithdrawalReq) (r
return nil, errors.Wrapf(xerr.NewErrMsg("请先完成实名认证"), "")
}
// 3. 验证提现金额
// 3. 验证提现方式
if req.WithdrawalType != 1 && req.WithdrawalType != 2 {
return nil, errors.Wrapf(xerr.NewErrMsg("提现方式无效"), "")
}
// 4. 验证提现信息
if req.WithdrawalType == 1 {
// 支付宝提现:验证支付宝账号和姓名
if req.PayeeAccount == "" {
return nil, errors.Wrapf(xerr.NewErrMsg("请输入支付宝账号"), "")
}
if req.PayeeName == "" {
return nil, errors.Wrapf(xerr.NewErrMsg("请输入收款人姓名"), "")
}
} else if req.WithdrawalType == 2 {
// 银行卡提现:验证银行卡号、开户行和姓名
if req.BankCardNo == "" {
return nil, errors.Wrapf(xerr.NewErrMsg("请输入银行卡号"), "")
}
if req.BankName == "" {
return nil, errors.Wrapf(xerr.NewErrMsg("请输入开户行名称"), "")
}
if req.PayeeName == "" {
return nil, errors.Wrapf(xerr.NewErrMsg("请输入收款人姓名"), "")
}
}
// 5. 验证提现金额
if req.Amount <= 0 {
return nil, errors.Wrapf(xerr.NewErrMsg("提现金额必须大于0"), "")
}
// 4. 获取钱包信息
// 6. 获取钱包信息
wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(l.ctx, agent.Id)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询钱包失败, %v", err)
}
// 5. 验证余额
// 7. 验证余额(包括检查是否为负数)
if wallet.Balance < 0 {
return nil, errors.Wrapf(xerr.NewErrMsg(fmt.Sprintf("账户存在欠款,请先补足欠款后再申请提现,当前余额:%.2f", wallet.Balance)), "")
}
if wallet.Balance < req.Amount {
return nil, errors.Wrapf(xerr.NewErrMsg(fmt.Sprintf("余额不足,当前余额:%.2f", wallet.Balance)), "")
}
// 6. 计算税费
// 8. 支付宝月度提现额度校验(仅针对支付宝提现)
if req.WithdrawalType == 1 {
now := time.Now()
monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
nextMonthStart := monthStart.AddDate(0, 1, 0)
// 8.1 获取支付宝月度额度配置(默认 800 元)
alipayQuota := 800.0
if cfg, cfgErr := l.svcCtx.AgentConfigModel.FindOneByConfigKey(l.ctx, "alipay_month_quota"); cfgErr == nil {
if parsed, parseErr := l.parseFloat(cfg.ConfigValue); parseErr == nil && parsed > 0 {
alipayQuota = parsed
}
}
// 8.2 统计本月已申请/成功的支付宝提现金额status IN (1,5)),避免多次申请占用超额
withdrawBuilder := l.svcCtx.AgentWithdrawalModel.SelectBuilder().
Where("agent_id = ? AND withdrawal_type = ? AND status IN (1,5) AND create_time >= ? AND create_time < ?",
agent.Id, 1, monthStart, nextMonthStart)
usedAmount, sumErr := l.svcCtx.AgentWithdrawalModel.FindSum(l.ctx, withdrawBuilder, "amount")
if sumErr != nil {
return nil, errors.Wrapf(sumErr, "查询本月支付宝提现额度使用情况失败")
}
remainQuota := alipayQuota - usedAmount
if remainQuota <= 0 {
return nil, errors.Wrapf(
xerr.NewErrMsg(fmt.Sprintf("本月支付宝提现额度已用完(额度:%.2f 元),请使用银行卡提现", alipayQuota)),
"",
)
}
if req.Amount > remainQuota {
return nil, errors.Wrapf(
xerr.NewErrMsg(fmt.Sprintf("本月支付宝最高可提现 %.2f 元,请调整提现金额或使用银行卡提现", remainQuota)),
"",
)
}
}
// 9. 计算税费
yearMonth := int64(time.Now().Year()*100 + int(time.Now().Month()))
taxInfo, err := l.calculateTax(l.ctx, agent.Id, req.Amount, yearMonth)
if err != nil {
return nil, errors.Wrapf(err, "计算税费失败")
}
// 7. 生成提现单号
withdrawNo := fmt.Sprintf("WD%d%d", time.Now().Unix(), agent.Id)
// 10. 生成提现单号WD开头 + GenerateOutTradeNo生成的订单号确保总长度不超过32个字符
orderNo := l.svcCtx.AlipayService.GenerateOutTradeNo()
withdrawNo := "WD" + orderNo
// 确保总长度不超过32个字符
if len(withdrawNo) > 32 {
withdrawNo = withdrawNo[:32]
}
// 8. 使用事务处理提现申请
// 11. 使用事务处理提现申请
var withdrawalId string
err = l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
// 8.1 冻结余额
// 11.1 冻结余额
wallet.FrozenBalance += req.Amount
wallet.Balance -= req.Amount
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(transCtx, session, wallet); err != nil {
return errors.Wrapf(err, "冻结余额失败")
}
// 8.2 创建提现记录
// 11.2 创建提现记录
withdrawal := &model.AgentWithdrawal{
Id: uuid.New().String(),
AgentId: agent.Id,
WithdrawNo: withdrawNo,
PayeeAccount: req.PayeeAccount,
PayeeName: req.PayeeName,
Amount: req.Amount,
ActualAmount: taxInfo.ActualAmount,
TaxAmount: taxInfo.TaxAmount,
Status: 1, // 处理中(待审核)
Id: uuid.New().String(),
AgentId: agent.Id,
WithdrawNo: withdrawNo,
WithdrawalType: req.WithdrawalType,
PayeeAccount: req.PayeeAccount,
PayeeName: req.PayeeName,
Amount: req.Amount,
ActualAmount: taxInfo.ActualAmount,
TaxAmount: taxInfo.TaxAmount,
Status: 1, // 待审核
}
// 如果是银行卡提现,设置银行卡相关字段
if req.WithdrawalType == 2 {
withdrawal.BankCardNo = lzUtils.StringToNullString(req.BankCardNo)
withdrawal.BankName = lzUtils.StringToNullString(req.BankName)
// 银行卡提现时payee_account 可以存储银行卡号(便于查询),也可以留空
if req.PayeeAccount == "" {
withdrawal.PayeeAccount = req.BankCardNo
}
}
_, err := l.svcCtx.AgentWithdrawalModel.Insert(transCtx, session, withdrawal)
@@ -117,7 +201,7 @@ func (l *ApplyWithdrawalLogic) ApplyWithdrawal(req *types.ApplyWithdrawalReq) (r
}
withdrawalId = withdrawal.Id
// 8.3 创建扣税记录
// 11.3 创建扣税记录
taxRecord := &model.AgentWithdrawalTax{
AgentId: agent.Id,
WithdrawalId: withdrawalId,
@@ -167,8 +251,10 @@ func (l *ApplyWithdrawalLogic) calculateTax(ctx context.Context, agentId string,
}
// 查询本月已提现金额
// 注意FindAll 方法会自动添加 del_state = ? 条件,所以这里不需要手动添加
// 这里对 year_month 使用反引号包裹,避免与某些数据库版本/SQL 模式下的关键字冲突
builder := l.svcCtx.AgentWithdrawalTaxModel.SelectBuilder().
Where("agent_id = ? AND year_month = ? AND del_state = ?", agentId, yearMonth, globalkey.DelStateNo)
Where("agent_id = ? AND `year_month` = ?", agentId, yearMonth)
taxRecords, err := l.svcCtx.AgentWithdrawalTaxModel.FindAll(ctx, builder, "")
if err != nil {
return nil, errors.Wrapf(err, "查询月度提现记录失败")

View File

@@ -0,0 +1,30 @@
package agent
import (
"context"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type CheckFeatureWhitelistStatusLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCheckFeatureWhitelistStatusLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CheckFeatureWhitelistStatusLogic {
return &CheckFeatureWhitelistStatusLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CheckFeatureWhitelistStatusLogic) CheckFeatureWhitelistStatus(req *types.CheckFeatureWhitelistStatusReq) (resp *types.CheckFeatureWhitelistStatusResp, err error) {
// todo: add your logic here and delete this line
return
}

View File

@@ -0,0 +1,30 @@
package agent
import (
"context"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type CheckOrderAgentLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCheckOrderAgentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CheckOrderAgentLogic {
return &CheckOrderAgentLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CheckOrderAgentLogic) CheckOrderAgent(req *types.CheckOrderAgentReq) (resp *types.CheckOrderAgentResp, err error) {
// todo: add your logic here and delete this line
return
}

View File

@@ -0,0 +1,30 @@
package agent
import (
"context"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type CreateWhitelistOrderLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCreateWhitelistOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateWhitelistOrderLogic {
return &CreateWhitelistOrderLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CreateWhitelistOrderLogic) CreateWhitelistOrder(req *types.CreateWhitelistOrderReq) (resp *types.CreateWhitelistOrderResp, err error) {
// todo: add your logic here and delete this line
return
}

View File

@@ -0,0 +1,95 @@
package agent
import (
"context"
"qnc-server/app/main/model"
"qnc-server/common/ctxdata"
"qnc-server/common/xerr"
"github.com/pkg/errors"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetLastWithdrawalInfoLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetLastWithdrawalInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetLastWithdrawalInfoLogic {
return &GetLastWithdrawalInfoLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetLastWithdrawalInfoLogic) GetLastWithdrawalInfo(req *types.GetLastWithdrawalInfoReq) (resp *types.GetLastWithdrawalInfoResp, err error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户信息失败, %v", err)
}
// 1. 获取代理信息
agent, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrMsg("您不是代理"), "")
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败, %v", err)
}
// 2. 验证提现方式
if req.WithdrawalType != 1 && req.WithdrawalType != 2 {
return nil, errors.Wrapf(xerr.NewErrMsg("提现方式无效"), "")
}
// 3. 查询该代理最近一次该类型的提现记录
// 注意FindAll 方法会自动添加 del_state = ? 条件,所以这里不需要手动添加
builder := l.svcCtx.AgentWithdrawalModel.SelectBuilder().
Where("agent_id = ? AND withdrawal_type = ?", agent.Id, req.WithdrawalType).
OrderBy("create_time DESC").
Limit(1)
withdrawals, err := l.svcCtx.AgentWithdrawalModel.FindAll(l.ctx, builder, "")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询上次提现记录失败, %v", err)
}
// 4. 如果没有找到记录,返回空信息
if len(withdrawals) == 0 {
return &types.GetLastWithdrawalInfoResp{
WithdrawalType: req.WithdrawalType,
PayeeAccount: "",
PayeeName: "",
BankCardNo: "",
BankName: "",
}, nil
}
// 5. 组装响应
lastWithdrawal := withdrawals[0]
resp = &types.GetLastWithdrawalInfoResp{
WithdrawalType: lastWithdrawal.WithdrawalType,
PayeeAccount: lastWithdrawal.PayeeAccount,
PayeeName: lastWithdrawal.PayeeName,
BankCardNo: "",
BankName: "",
}
// 如果是银行卡提现,填充银行卡信息
if lastWithdrawal.WithdrawalType == 2 {
if lastWithdrawal.BankCardNo.Valid {
resp.BankCardNo = lastWithdrawal.BankCardNo.String
}
if lastWithdrawal.BankName.Valid {
resp.BankName = lastWithdrawal.BankName.String
}
}
return resp, nil
}

View File

@@ -0,0 +1,30 @@
package agent
import (
"context"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetWhitelistFeaturesLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetWhitelistFeaturesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetWhitelistFeaturesLogic {
return &GetWhitelistFeaturesLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetWhitelistFeaturesLogic) GetWhitelistFeatures(req *types.GetWhitelistFeaturesReq) (resp *types.GetWhitelistFeaturesResp, err error) {
// todo: add your logic here and delete this line
return
}

View File

@@ -0,0 +1,30 @@
package agent
import (
"context"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetWhitelistListLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetWhitelistListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetWhitelistListLogic {
return &GetWhitelistListLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetWhitelistListLogic) GetWhitelistList(req *types.GetWhitelistListReq) (resp *types.GetWhitelistListResp, err error) {
// todo: add your logic here and delete this line
return
}

View File

@@ -81,18 +81,31 @@ func (l *GetWithdrawalListLogic) GetWithdrawalList(req *types.GetWithdrawalListR
remark = withdrawal.Remark.String
}
list = append(list, types.WithdrawalItem{
Id: withdrawal.Id,
WithdrawalNo: withdrawal.WithdrawNo,
Amount: withdrawal.Amount,
TaxAmount: withdrawal.TaxAmount,
ActualAmount: withdrawal.ActualAmount,
Status: withdrawal.Status,
PayeeAccount: withdrawal.PayeeAccount,
PayeeName: withdrawal.PayeeName,
Remark: remark,
CreateTime: withdrawal.CreateTime.Format("2006-01-02 15:04:05"),
})
item := types.WithdrawalItem{
Id: withdrawal.Id,
WithdrawalNo: withdrawal.WithdrawNo,
WithdrawalType: withdrawal.WithdrawalType,
Amount: withdrawal.Amount,
TaxAmount: withdrawal.TaxAmount,
ActualAmount: withdrawal.ActualAmount,
Status: withdrawal.Status,
PayeeAccount: withdrawal.PayeeAccount,
PayeeName: withdrawal.PayeeName,
Remark: remark,
CreateTime: withdrawal.CreateTime.Format("2006-01-02 15:04:05"),
}
// 如果是银行卡提现,填充银行卡信息
if withdrawal.WithdrawalType == 2 {
if withdrawal.BankCardNo.Valid {
item.BankCardNo = withdrawal.BankCardNo.String
}
if withdrawal.BankName.Valid {
item.BankName = withdrawal.BankName.String
}
}
list = append(list, item)
}
return &types.GetWithdrawalListResp{

View File

@@ -0,0 +1,30 @@
package agent
import (
"context"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type OfflineFeatureLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewOfflineFeatureLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OfflineFeatureLogic {
return &OfflineFeatureLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *OfflineFeatureLogic) OfflineFeature(req *types.OfflineFeatureReq) (resp *types.OfflineFeatureResp, err error) {
// todo: add your logic here and delete this line
return
}

View File

@@ -282,6 +282,7 @@ type AdminGetAgentOrderListReq struct {
AgentId *string `form:"agent_id,optional"` // 代理ID可选
OrderId *string `form:"order_id,optional"` // 订单ID可选
ProcessStatus *int64 `form:"process_status,optional"` // 处理状态(可选)
OrderStatus *string `form:"order_status,optional"` // 订单状态可选pending-待支付paid-已支付refunded-已退款closed-已关闭failed-支付失败
}
type AdminGetAgentOrderListResp struct {
@@ -319,6 +320,7 @@ type AdminGetAgentRebateListReq struct {
AgentId *string `form:"agent_id,optional"` // 代理ID可选
SourceAgentId *string `form:"source_agent_id,optional"` // 来源代理ID可选
RebateType *int64 `form:"rebate_type,optional"` // 返佣类型(可选)
Status *int64 `form:"status,optional"` // 状态可选1=已发放2=已冻结3=已取消(已退款)
}
type AdminGetAgentRebateListResp struct {
@@ -898,7 +900,7 @@ type AdminUpgradeAgentReq struct {
}
type AdminUpgradeAgentResp struct {
Success bool `json:"success"`
Success bool `json:"success"` // 是否成功
}
type AdminUserInfoReq struct {
@@ -1008,7 +1010,8 @@ type AgentOrderListItem struct {
ActualBasePrice float64 `json:"actual_base_price"` // 实际底价
PriceCost float64 `json:"price_cost"` // 提价成本
AgentProfit float64 `json:"agent_profit"` // 代理收益
ProcessStatus int64 `json:"process_status"` // 处理状态
ProcessStatus int64 `json:"process_status"` // 处理状态(保留用于筛选,前端不显示)
OrderStatus string `json:"order_status"` // 订单状态pending-待支付paid-已支付refunded-已退款closed-已关闭failed-支付失败
CreateTime string `json:"create_time"` // 创建时间
}
@@ -1046,6 +1049,7 @@ type AgentRebateListItem struct {
OrderId string `json:"order_id"` // 订单ID
RebateType int64 `json:"rebate_type"` // 返佣类型
Amount float64 `json:"amount"` // 金额
Status int64 `json:"status"` // 状态1=已发放2=已冻结3=已取消(已退款)
CreateTime string `json:"create_time"` // 创建时间
}
@@ -1062,17 +1066,20 @@ type AgentUpgradeListItem struct {
}
type AgentWithdrawalListItem struct {
Id string `json:"id"` // 主键
AgentId string `json:"agent_id"` // 代理ID
WithdrawNo string `json:"withdraw_no"` // 提现单号
Amount float64 `json:"amount"` // 金额
TaxAmount float64 `json:"tax_amount"` // 税费金额
ActualAmount float64 `json:"actual_amount"` // 实际到账金额
Status int64 `json:"status"` // 状态
PayeeAccount string `json:"payee_account"` // 收款账户
PayeeName string `json:"payee_name"` // 收款人姓名
Remark string `json:"remark"` // 备注
CreateTime string `json:"create_time"` // 创建时间
Id string `json:"id"` // 主键
AgentId string `json:"agent_id"` // 代理ID
WithdrawNo string `json:"withdraw_no"` // 提现单号
Amount float64 `json:"amount"` // 金额
TaxAmount float64 `json:"tax_amount"` // 税费金额
ActualAmount float64 `json:"actual_amount"` // 实际到账金额
Status int64 `json:"status"` // 状态
WithdrawalType int64 `json:"withdrawal_type"` // 提现方式1=支付宝2=银行卡
PayeeAccount string `json:"payee_account"` // 收款账户(支付宝账号或银行卡号)
PayeeName string `json:"payee_name"` // 收款人姓名
BankCardNo string `json:"bank_card_no"` // 银行卡号(银行卡提现时使用)
BankName string `json:"bank_name"` // 开户行名称(银行卡提现时使用)
Remark string `json:"remark"` // 备注
CreateTime string `json:"create_time"` // 创建时间
}
type ApplyUpgradeReq struct {
@@ -1085,9 +1092,12 @@ type ApplyUpgradeResp struct {
}
type ApplyWithdrawalReq struct {
Amount float64 `json:"amount"` // 提现金额
PayeeAccount string `json:"payee_account"` // 收款账户
PayeeName string `json:"payee_name"` // 收款人姓名
Amount float64 `json:"amount"` // 提现金额
WithdrawalType int64 `json:"withdrawal_type"` // 提现方式1=支付宝2=银行卡
PayeeAccount string `json:"payee_account"` // 收款账户(支付宝账号或银行卡号)
PayeeName string `json:"payee_name"` // 收款人姓名
BankCardNo string `json:"bank_card_no,optional"` // 银行卡号(银行卡提现必填)
BankName string `json:"bank_name,optional"` // 开户行名称(银行卡提现必填)
}
type ApplyWithdrawalResp struct {
@@ -1133,6 +1143,27 @@ type BindMobileResp struct {
RefreshAfter int64 `json:"refreshAfter"`
}
type CheckFeatureWhitelistStatusReq struct {
IdCard string `form:"id_card"` // 身份证号
FeatureApiId string `form:"feature_api_id"` // Feature的API标识
QueryId string `form:"query_id,optional"` // 查询记录ID可选用于检查报告数据是否已删除
}
type CheckFeatureWhitelistStatusResp struct {
IsWhitelisted bool `json:"is_whitelisted"` // 是否在白名单中
WhitelistPrice float64 `json:"whitelist_price"` // 屏蔽价格单位如果为0表示不支持下架
FeatureId string `json:"feature_id"` // Feature的UUID
DataDeleted bool `json:"data_deleted"` // 报告数据是否已删除仅当提供了query_id时有效
}
type CheckOrderAgentReq struct {
OrderId string `form:"order_id"` // 订单ID
}
type CheckOrderAgentResp struct {
IsAgentOrder bool `json:"is_agent_order"` // 是否是当前代理推广的订单
}
type CommissionFreezeConfig struct {
Ratio float64 `json:"ratio"` // 佣金冻结比例例如0.1表示10%
Threshold float64 `json:"threshold"` // 佣金冻结阈值(订单单价达到此金额才触发冻结,单位:元)
@@ -1189,6 +1220,18 @@ type CreateRoleResp struct {
Id string `json:"id"` // 角色ID
}
type CreateWhitelistOrderReq struct {
IdCard string `json:"id_card"` // 身份证号(查询对象标识)
FeatureIds []string `json:"feature_ids"` // 要屏蔽的feature ID列表
OrderId string `json:"order_id,optional"` // 关联的查询订单ID可选
}
type CreateWhitelistOrderResp struct {
OrderId string `json:"order_id"` // 订单ID
OrderNo string `json:"order_no"` // 订单号
TotalAmount float64 `json:"total_amount"` // 总金额
}
type DeleteInviteCodeReq struct {
Id string `json:"id"` // 邀请码ID
}
@@ -1306,6 +1349,18 @@ type GetInviteLinkResp struct {
InviteLink string `json:"invite_link"` // 邀请链接
}
type GetLastWithdrawalInfoReq struct {
WithdrawalType int64 `form:"withdrawal_type"` // 提现方式1=支付宝2=银行卡
}
type GetLastWithdrawalInfoResp struct {
WithdrawalType int64 `json:"withdrawal_type"` // 提现方式
PayeeAccount string `json:"payee_account"` // 收款账户(支付宝账号或银行卡号)
PayeeName string `json:"payee_name"` // 收款人姓名
BankCardNo string `json:"bank_card_no"` // 银行卡号
BankName string `json:"bank_name"` // 开户行名称
}
type GetLevelPrivilegeResp struct {
Levels []LevelPrivilegeItem `json:"levels"`
UpgradeToGoldFee float64 `json:"upgrade_to_gold_fee"`
@@ -1404,16 +1459,18 @@ type GetRebateListResp struct {
}
type GetRevenueInfoResp struct {
Balance float64 `json:"balance"` // 可用余额
FrozenBalance float64 `json:"frozen_balance"` // 冻结余额
TotalEarnings float64 `json:"total_earnings"` // 累计收益(钱包总收益)
WithdrawnAmount float64 `json:"withdrawn_amount"` // 累计提现
CommissionTotal float64 `json:"commission_total"` // 佣金累计总收益(推广订单获得的佣金)
CommissionToday float64 `json:"commission_today"` // 佣金今日收益
CommissionMonth float64 `json:"commission_month"` // 佣金本月收益
RebateTotal float64 `json:"rebate_total"` // 返佣累计总收益(包括推广返佣和升级返佣)
RebateToday float64 `json:"rebate_today"` // 返佣今日收益
RebateMonth float64 `json:"rebate_month"` // 返佣本月收益
Balance float64 `json:"balance"` // 可用余额
FrozenBalance float64 `json:"frozen_balance"` // 冻结余额
TotalEarnings float64 `json:"total_earnings"` // 累计收益(钱包总收益)
WithdrawnAmount float64 `json:"withdrawn_amount"` // 累计提现
CommissionTotal float64 `json:"commission_total"` // 佣金累计总收益(推广订单获得的佣金)
CommissionToday float64 `json:"commission_today"` // 佣金今日收益
CommissionMonth float64 `json:"commission_month"` // 佣金本月收益
RebateTotal float64 `json:"rebate_total"` // 返佣累计总收益(包括推广返佣和升级返佣)
RebateToday float64 `json:"rebate_today"` // 返佣今日收益
RebateMonth float64 `json:"rebate_month"` // 返佣本月收益
AlipayMonthQuota float64 `json:"alipay_month_quota"` // 支付宝每月提现总额度
AlipayMonthUsed float64 `json:"alipay_month_used"` // 本月已使用的支付宝提现额度
}
type GetRoleDetailReq struct {
@@ -1518,6 +1575,24 @@ type GetUpgradeRebateListResp struct {
List []UpgradeRebateItem `json:"list"` // 列表
}
type GetWhitelistFeaturesReq struct {
}
type GetWhitelistFeaturesResp struct {
List []WhitelistFeatureItem `json:"list"` // 可屏蔽的feature列表
}
type GetWhitelistListReq struct {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"page_size"` // 每页数量
IdCard string `form:"id_card,optional"` // 身份证号(可选,用于筛选)
}
type GetWhitelistListResp struct {
Total int64 `json:"total"` // 总数
List []WhitelistItem `json:"list"` // 列表
}
type GetWithdrawalListReq struct {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"page_size"` // 每页数量
@@ -1650,6 +1725,17 @@ type NotificationListItem struct {
UpdateTime string `json:"update_time"` // 更新时间
}
type OfflineFeatureReq struct {
FeatureApiId string `json:"feature_api_id"` // Feature的API标识
QueryId string `json:"query_id"` // 查询记录IDQuery表的ID必选
}
type OfflineFeatureResp struct {
Success bool `json:"success"` // 是否已完成下架
NeedPay bool `json:"need_pay"` // 是否需要发起支付
Amount float64 `json:"amount"` // 需要支付的金额单位0表示无需支付
}
type OrderItem struct {
OrderNo string `json:"order_no"` // 订单号
ProductId string `json:"product_id"` // 产品ID
@@ -1695,7 +1781,6 @@ type PaymentReq struct {
Id string `json:"id"`
PayMethod string `json:"pay_method"` // 支付方式: wechat, alipay, appleiap, test(仅开发环境), test_empty(仅开发环境-空报告模式)
PayType string `json:"pay_type" validate:"required,oneof=query agent_vip agent_upgrade"`
Code string `json:"code,optional"` // 微信小程序/H5授权码用于自动绑定微信账号当用户未绑定微信时
}
type PaymentResp struct {
@@ -1767,11 +1852,13 @@ type ProductResponse struct {
}
type PromotionQueryItem struct {
Id string `json:"id"` // 查询ID
OrderId string `json:"order_id"` // 订单ID
ProductName string `json:"product_name"` // 产品名称
CreateTime string `json:"create_time"` // 创建时间
QueryState string `json:"query_state"` // 查询状态
Id string `json:"id"` // 查询ID
OrderId string `json:"order_id"` // 订单ID
ProductName string `json:"product_name"` // 产品名称
CreateTime string `json:"create_time"` // 创建时间
QueryState string `json:"query_state"` // 查询状态
Params map[string]interface{} `json:"params"` // 查询参数(已脱敏)
Price float64 `json:"price"` // 查询价格
}
type Query struct {
@@ -1931,6 +2018,7 @@ type RebateItem struct {
OrderNo string `json:"order_no"` // 订单号
RebateType int64 `json:"rebate_type"` // 返佣类型1=直接上级2=钻石上级3=黄金上级
Amount float64 `json:"amount"` // 返佣金额
Status int64 `json:"status"` // 状态1=已发放2=已冻结3=已取消(已退款)
CreateTime string `json:"create_time"` // 创建时间
}
@@ -1990,14 +2078,14 @@ type TeamMemberItem struct {
LevelName string `json:"level_name"` // 等级名称
Mobile string `json:"mobile"` // 手机号
CreateTime string `json:"create_time"` // 加入团队时间
TotalRebateAmount float64 `json:"total_rebate_amount"` // 返佣给我的总金额
TodayRebateAmount float64 `json:"today_rebate_amount"` // 返佣给我的今日金额
TodayInvites int64 `json:"today_invites"` // 邀请加入团队的今日人数
MonthInvites int64 `json:"month_invites"` // 邀请加入团队的本月人数
TotalInvites int64 `json:"total_invites"` // 邀请加入团队的总人数
TodayQueries int64 `json:"today_queries"` // 当日查询量
MonthQueries int64 `json:"month_queries"` // 本月查询量
TotalQueries int64 `json:"total_queries"` // 总查询量
TotalRebateAmount float64 `json:"total_rebate_amount"` // 返佣给我的总金额
TodayRebateAmount float64 `json:"today_rebate_amount"` // 返佣给我的今日金额
TotalInvites int64 `json:"total_invites"` // 邀请加入团队的总人数
TodayInvites int64 `json:"today_invites"` // 邀请加入团队的今日人数
MonthInvites int64 `json:"month_invites"` // 邀请加入团队的本月人数
IsDirect bool `json:"is_direct"` // 是否直接下级
}
@@ -2137,17 +2225,39 @@ type WXMiniAuthResp struct {
RefreshAfter int64 `json:"refreshAfter"`
}
type WhitelistFeatureItem struct {
FeatureId string `json:"feature_id"` // Feature的UUID
FeatureApiId string `json:"feature_api_id"` // Feature的API标识
FeatureName string `json:"feature_name"` // Feature的名称
WhitelistPrice float64 `json:"whitelist_price"` // 屏蔽价格(单位:元)
}
type WhitelistItem struct {
Id string `json:"id"` // 白名单记录ID
IdCard string `json:"id_card"` // 身份证号
FeatureId string `json:"feature_id"` // Feature的UUID
FeatureApiId string `json:"feature_api_id"` // Feature的API标识
FeatureName string `json:"feature_name"` // Feature的名称
Amount float64 `json:"amount"` // 费用
Status int64 `json:"status"` // 状态1=生效2=已失效
StatusText string `json:"status_text"` // 状态文本
CreateTime string `json:"create_time"` // 创建时间
}
type WithdrawalItem struct {
Id string `json:"id"` // 记录ID
WithdrawalNo string `json:"withdrawal_no"` // 提现单号
Amount float64 `json:"amount"` // 提现金额
TaxAmount float64 `json:"tax_amount"` // 税费金额
ActualAmount float64 `json:"actual_amount"` // 实际到账金额
Status int64 `json:"status"` // 状态1=待审核2=审核通过3=审核拒绝4=提现中5=提现成功6=提现失败
PayeeAccount string `json:"payee_account"` // 收款账户
PayeeName string `json:"payee_name"` // 收款人姓名
Remark string `json:"remark"` // 备注
CreateTime string `json:"create_time"` // 创建时间
Id string `json:"id"` // 记录ID
WithdrawalNo string `json:"withdrawal_no"` // 提现单号
Amount float64 `json:"amount"` // 提现金额
TaxAmount float64 `json:"tax_amount"` // 税费金额
ActualAmount float64 `json:"actual_amount"` // 实际到账金额
Status int64 `json:"status"` // 状态1=待审核2=审核通过3=审核拒绝4=提现中5=提现成功6=提现失败
WithdrawalType int64 `json:"withdrawal_type"` // 提现方式1=支付宝2=银行卡
PayeeAccount string `json:"payee_account"` // 收款账户(支付宝账号或银行卡号)
PayeeName string `json:"payee_name"` // 收款人姓名
BankCardNo string `json:"bank_card_no"` // 银行卡号(银行卡提现时填写)
BankName string `json:"bank_name"` // 开户行名称(银行卡提现时填写)
Remark string `json:"remark"` // 备注
CreateTime string `json:"create_time"` // 创建时间
}
type GetAppConfigResp struct {

View File

@@ -11,8 +11,6 @@ import (
"reflect"
"time"
"qnc-server/common/globalkey"
"github.com/Masterminds/squirrel"
"github.com/google/uuid"
"github.com/pkg/errors"
@@ -21,6 +19,7 @@ import (
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
"qnc-server/common/globalkey"
)
var (

View File

@@ -59,21 +59,24 @@ type (
}
AgentWithdrawal struct {
Id string `db:"id"`
AgentId string `db:"agent_id"`
WithdrawNo string `db:"withdraw_no"` // 提现单号
PayeeAccount string `db:"payee_account"` // 收款账户
PayeeName string `db:"payee_name"` // 收款人姓名
Amount float64 `db:"amount"` // 提现金额
ActualAmount float64 `db:"actual_amount"` // 实际到账金额(扣除税费后
TaxAmount float64 `db:"tax_amount"` // 税费金额
Status int64 `db:"status"` // 状态1=处理中2=成功3=失败
Remark sql.NullString `db:"remark"` // 备注
CreateTime time.Time `db:"create_time"` // 创建时间
UpdateTime time.Time `db:"update_time"` // 更新时间
DeleteTime sql.NullTime `db:"delete_time"` // 删除时间
DelState int64 `db:"del_state"` // 删除状态0=未删除1=已删除
Version int64 `db:"version"` // 版本号(乐观锁)
Id string `db:"id"`
AgentId string `db:"agent_id"`
WithdrawalType int64 `db:"withdrawal_type"` // 提现方式1=支付宝2=银行卡
WithdrawNo string `db:"withdraw_no"` // 提现单号
PayeeAccount string `db:"payee_account"` // 收款账户
BankCardNo sql.NullString `db:"bank_card_no"` // 银行卡号(银行卡提现时使用)
BankName sql.NullString `db:"bank_name"` // 开户行名称(银行卡提现时使用
PayeeName string `db:"payee_name"` // 收款人姓名
Amount float64 `db:"amount"` // 提现金额
ActualAmount float64 `db:"actual_amount"` // 实际到账金额(扣除税费后)
TaxAmount float64 `db:"tax_amount"` // 税费金额
Status int64 `db:"status"` // 状态1=处理中2=成功3=失败
Remark sql.NullString `db:"remark"` // 备注
CreateTime time.Time `db:"create_time"` // 创建时间
UpdateTime time.Time `db:"update_time"` // 更新时间
DeleteTime sql.NullTime `db:"delete_time"` // 删除时间
DelState int64 `db:"del_state"` // 删除状态0=未删除1=已删除
Version int64 `db:"version"` // 版本号(乐观锁)
}
)
@@ -90,11 +93,11 @@ func (m *defaultAgentWithdrawalModel) Insert(ctx context.Context, session sqlx.S
qncAgentWithdrawalIdKey := fmt.Sprintf("%s%v", cacheQncAgentWithdrawalIdPrefix, data.Id)
qncAgentWithdrawalWithdrawNoKey := fmt.Sprintf("%s%v", cacheQncAgentWithdrawalWithdrawNoPrefix, data.WithdrawNo)
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, agentWithdrawalRowsExpectAutoSet)
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, agentWithdrawalRowsExpectAutoSet)
if session != nil {
return session.ExecCtx(ctx, query, data.Id, data.AgentId, data.WithdrawNo, data.PayeeAccount, data.PayeeName, data.Amount, data.ActualAmount, data.TaxAmount, data.Status, data.Remark, data.DeleteTime, data.DelState, data.Version)
return session.ExecCtx(ctx, query, data.Id, data.AgentId, data.WithdrawalType, data.WithdrawNo, data.PayeeAccount, data.BankCardNo, data.BankName, data.PayeeName, data.Amount, data.ActualAmount, data.TaxAmount, data.Status, data.Remark, data.DeleteTime, data.DelState, data.Version)
}
return conn.ExecCtx(ctx, query, data.Id, data.AgentId, data.WithdrawNo, data.PayeeAccount, data.PayeeName, data.Amount, data.ActualAmount, data.TaxAmount, data.Status, data.Remark, data.DeleteTime, data.DelState, data.Version)
return conn.ExecCtx(ctx, query, data.Id, data.AgentId, data.WithdrawalType, data.WithdrawNo, data.PayeeAccount, data.BankCardNo, data.BankName, data.PayeeName, data.Amount, data.ActualAmount, data.TaxAmount, data.Status, data.Remark, data.DeleteTime, data.DelState, data.Version)
}, qncAgentWithdrawalIdKey, qncAgentWithdrawalWithdrawNoKey)
}
func (m *defaultAgentWithdrawalModel) insertUUID(data *AgentWithdrawal) {
@@ -161,9 +164,9 @@ func (m *defaultAgentWithdrawalModel) Update(ctx context.Context, session sqlx.S
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, agentWithdrawalRowsWithPlaceHolder)
if session != nil {
return session.ExecCtx(ctx, query, newData.AgentId, newData.WithdrawNo, newData.PayeeAccount, newData.PayeeName, newData.Amount, newData.ActualAmount, newData.TaxAmount, newData.Status, newData.Remark, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
return session.ExecCtx(ctx, query, newData.AgentId, newData.WithdrawalType, newData.WithdrawNo, newData.PayeeAccount, newData.BankCardNo, newData.BankName, newData.PayeeName, newData.Amount, newData.ActualAmount, newData.TaxAmount, newData.Status, newData.Remark, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
}
return conn.ExecCtx(ctx, query, newData.AgentId, newData.WithdrawNo, newData.PayeeAccount, newData.PayeeName, newData.Amount, newData.ActualAmount, newData.TaxAmount, newData.Status, newData.Remark, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
return conn.ExecCtx(ctx, query, newData.AgentId, newData.WithdrawalType, newData.WithdrawNo, newData.PayeeAccount, newData.BankCardNo, newData.BankName, newData.PayeeName, newData.Amount, newData.ActualAmount, newData.TaxAmount, newData.Status, newData.Remark, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
}, qncAgentWithdrawalIdKey, qncAgentWithdrawalWithdrawNoKey)
}
@@ -184,9 +187,9 @@ func (m *defaultAgentWithdrawalModel) UpdateWithVersion(ctx context.Context, ses
sqlResult, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("update %s set %s where `id` = ? and version = ? ", m.table, agentWithdrawalRowsWithPlaceHolder)
if session != nil {
return session.ExecCtx(ctx, query, newData.AgentId, newData.WithdrawNo, newData.PayeeAccount, newData.PayeeName, newData.Amount, newData.ActualAmount, newData.TaxAmount, newData.Status, newData.Remark, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
return session.ExecCtx(ctx, query, newData.AgentId, newData.WithdrawalType, newData.WithdrawNo, newData.PayeeAccount, newData.BankCardNo, newData.BankName, newData.PayeeName, newData.Amount, newData.ActualAmount, newData.TaxAmount, newData.Status, newData.Remark, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
}
return conn.ExecCtx(ctx, query, newData.AgentId, newData.WithdrawNo, newData.PayeeAccount, newData.PayeeName, newData.Amount, newData.ActualAmount, newData.TaxAmount, newData.Status, newData.Remark, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
return conn.ExecCtx(ctx, query, newData.AgentId, newData.WithdrawalType, newData.WithdrawNo, newData.PayeeAccount, newData.BankCardNo, newData.BankName, newData.PayeeName, newData.Amount, newData.ActualAmount, newData.TaxAmount, newData.Status, newData.Remark, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
}, qncAgentWithdrawalIdKey, qncAgentWithdrawalWithdrawNoKey)
if err != nil {
return err

View File

@@ -28,7 +28,7 @@ $tables = @(
# "admin_user_role",
# "agent",
# "agent_commission",
"agent_config"
# "agent_config"
# "agent_freeze_task",
# "agent_invite_code",
# "agent_invite_code_usage",
@@ -41,8 +41,8 @@ $tables = @(
# "agent_short_link",
# "agent_upgrade",
# "agent_wallet",
# "agent_withdrawal",
# "agent_withdrawal_tax",
"agent_withdrawal",
"agent_withdrawal_tax"
# "authorization_document",
# "example",
# "feature",
@@ -62,8 +62,9 @@ $tables = @(
# 为每个表生成模型
foreach ($table in $tables) {
Write-Host "正在生成表: $table" -ForegroundColor Green
goctl model mysql datasource -url="qnc:5vg67b3UNHu8@tcp(127.0.0.1:21001)/qnc" -table="$table" -dir="./model" --home="$HOME_DIR" -cache=true --style=goZero
# goctl model mysql datasource -url="qnc:5vg67b3UNHu8@tcp(127.0.0.1:21001)/qnc" -table="$table" -dir="./model" --home="$HOME_DIR" -cache=true --style=goZero
goctl model mysql datasource -url="qnc:5vg67b3UNHu8@tcp(127.0.0.1:21201)/qnc" -table="$table" -dir="./model" --home="$HOME_DIR" -cache=true --style=goZero
# 移动生成的文件到目标目录
if (Test-Path $OUTPUT_DIR) {
$sourceFiles = Get-ChildItem -Path $OUTPUT_DIR -File

View File

@@ -0,0 +1,26 @@
-- ============================================
-- 支付宝月度提现额度配置
-- ============================================
-- 说明:为代理系统增加支付宝每月提现额度配置,默认 800 元
-- 执行时间2026-01-06
-- ============================================
INSERT INTO
`agent_config` (
`id`,
`config_key`,
`config_value`,
`config_type`,
`description`
)
VALUES (
'f47ac10b-58cc-4372-a567-0e02b2c3d479',
'alipay_month_quota',
'800.00',
'withdrawal',
'支付宝每月提现额度(单位:元)'
)
ON DUPLICATE KEY UPDATE
`config_value` = VALUES(`config_value`),
`config_type` = VALUES(`config_type`),
`description` = VALUES(`description`);

View File

@@ -0,0 +1,36 @@
-- ============================================
-- 代理提现表 - 添加银行卡提现支持
-- ============================================
-- 说明:为 agent_withdrawal 表添加提现方式字段和银行卡相关字段
-- 执行时间2024-XX-XX
-- ============================================
-- 1. 添加提现方式字段1=支付宝2=银行卡)
ALTER TABLE `agent_withdrawal`
ADD COLUMN `withdrawal_type` tinyint NOT NULL DEFAULT 1 COMMENT '提现方式1=支付宝2=银行卡' AFTER `agent_id`;
-- 2. 添加银行卡号字段(银行卡提现时使用)
ALTER TABLE `agent_withdrawal`
ADD COLUMN `bank_card_no` varchar(100) DEFAULT NULL COMMENT '银行卡号(银行卡提现时使用)' AFTER `payee_account`;
-- 3. 添加开户行名称字段(银行卡提现时使用)
ALTER TABLE `agent_withdrawal`
ADD COLUMN `bank_name` varchar(100) DEFAULT NULL COMMENT '开户行名称(银行卡提现时使用)' AFTER `bank_card_no`;
-- 4. 为提现方式字段添加索引(用于按提现方式查询)
ALTER TABLE `agent_withdrawal`
ADD INDEX `idx_withdrawal_type` (`withdrawal_type`);
-- 5. 为提现方式和状态添加复合索引(用于后台审核查询)
ALTER TABLE `agent_withdrawal`
ADD INDEX `idx_type_status` (`withdrawal_type`, `status`);
-- ============================================
-- 说明:
-- 1. withdrawal_type 默认值为 1支付宝兼容历史数据
-- 2. bank_card_no 和 bank_name 为可选字段,支付宝提现时为空
-- 3. 对于支付宝提现payee_account 存储支付宝账号
-- 4. 对于银行卡提现payee_account 可以存储银行卡号(与 bank_card_no 保持一致),或留空
-- ============================================