This commit is contained in:
2025-12-09 18:55:28 +08:00
parent 8d00d67540
commit c23ab8338b
209 changed files with 5445 additions and 3963 deletions

View File

@@ -59,7 +59,6 @@ service main {
// 代理实名认证审核(已废弃:实名认证改为三要素核验,无需审核)
// @handler AdminAuditRealName
// post /real_name/audit (AdminAuditRealNameReq) returns (AdminAuditRealNameResp)
// 系统配置查询
@handler AdminGetAgentConfig
get /config returns (AdminGetAgentConfigResp)
@@ -93,17 +92,18 @@ type (
Mobile *string `form:"mobile,optional"` // 手机号(可选)
Region *string `form:"region,optional"` // 区域(可选)
Level *int64 `form:"level,optional"` // 等级(可选)
TeamLeaderId *int64 `form:"team_leader_id,optional"` // 团队首领ID可选
TeamLeaderId *string `form:"team_leader_id,optional"` // 团队首领ID可选
}
AgentListItem {
Id int64 `json:"id"` // 主键
UserId int64 `json:"user_id"` // 用户ID
Id string `json:"id"` // 主键
UserId string `json:"user_id"` // 用户ID
Level int64 `json:"level"` // 等级1=普通2=黄金3=钻石
LevelName string `json:"level_name"` // 等级名称
Region string `json:"region"` // 区域
Mobile string `json:"mobile"` // 手机号
WechatId string `json:"wechat_id"` // 微信号
TeamLeaderId int64 `json:"team_leader_id"` // 团队首领ID
TeamLeaderId string `json:"team_leader_id"` // 团队首领ID
AgentCode int64 `json:"agent_code"`
Balance float64 `json:"balance"` // 钱包余额
TotalEarnings float64 `json:"total_earnings"` // 累计收益
FrozenBalance float64 `json:"frozen_balance"` // 冻结余额
@@ -128,14 +128,14 @@ type (
AdminGetAgentLinkListReq {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *int64 `form:"agent_id,optional"` // 代理ID可选
ProductId *int64 `form:"product_id,optional"` // 产品ID可选
AgentId *string `form:"agent_id,optional"` // 代理ID可选
ProductId *string `form:"product_id,optional"` // 产品ID可选
LinkIdentifier *string `form:"link_identifier,optional"` // 推广码(可选)
}
AgentLinkListItem {
Id int64 `json:"id"` // 主键
AgentId int64 `json:"agent_id"` // 代理ID
ProductId int64 `json:"product_id"` // 产品ID
Id string `json:"id"` // 主键
AgentId string `json:"agent_id"` // 代理ID
ProductId string `json:"product_id"` // 产品ID
ProductName string `json:"product_name"` // 产品名称
SetPrice float64 `json:"set_price"` // 设定价格
ActualBasePrice float64 `json:"actual_base_price"` // 实际底价
@@ -148,17 +148,17 @@ type (
}
// 代理订单分页查询
AdminGetAgentOrderListReq {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *int64 `form:"agent_id,optional"` // 代理ID可选
OrderId *int64 `form:"order_id,optional"` // 订单ID可选
ProcessStatus *int64 `form:"process_status,optional"` // 处理状态(可选)
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *string `form:"agent_id,optional"` // 代理ID可选
OrderId *string `form:"order_id,optional"` // 订单ID可选
ProcessStatus *int64 `form:"process_status,optional"` // 处理状态(可选)
}
AgentOrderListItem {
Id int64 `json:"id"` // 主键
AgentId int64 `json:"agent_id"` // 代理ID
OrderId int64 `json:"order_id"` // 订单ID
ProductId int64 `json:"product_id"` // 产品ID
Id string `json:"id"` // 主键
AgentId string `json:"agent_id"` // 代理ID
OrderId string `json:"order_id"` // 订单ID
ProductId string `json:"product_id"` // 产品ID
ProductName string `json:"product_name"` // 产品名称
OrderAmount float64 `json:"order_amount"` // 订单金额
SetPrice float64 `json:"set_price"` // 设定价格
@@ -174,16 +174,16 @@ type (
}
// 代理佣金分页查询
AdminGetAgentCommissionListReq {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *int64 `form:"agent_id,optional"` // 代理ID可选
OrderId *int64 `form:"order_id,optional"` // 订单ID可选
Status *int64 `form:"status,optional"` // 状态(可选)
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *string `form:"agent_id,optional"` // 代理ID可选
OrderId *string `form:"order_id,optional"` // 订单ID可选
Status *int64 `form:"status,optional"` // 状态(可选)
}
AgentCommissionListItem {
Id int64 `json:"id"` // 主键
AgentId int64 `json:"agent_id"` // 代理ID
OrderId int64 `json:"order_id"` // 订单ID
Id string `json:"id"` // 主键
AgentId string `json:"agent_id"` // 代理ID
OrderId string `json:"order_id"` // 订单ID
ProductName string `json:"product_name"` // 产品名称
Amount float64 `json:"amount"` // 金额
Status int64 `json:"status"` // 状态
@@ -195,17 +195,17 @@ type (
}
// 代理返佣分页查询
AdminGetAgentRebateListReq {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *int64 `form:"agent_id,optional"` // 代理ID可选
SourceAgentId *int64 `form:"source_agent_id,optional"` // 来源代理ID可选
RebateType *int64 `form:"rebate_type,optional"` // 返佣类型(可选)
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *string `form:"agent_id,optional"` // 代理ID可选
SourceAgentId *string `form:"source_agent_id,optional"` // 来源代理ID可选
RebateType *int64 `form:"rebate_type,optional"` // 返佣类型(可选)
}
AgentRebateListItem {
Id int64 `json:"id"` // 主键
AgentId int64 `json:"agent_id"` // 获得返佣的代理ID
SourceAgentId int64 `json:"source_agent_id"` // 来源代理ID
OrderId int64 `json:"order_id"` // 订单ID
Id string `json:"id"` // 主键
AgentId string `json:"agent_id"` // 获得返佣的代理ID
SourceAgentId string `json:"source_agent_id"` // 来源代理ID
OrderId string `json:"order_id"` // 订单ID
RebateType int64 `json:"rebate_type"` // 返佣类型
Amount float64 `json:"amount"` // 金额
CreateTime string `json:"create_time"` // 创建时间
@@ -216,15 +216,15 @@ type (
}
// 代理升级记录分页查询
AdminGetAgentUpgradeListReq {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *int64 `form:"agent_id,optional"` // 代理ID可选
UpgradeType *int64 `form:"upgrade_type,optional"` // 升级类型(可选)
Status *int64 `form:"status,optional"` // 状态(可选)
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *string `form:"agent_id,optional"` // 代理ID可选
UpgradeType *int64 `form:"upgrade_type,optional"` // 升级类型(可选)
Status *int64 `form:"status,optional"` // 状态(可选)
}
AgentUpgradeListItem {
Id int64 `json:"id"` // 主键
AgentId int64 `json:"agent_id"` // 代理ID
Id string `json:"id"` // 主键
AgentId string `json:"agent_id"` // 代理ID
FromLevel int64 `json:"from_level"` // 原等级
ToLevel int64 `json:"to_level"` // 目标等级
UpgradeType int64 `json:"upgrade_type"` // 升级类型
@@ -241,13 +241,13 @@ type (
AdminGetAgentWithdrawalListReq {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *int64 `form:"agent_id,optional"` // 代理ID可选
AgentId *string `form:"agent_id,optional"` // 代理ID可选
Status *int64 `form:"status,optional"` // 状态(可选)
WithdrawNo *string `form:"withdraw_no,optional"` // 提现单号(可选)
}
AgentWithdrawalListItem {
Id int64 `json:"id"` // 主键
AgentId int64 `json:"agent_id"` // 代理ID
Id string `json:"id"` // 主键
AgentId string `json:"agent_id"` // 代理ID
WithdrawNo string `json:"withdraw_no"` // 提现单号
Amount float64 `json:"amount"` // 金额
TaxAmount float64 `json:"tax_amount"` // 税费金额
@@ -264,7 +264,7 @@ type (
}
// 代理提现审核
AdminAuditWithdrawalReq {
WithdrawalId int64 `json:"withdrawal_id"` // 提现记录ID
WithdrawalId string `json:"withdrawal_id"` // 提现记录ID
Status int64 `json:"status"` // 审核状态2=通过3=拒绝
Remark string `json:"remark"` // 备注
}
@@ -273,20 +273,20 @@ type (
}
// 代理实名认证分页查询
AdminGetAgentRealNameListReq {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *int64 `form:"agent_id,optional"` // 代理ID可选
Status *int64 `form:"status,optional"` // 状态可选1=未验证2=已通过
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *string `form:"agent_id,optional"` // 代理ID可选
Status *int64 `form:"status,optional"` // 状态可选1=未验证2=已通过
}
AgentRealNameListItem {
Id int64 `json:"id"` // 主键
AgentId int64 `json:"agent_id"` // 代理ID
Name string `json:"name"` // 姓名
IdCard string `json:"id_card"` // 身份证号
Mobile string `json:"mobile"` // 手机号
Status int64 `json:"status"` // 状态1=未验证2=已通过verify_time不为空表示已通过
VerifyTime string `json:"verify_time"` // 验证时间(三要素核验通过时间)
CreateTime string `json:"create_time"` // 创建时间
Id string `json:"id"` // 主键
AgentId string `json:"agent_id"` // 代理ID
Name string `json:"name"` // 姓名
IdCard string `json:"id_card"` // 身份证号
Mobile string `json:"mobile"` // 手机号
Status int64 `json:"status"` // 状态1=未验证2=已通过verify_time不为空表示已通过
VerifyTime string `json:"verify_time"` // 验证时间(三要素核验通过时间)
CreateTime string `json:"create_time"` // 创建时间
}
AdminGetAgentRealNameListResp {
Total int64 `json:"total"` // 总数
@@ -303,14 +303,16 @@ type (
}
// 系统配置查询(价格配置已移除,改为产品配置表管理)
AdminGetAgentConfigResp {
LevelBonus LevelBonusConfig `json:"level_bonus"` // 等级加成配置
UpgradeFee UpgradeFeeConfig `json:"upgrade_fee"` // 升级费用配置
UpgradeRebate UpgradeRebateConfig `json:"upgrade_rebate"` // 升级返佣配置
DirectParentRebate DirectParentRebateConfig `json:"direct_parent_rebate"` // 直接上级返佣配置
MaxGoldRebateAmount float64 `json:"max_gold_rebate_amount"` // 黄金代理最大返佣金额
CommissionFreeze CommissionFreezeConfig `json:"commission_freeze"` // 佣金冻结配置
TaxRate float64 `json:"tax_rate"` // 税率
TaxExemptionAmount float64 `json:"tax_exemption_amount"` // 免税额度
LevelBonus LevelBonusConfig `json:"level_bonus"` // 等级加成配置
UpgradeFee UpgradeFeeConfig `json:"upgrade_fee"` // 升级费用配置
UpgradeRebate UpgradeRebateConfig `json:"upgrade_rebate"` // 升级返佣配置
DirectParentRebate DirectParentRebateConfig `json:"direct_parent_rebate"` // 直接上级返佣配置
MaxGoldRebateAmount float64 `json:"max_gold_rebate_amount"` // 黄金代理最大返佣金额
CommissionFreeze CommissionFreezeConfig `json:"commission_freeze"` // 佣金冻结配置
TaxRate float64 `json:"tax_rate"` // 税率
TaxExemptionAmount float64 `json:"tax_exemption_amount"` // 免税额度
GoldMaxUpliftAmount float64 `json:"gold_max_uplift_amount"`
DiamondMaxUpliftAmount float64 `json:"diamond_max_uplift_amount"`
}
LevelBonusConfig {
Diamond int64 `json:"diamond"` // 钻石加成0
@@ -320,7 +322,6 @@ type (
UpgradeFeeConfig {
NormalToGold float64 `json:"normal_to_gold"` // 普通→黄金199
NormalToDiamond float64 `json:"normal_to_diamond"` // 普通→钻石980
GoldToDiamond float64 `json:"gold_to_diamond"` // 黄金→钻石980
}
UpgradeRebateConfig {
NormalToGoldRebate float64 `json:"normal_to_gold_rebate"` // 普通→黄金返佣139
@@ -332,34 +333,36 @@ type (
Normal float64 `json:"normal"` // 直接上级是普通的返佣金额2元
}
CommissionFreezeConfig {
Ratio float64 `json:"ratio"` // 佣金冻结比例例如0.1表示10%
Threshold float64 `json:"threshold"` // 佣金冻结阈值(订单单价达到此金额才触发冻结,单位:元)
Days int64 `json:"days"` // 佣金冻结解冻天数单位例如30表示30天后解冻
Ratio float64 `json:"ratio"` // 佣金冻结比例例如0.1表示10%
Threshold float64 `json:"threshold"` // 佣金冻结阈值(订单单价达到此金额才触发冻结,单位:元)
Days int64 `json:"days"` // 佣金冻结解冻天数单位例如30表示30天后解冻
}
// 系统配置更新(价格配置已移除,改为产品配置表管理)
AdminUpdateAgentConfigReq {
LevelBonus *LevelBonusConfig `json:"level_bonus,optional"` // 等级加成配置
UpgradeFee *UpgradeFeeConfig `json:"upgrade_fee,optional"` // 升级费用配置
UpgradeRebate *UpgradeRebateConfig `json:"upgrade_rebate,optional"` // 升级返佣配置
DirectParentRebate *DirectParentRebateConfig `json:"direct_parent_rebate,optional"` // 直接上级返佣配置
MaxGoldRebateAmount *float64 `json:"max_gold_rebate_amount,optional"` // 黄金代理最大返佣金额
CommissionFreeze *CommissionFreezeConfig `json:"commission_freeze,optional"` // 佣金冻结配置
TaxRate *float64 `json:"tax_rate,optional"` // 税率
TaxExemptionAmount *float64 `json:"tax_exemption_amount,optional"` // 免税额度
LevelBonus *LevelBonusConfig `json:"level_bonus,optional"` // 等级加成配置
UpgradeFee *UpgradeFeeConfig `json:"upgrade_fee,optional"` // 升级费用配置
UpgradeRebate *UpgradeRebateConfig `json:"upgrade_rebate,optional"` // 升级返佣配置
DirectParentRebate *DirectParentRebateConfig `json:"direct_parent_rebate,optional"` // 直接上级返佣配置
MaxGoldRebateAmount *float64 `json:"max_gold_rebate_amount,optional"` // 黄金代理最大返佣金额
CommissionFreeze *CommissionFreezeConfig `json:"commission_freeze,optional"` // 佣金冻结配置
TaxRate *float64 `json:"tax_rate,optional"` // 税率
TaxExemptionAmount *float64 `json:"tax_exemption_amount,optional"` // 免税额度
GoldMaxUpliftAmount *float64 `json:"gold_max_uplift_amount,optional"`
DiamondMaxUpliftAmount *float64 `json:"diamond_max_uplift_amount,optional"`
}
AdminUpdateAgentConfigResp {
Success bool `json:"success"`
}
// 产品配置分页查询
AdminGetAgentProductConfigListReq {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
ProductId *int64 `form:"product_id,optional"` // 产品ID可选
ProductName *string `form:"product_name,optional"` // 产品名称(可选,用于搜索)
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
ProductId *string `form:"product_id,optional"` // 产品ID可选
ProductName *string `form:"product_name,optional"` // 产品名称(可选,用于搜索)
}
AgentProductConfigItem {
Id int64 `json:"id"` // 主键
ProductId int64 `json:"product_id"` // 产品ID
Id string `json:"id"` // 主键
ProductId string `json:"product_id"` // 产品ID
ProductName string `json:"product_name"` // 产品名称
BasePrice float64 `json:"base_price"` // 基础底价
PriceRangeMin float64 `json:"price_range_min"` // 最低定价
@@ -374,11 +377,11 @@ type (
}
// 产品配置更新
AdminUpdateAgentProductConfigReq {
Id int64 `json:"id"` // 主键
BasePrice float64 `json:"base_price"` // 基础底价
PriceRangeMax float64 `json:"price_range_max"` // 最高定价(对应数据库 system_max_price
PriceThreshold *float64 `json:"price_threshold,optional"` // 提价标准阈值(可选)
PriceFeeRate *float64 `json:"price_fee_rate,optional"` // 提价手续费比例(可选)
Id string `json:"id"` // 主键
BasePrice float64 `json:"base_price"` // 基础底价
PriceRangeMax float64 `json:"price_range_max"` // 最高定价(对应数据库 system_max_price
PriceThreshold *float64 `json:"price_threshold,optional"` // 提价标准阈值(可选)
PriceFeeRate *float64 `json:"price_fee_rate,optional"` // 提价手续费比例(可选)
}
AdminUpdateAgentProductConfigResp {
Success bool `json:"success"`
@@ -397,19 +400,19 @@ type (
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
Code *string `form:"code,optional"` // 邀请码(可选)
AgentId *int64 `form:"agent_id,optional"` // 发放代理ID可选NULL表示平台发放
AgentId *string `form:"agent_id,optional"` // 发放代理ID可选NULL表示平台发放
TargetLevel *int64 `form:"target_level,optional"` // 目标等级(可选)
Status *int64 `form:"status,optional"` // 状态(可选)
}
InviteCodeListItem {
Id int64 `json:"id"` // 主键
Id string `json:"id"` // 主键
Code string `json:"code"` // 邀请码
AgentId int64 `json:"agent_id"` // 发放代理ID0表示平台发放
AgentId string `json:"agent_id"` // 发放代理ID0表示平台发放
AgentMobile string `json:"agent_mobile"` // 发放代理手机号
TargetLevel int64 `json:"target_level"` // 目标等级
Status int64 `json:"status"` // 状态0=未使用1=已使用2=已失效
UsedUserId int64 `json:"used_user_id"` // 使用用户ID
UsedAgentId int64 `json:"used_agent_id"` // 使用代理ID
UsedUserId string `json:"used_user_id"` // 使用用户ID
UsedAgentId string `json:"used_agent_id"` // 使用代理ID
UsedTime string `json:"used_time"` // 使用时间
ExpireTime string `json:"expire_time"` // 过期时间
Remark string `json:"remark"` // 备注

View File

@@ -25,7 +25,7 @@ type (
// API信息
AdminApiInfo {
Id int64 `json:"id"`
Id string `json:"id"`
ApiName string `json:"api_name"`
ApiCode string `json:"api_code"`
Method string `json:"method"`
@@ -38,7 +38,7 @@ type (
// API详情请求
AdminGetApiDetailReq {
Id int64 `path:"id"`
Id string `path:"id"`
}
// API详情响应
@@ -58,12 +58,12 @@ type (
// 创建API响应
AdminCreateApiResp {
Id int64 `json:"id"`
Id string `json:"id"`
}
// 更新API请求
AdminUpdateApiReq {
Id int64 `path:"id"`
Id string `path:"id"`
ApiName string `json:"api_name"`
ApiCode string `json:"api_code"`
Method string `json:"method"`
@@ -79,7 +79,7 @@ type (
// 删除API请求
AdminDeleteApiReq {
Id int64 `path:"id"`
Id string `path:"id"`
}
// 删除API响应
@@ -89,7 +89,7 @@ type (
// 批量更新API状态请求
AdminBatchUpdateApiStatusReq {
Ids []int64 `json:"ids"`
Ids []string `json:"ids"`
Status int64 `json:"status"`
}

View File

@@ -49,23 +49,23 @@ type (
Name string `json:"name"` // 描述
}
// 创建功能响应
AdminCreateFeatureResp {
Id int64 `json:"id"` // 功能ID
}
AdminCreateFeatureResp {
Id string `json:"id"` // 功能ID
}
// 更新功能请求
AdminUpdateFeatureReq {
Id int64 `path:"id"` // 功能ID
ApiId *string `json:"api_id,optional"` // API标识
Name *string `json:"name,optional"` // 描述
}
AdminUpdateFeatureReq {
Id string `path:"id"` // 功能ID
ApiId *string `json:"api_id,optional"` // API标识
Name *string `json:"name,optional"` // 描述
}
// 更新功能响应
AdminUpdateFeatureResp {
Success bool `json:"success"` // 是否成功
}
// 删除功能请求
AdminDeleteFeatureReq {
Id int64 `path:"id"` // 功能ID
}
AdminDeleteFeatureReq {
Id string `path:"id"` // 功能ID
}
// 删除功能响应
AdminDeleteFeatureResp {
Success bool `json:"success"` // 是否成功
@@ -78,9 +78,9 @@ type (
Name *string `form:"name,optional"` // 描述
}
// 功能列表项
FeatureListItem {
Id int64 `json:"id"` // 功能ID
ApiId string `json:"api_id"` // API标识
FeatureListItem {
Id string `json:"id"` // 功能ID
ApiId string `json:"api_id"` // API标识
Name string `json:"name"` // 描述
CreateTime string `json:"create_time"` // 创建时间
UpdateTime string `json:"update_time"` // 更新时间
@@ -91,38 +91,38 @@ type (
Items []FeatureListItem `json:"items"` // 列表数据
}
// 获取功能详情请求
AdminGetFeatureDetailReq {
Id int64 `path:"id"` // 功能ID
}
AdminGetFeatureDetailReq {
Id string `path:"id"` // 功能ID
}
// 获取功能详情响应
AdminGetFeatureDetailResp {
Id int64 `json:"id"` // 功能ID
ApiId string `json:"api_id"` // API标识
AdminGetFeatureDetailResp {
Id string `json:"id"` // 功能ID
ApiId string `json:"api_id"` // API标识
Name string `json:"name"` // 描述
CreateTime string `json:"create_time"` // 创建时间
UpdateTime string `json:"update_time"` // 更新时间
}
// 配置功能示例数据请求
AdminConfigFeatureExampleReq {
FeatureId int64 `json:"feature_id"` // 功能ID
Data string `json:"data"` // 示例数据JSON
}
AdminConfigFeatureExampleReq {
FeatureId string `json:"feature_id"` // 功能ID
Data string `json:"data"` // 示例数据JSON
}
// 配置功能示例数据响应
AdminConfigFeatureExampleResp {
Success bool `json:"success"` // 是否成功
}
// 查看功能示例数据请求
AdminGetFeatureExampleReq {
FeatureId int64 `path:"feature_id"` // 功能ID
}
AdminGetFeatureExampleReq {
FeatureId string `path:"feature_id"` // 功能ID
}
// 查看功能示例数据响应
AdminGetFeatureExampleResp {
Id int64 `json:"id"` // 示例数据ID
FeatureId int64 `json:"feature_id"` // 功能ID
ApiId string `json:"api_id"` // API标识
Data string `json:"data"` // 示例数据JSON
CreateTime string `json:"create_time"` // 创建时间
UpdateTime string `json:"update_time"` // 更新时间
}
AdminGetFeatureExampleResp {
Id string `json:"id"` // 示例数据ID
FeatureId string `json:"feature_id"` // 功能ID
ApiId string `json:"api_id"` // API标识
Data string `json:"data"` // 示例数据JSON
CreateTime string `json:"create_time"` // 创建时间
UpdateTime string `json:"update_time"` // 更新时间
}
)

View File

@@ -54,14 +54,14 @@ type (
}
// 创建产品响应
AdminCreateProductResp {
Id int64 `json:"id"` // 产品ID
}
AdminCreateProductResp {
Id string `json:"id"` // 产品ID
}
// 更新产品请求
AdminUpdateProductReq {
Id int64 `path:"id"` // 产品ID
ProductName *string `json:"product_name,optional"` // 服务名
AdminUpdateProductReq {
Id string `path:"id"` // 产品ID
ProductName *string `json:"product_name,optional"` // 服务名
ProductEn *string `json:"product_en,optional"` // 英文名
Description *string `json:"description,optional"` // 描述
Notes *string `json:"notes,optional"` // 备注
@@ -75,9 +75,9 @@ type (
}
// 删除产品请求
AdminDeleteProductReq {
Id int64 `path:"id"` // 产品ID
}
AdminDeleteProductReq {
Id string `path:"id"` // 产品ID
}
// 删除产品响应
AdminDeleteProductResp {
@@ -93,9 +93,9 @@ type (
}
// 产品列表项
ProductListItem {
Id int64 `json:"id"` // 产品ID
ProductName string `json:"product_name"` // 服务名
ProductListItem {
Id string `json:"id"` // 产品ID
ProductName string `json:"product_name"` // 服务名
ProductEn string `json:"product_en"` // 英文名
Description string `json:"description"` // 描述
Notes string `json:"notes"` // 备注
@@ -112,14 +112,14 @@ type (
}
// 获取产品详情请求
AdminGetProductDetailReq {
Id int64 `path:"id"` // 产品ID
}
AdminGetProductDetailReq {
Id string `path:"id"` // 产品ID
}
// 获取产品详情响应
AdminGetProductDetailResp {
Id int64 `json:"id"` // 产品ID
ProductName string `json:"product_name"` // 服务名
AdminGetProductDetailResp {
Id string `json:"id"` // 产品ID
ProductName string `json:"product_name"` // 服务名
ProductEn string `json:"product_en"` // 英文名
Description string `json:"description"` // 描述
Notes string `json:"notes"` // 备注
@@ -130,23 +130,23 @@ type (
}
// 获取产品功能列表请求
AdminGetProductFeatureListReq {
ProductId int64 `path:"product_id"` // 产品ID
}
AdminGetProductFeatureListReq {
ProductId string `path:"product_id"` // 产品ID
}
// 获取产品功能列表响应Item
AdminGetProductFeatureListResp {
Id int64 `json:"id"` // 关联ID
ProductId int64 `json:"product_id"` // 产品ID
FeatureId int64 `json:"feature_id"` // 功能ID
ApiId string `json:"api_id"` // API标识
Name string `json:"name"` // 功能描述
Sort int64 `json:"sort"` // 排序
Enable int64 `json:"enable"` // 是否启用
IsImportant int64 `json:"is_important"` // 是否重要
CreateTime string `json:"create_time"` // 创建时间
UpdateTime string `json:"update_time"` // 更新时间
}
AdminGetProductFeatureListResp {
Id string `json:"id"` // 关联ID
ProductId string `json:"product_id"` // 产品ID
FeatureId string `json:"feature_id"` // 功能ID
ApiId string `json:"api_id"` // API标识
Name string `json:"name"` // 功能描述
Sort int64 `json:"sort"` // 排序
Enable int64 `json:"enable"` // 是否启用
IsImportant int64 `json:"is_important"` // 是否重要
CreateTime string `json:"create_time"` // 创建时间
UpdateTime string `json:"update_time"` // 更新时间
}
// // 获取产品功能列表响应
// AdminGetProductFeatureListResp {
@@ -154,21 +154,21 @@ type (
// }
// 产品功能关联项
ProductFeatureItem {
FeatureId int64 `json:"feature_id"` // 功能ID
Sort int64 `json:"sort"` // 排序
Enable int64 `json:"enable"` // 是否启用
IsImportant int64 `json:"is_important"` // 是否重要
}
ProductFeatureItem {
FeatureId string `json:"feature_id"` // 功能ID
Sort int64 `json:"sort"` // 排序
Enable int64 `json:"enable"` // 是否启用
IsImportant int64 `json:"is_important"` // 是否重要
}
// 更新产品功能关联请求(批量)
AdminUpdateProductFeaturesReq {
ProductId int64 `path:"product_id"` // 产品ID
Features []ProductFeatureItem `json:"features"` // 功能列表
}
AdminUpdateProductFeaturesReq {
ProductId string `path:"product_id"` // 产品ID
Features []ProductFeatureItem `json:"features"` // 功能列表
}
// 更新产品功能关联响应
AdminUpdateProductFeaturesResp {
Success bool `json:"success"` // 是否成功
}
)
)

View File

@@ -33,14 +33,14 @@ service main {
put /cleanup/config (AdminUpdateQueryCleanupConfigReq) returns (AdminUpdateQueryCleanupConfigResp)
}
type AdminGetQueryDetailByOrderIdReq {
OrderId int64 `path:"order_id"`
type AdminGetQueryDetailByOrderIdReq {
OrderId string `path:"order_id"`
}
type AdminGetQueryDetailByOrderIdResp {
Id int64 `json:"id"` // 主键ID
OrderId int64 `json:"order_id"` // 订单ID
UserId int64 `json:"user_id"` // 用户ID
type AdminGetQueryDetailByOrderIdResp {
Id string `json:"id"` // 主键ID
OrderId string `json:"order_id"` // 订单ID
UserId string `json:"user_id"` // 用户ID
ProductName string `json:"product_name"` // 产品ID
QueryParams map[string]interface{} `json:"query_params"`
QueryData []AdminQueryItem `json:"query_data"`
@@ -68,8 +68,8 @@ type AdminGetQueryCleanupLogListResp {
Items []QueryCleanupLogItem `json:"items"` // 列表
}
type QueryCleanupLogItem {
Id int64 `json:"id"` // 主键ID
type QueryCleanupLogItem {
Id string `json:"id"` // 主键ID
CleanupTime string `json:"cleanup_time"` // 清理时间
CleanupBefore string `json:"cleanup_before"` // 清理截止时间
Status int64 `json:"status"` // 状态1-成功2-失败
@@ -80,8 +80,8 @@ type QueryCleanupLogItem {
}
// 清理详情相关请求响应定义
type AdminGetQueryCleanupDetailListReq {
LogId int64 `path:"log_id"` // 清理日志ID
type AdminGetQueryCleanupDetailListReq {
LogId string `path:"log_id"` // 清理日志ID
Page int64 `form:"page,default=1"` // 页码
PageSize int64 `form:"page_size,default=20"` // 每页数量
}
@@ -91,12 +91,12 @@ type AdminGetQueryCleanupDetailListResp {
Items []QueryCleanupDetailItem `json:"items"` // 列表
}
type QueryCleanupDetailItem {
Id int64 `json:"id"` // 主键ID
CleanupLogId int64 `json:"cleanup_log_id"` // 清理日志ID
QueryId int64 `json:"query_id"` // 查询ID
OrderId int64 `json:"order_id"` // 订单ID
UserId int64 `json:"user_id"` // 用户ID
type QueryCleanupDetailItem {
Id string `json:"id"` // 主键ID
CleanupLogId string `json:"cleanup_log_id"` // 清理日志ID
QueryId string `json:"query_id"` // 查询ID
OrderId string `json:"order_id"` // 订单ID
UserId string `json:"user_id"` // 用户ID
ProductName string `json:"product_name"` // 产品名称
QueryState string `json:"query_state"` // 查询状态
CreateTimeOld string `json:"create_time_old"` // 原创建时间
@@ -112,8 +112,8 @@ type AdminGetQueryCleanupConfigListResp {
Items []QueryCleanupConfigItem `json:"items"` // 配置列表
}
type QueryCleanupConfigItem {
Id int64 `json:"id"` // 主键ID
type QueryCleanupConfigItem {
Id string `json:"id"` // 主键ID
ConfigKey string `json:"config_key"` // 配置键
ConfigValue string `json:"config_value"` // 配置值
ConfigDesc string `json:"config_desc"` // 配置描述
@@ -122,12 +122,12 @@ type QueryCleanupConfigItem {
UpdateTime string `json:"update_time"` // 更新时间
}
type AdminUpdateQueryCleanupConfigReq {
Id int64 `json:"id"` // 主键ID
type AdminUpdateQueryCleanupConfigReq {
Id string `json:"id"` // 主键ID
ConfigValue string `json:"config_value"` // 配置值
Status int64 `json:"status"` // 状态1-启用0-禁用
}
type AdminUpdateQueryCleanupConfigResp {
Success bool `json:"success"` // 是否成功
}
}

View File

@@ -10,7 +10,7 @@ info(
type (
// 获取角色API权限列表请求
AdminGetRoleApiListReq {
RoleId int64 `path:"role_id"`
RoleId string `path:"role_id"`
}
// 获取角色API权限列表响应
@@ -20,9 +20,9 @@ type (
// 角色API权限信息
AdminRoleApiInfo {
Id int64 `json:"id"`
RoleId int64 `json:"role_id"`
ApiId int64 `json:"api_id"`
Id string `json:"id"`
RoleId string `json:"role_id"`
ApiId string `json:"api_id"`
ApiName string `json:"api_name"`
ApiCode string `json:"api_code"`
Method string `json:"method"`
@@ -33,8 +33,8 @@ type (
// 分配角色API权限请求
AdminAssignRoleApiReq {
RoleId int64 `json:"role_id"`
ApiIds []int64 `json:"api_ids"`
RoleId string `json:"role_id"`
ApiIds []string `json:"api_ids"`
}
// 分配角色API权限响应
@@ -44,8 +44,8 @@ type (
// 移除角色API权限请求
AdminRemoveRoleApiReq {
RoleId int64 `json:"role_id"`
ApiIds []int64 `json:"api_ids"`
RoleId string `json:"role_id"`
ApiIds []string `json:"api_ids"`
}
// 移除角色API权限响应
@@ -55,8 +55,8 @@ type (
// 更新角色API权限请求
AdminUpdateRoleApiReq {
RoleId int64 `json:"role_id"`
ApiIds []int64 `json:"api_ids"`
RoleId string `json:"role_id"`
ApiIds []string `json:"api_ids"`
}
// 更新角色API权限响应

View File

@@ -58,52 +58,52 @@ type (
}
// 列表项
AdminUserListItem {
Id int64 `json:"id"` // 用户ID
Username string `json:"username"` // 用户名
RealName string `json:"real_name"` // 真实姓名
Status int64 `json:"status"` // 状态0-禁用1-启用
CreateTime string `json:"create_time"` // 创建时间
RoleIds []int64 `json:"role_ids"` // 关联的角色ID列表
}
AdminUserListItem {
Id string `json:"id"` // 用户ID
Username string `json:"username"` // 用户名
RealName string `json:"real_name"` // 真实姓名
Status int64 `json:"status"` // 状态0-禁用1-启用
CreateTime string `json:"create_time"` // 创建时间
RoleIds []string `json:"role_ids"` // 关联的角色ID列表
}
// 详情请求
AdminGetUserDetailReq {
Id int64 `path:"id"` // 用户ID
}
AdminGetUserDetailReq {
Id string `path:"id"` // 用户ID
}
// 详情响应
AdminGetUserDetailResp {
Id int64 `json:"id"` // 用户ID
Username string `json:"username"` // 用户名
RealName string `json:"real_name"` // 真实姓名
Status int64 `json:"status"` // 状态0-禁用1-启用
CreateTime string `json:"create_time"` // 创建时间
UpdateTime string `json:"update_time"` // 更新时间
RoleIds []int64 `json:"role_ids"` // 关联的角色ID列表
}
AdminGetUserDetailResp {
Id string `json:"id"` // 用户ID
Username string `json:"username"` // 用户名
RealName string `json:"real_name"` // 真实姓名
Status int64 `json:"status"` // 状态0-禁用1-启用
CreateTime string `json:"create_time"` // 创建时间
UpdateTime string `json:"update_time"` // 更新时间
RoleIds []string `json:"role_ids"` // 关联的角色ID列表
}
// 创建请求
AdminCreateUserReq {
Username string `json:"username"` // 用户名
RealName string `json:"real_name"` // 真实姓名
Status int64 `json:"status,default=1"` // 状态0-禁用1-启用
RoleIds []int64 `json:"role_ids"` // 关联的角色ID列表
}
AdminCreateUserReq {
Username string `json:"username"` // 用户名
RealName string `json:"real_name"` // 真实姓名
Status int64 `json:"status,default=1"` // 状态0-禁用1-启用
RoleIds []string `json:"role_ids"` // 关联的角色ID列表
}
// 创建响应
AdminCreateUserResp {
Id int64 `json:"id"` // 用户ID
}
AdminCreateUserResp {
Id string `json:"id"` // 用户ID
}
// 更新请求
AdminUpdateUserReq {
Id int64 `path:"id"` // 用户ID
Username *string `json:"username,optional"` // 用户名
RealName *string `json:"real_name,optional"` // 真实姓名
Status *int64 `json:"status,optional"` // 状态0-禁用1-启用
RoleIds []int64 `json:"role_ids,optional"` // 关联的角色ID列表
}
AdminUpdateUserReq {
Id string `path:"id"` // 用户ID
Username *string `json:"username,optional"` // 用户名
RealName *string `json:"real_name,optional"` // 真实姓名
Status *int64 `json:"status,optional"` // 状态0-禁用1-启用
RoleIds []string `json:"role_ids,optional"` // 关联的角色ID列表
}
// 更新响应
AdminUpdateUserResp {
@@ -111,9 +111,9 @@ type (
}
// 删除请求
AdminDeleteUserReq {
Id int64 `path:"id"` // 用户ID
}
AdminDeleteUserReq {
Id string `path:"id"` // 用户ID
}
// 删除响应
AdminDeleteUserResp {
@@ -132,13 +132,13 @@ type (
}
// 重置密码请求
AdminResetPasswordReq {
Id int64 `path:"id"` // 用户ID
Password string `json:"password"` // 新密码
}
AdminResetPasswordReq {
Id string `path:"id"` // 用户ID
Password string `json:"password"` // 新密码
}
// 重置密码响应
AdminResetPasswordResp {
Success bool `json:"success"` // 是否成功
}
)
)

View File

@@ -7,8 +7,8 @@ info (
)
@server (
prefix: api/v1/admin/menu
group: admin_menu
prefix: api/v1/admin/menu
group: admin_menu
middleware: AdminAuthInterceptor
)
service main {
@@ -40,100 +40,88 @@ service main {
type (
// 列表请求
GetMenuListReq {
Name string `form:"name,optional"` // 菜单名称
Path string `form:"path,optional"` // 路由路径
Name string `form:"name,optional"` // 菜单名称
Path string `form:"path,optional"` // 路由路径
Status int64 `form:"status,optional,default=-1"` // 状态0-禁用1-启用
Type string `form:"type,optional"` // 类型
Type string `form:"type,optional"` // 类型
}
// 列表项
MenuListItem {
Id int64 `json:"id"` // 菜单ID
Pid int64 `json:"pid"` // 父菜单ID
Name string `json:"name"` // 路由名称
Path string `json:"path"` // 路由路径
Component string `json:"component"` // 组件路径
Redirect string `json:"redirect"` // 重定向路径
Meta map[string]interface{} `json:"meta"` // 路由元数据
Status int64 `json:"status"` // 状态0-禁用1-启用
Type string `json:"type"` // 类型
Sort int64 `json:"sort"` // 排序
Id string `json:"id"` // 菜单ID
Pid string `json:"pid"` // 父菜单ID
Name string `json:"name"` // 路由名称
Path string `json:"path"` // 路由路径
Component string `json:"component"` // 组件路径
Redirect string `json:"redirect"` // 重定向路径
Meta map[string]interface{} `json:"meta"` // 路由元数据
Status int64 `json:"status"` // 状态0-禁用1-启用
Type string `json:"type"` // 类型
Sort int64 `json:"sort"` // 排序
CreateTime string `json:"createTime"` // 创建时间
Children []MenuListItem `json:"children"` // 子菜单
Children []MenuListItem `json:"children"` // 子菜单
}
// 详情请求
GetMenuDetailReq {
Id int64 `path:"id"` // 菜单ID
Id string `path:"id"` // 菜单ID
}
// 详情响应
GetMenuDetailResp {
Id int64 `json:"id"` // 菜单ID
Pid int64 `json:"pid"` // 父菜单ID
Name string `json:"name"` // 路由名称
Path string `json:"path"` // 路由路径
Component string `json:"component"` // 组件路径
Redirect string `json:"redirect"` // 重定向路径
Meta map[string]interface{} `json:"meta"` // 路由元数据
Status int64 `json:"status"` // 状态0-禁用1-启用
Type string `json:"type"` // 类型
Sort int64 `json:"sort"` // 排序
Id string `json:"id"` // 菜单ID
Pid string `json:"pid"` // 父菜单ID
Name string `json:"name"` // 路由名称
Path string `json:"path"` // 路由路径
Component string `json:"component"` // 组件路径
Redirect string `json:"redirect"` // 重定向路径
Meta map[string]interface{} `json:"meta"` // 路由元数据
Status int64 `json:"status"` // 状态0-禁用1-启用
Type string `json:"type"` // 类型
Sort int64 `json:"sort"` // 排序
CreateTime string `json:"createTime"` // 创建时间
UpdateTime string `json:"updateTime"` // 更新时间
}
// 创建请求
CreateMenuReq {
Pid int64 `json:"pid,optional"` // 父菜单ID
Name string `json:"name"` // 路由名称
Path string `json:"path,optional"` // 路由路径
Component string `json:"component,optional"` // 组件路径
Redirect string `json:"redirect,optional"` // 重定向路径
Meta map[string]interface{} `json:"meta"` // 路由元数据
Pid string `json:"pid,optional"` // 父菜单ID
Name string `json:"name"` // 路由名称
Path string `json:"path,optional"` // 路由路径
Component string `json:"component,optional"` // 组件路径
Redirect string `json:"redirect,optional"` // 重定向路径
Meta map[string]interface{} `json:"meta"` // 路由元数据
Status int64 `json:"status,optional,default=1"` // 状态0-禁用1-启用
Type string `json:"type"` // 类型
Sort int64 `json:"sort,optional"` // 排序
Type string `json:"type"` // 类型
Sort int64 `json:"sort,optional"` // 排序
}
// 创建响应
CreateMenuResp {
Id int64 `json:"id"` // 菜单ID
Id string `json:"id"` // 菜单ID
}
// 更新请求
UpdateMenuReq {
Id int64 `path:"id"` // 菜单ID
Pid int64 `json:"pid,optional"` // 父菜单ID
Name string `json:"name"` // 路由名称
Path string `json:"path,optional"` // 路由路径
Id string `path:"id"` // 菜单ID
Pid *string `json:"pid,optional"` // 父菜单ID
Name string `json:"name"` // 路由名称
Path string `json:"path,optional"` // 路由路径
Component string `json:"component,optional"` // 组件路径
Redirect string `json:"redirect,optional"` // 重定向路径
Meta map[string]interface{} `json:"meta"` // 路由元数据
Status int64 `json:"status,optional"` // 状态0-禁用1-启用
Type string `json:"type"` // 类型
Sort int64 `json:"sort,optional"` // 排序
Redirect string `json:"redirect,optional"` // 重定向路径
Meta map[string]interface{} `json:"meta"` // 路由元数据
Status int64 `json:"status,optional"` // 状态0-禁用1-启用
Type string `json:"type"` // 类型
Sort int64 `json:"sort,optional"` // 排序
}
// 更新响应
UpdateMenuResp {
Success bool `json:"success"` // 是否成功
}
// 删除请求
DeleteMenuReq {
Id int64 `path:"id"` // 菜单ID
Id string `path:"id"` // 菜单ID
}
// 删除响应
DeleteMenuResp {
Success bool `json:"success"` // 是否成功
}
// 获取所有菜单请求
GetMenuAllReq {
}
GetMenuAllReq {}
// 获取所有菜单响应
GetMenuAllResp {
Name string `json:"name"`
@@ -144,4 +132,5 @@ type (
Meta map[string]interface{} `json:"meta"`
Children []GetMenuAllResp `json:"children"`
}
)
)

View File

@@ -14,14 +14,14 @@ type (
}
// 创建通知响应
AdminCreateNotificationResp {
Id int64 `json:"id"` // 通知ID
}
AdminCreateNotificationResp {
Id string `json:"id"` // 通知ID
}
// 更新通知请求
AdminUpdateNotificationReq {
Id int64 `path:"id"` // 通知ID
Title *string `json:"title,optional"` // 通知标题
AdminUpdateNotificationReq {
Id string `path:"id"` // 通知ID
Title *string `json:"title,optional"` // 通知标题
Content *string `json:"content,optional"` // 通知内容
NotificationPage *string `json:"notification_page,optional"` // 通知页面
StartDate *string `json:"start_date,optional"` // 生效开始日期
@@ -37,9 +37,9 @@ type (
}
// 删除通知请求
AdminDeleteNotificationReq {
Id int64 `path:"id"` // 通知ID
}
AdminDeleteNotificationReq {
Id string `path:"id"` // 通知ID
}
// 删除通知响应
AdminDeleteNotificationResp {
@@ -47,14 +47,14 @@ type (
}
// 获取通知详情请求
AdminGetNotificationDetailReq {
Id int64 `path:"id"` // 通知ID
}
AdminGetNotificationDetailReq {
Id string `path:"id"` // 通知ID
}
// 获取通知详情响应
AdminGetNotificationDetailResp {
Id int64 `json:"id"` // 通知ID
Title string `json:"title"` // 通知标题
AdminGetNotificationDetailResp {
Id string `json:"id"` // 通知ID
Title string `json:"title"` // 通知标题
Content string `json:"content"` // 通知内容
NotificationPage string `json:"notification_page"` // 通知页面
StartDate string `json:"start_date"` // 生效开始日期
@@ -78,9 +78,9 @@ type (
}
// 通知列表项
NotificationListItem {
Id int64 `json:"id"` // 通知ID
Title string `json:"title"` // 通知标题
NotificationListItem {
Id string `json:"id"` // 通知ID
Title string `json:"title"` // 通知标题
NotificationPage string `json:"notification_page"` // 通知页面
Content string `json:"content"` // 通知内容
StartDate string `json:"start_date"` // 生效开始日期
@@ -125,4 +125,4 @@ service main {
// 获取通知列表
@handler AdminGetNotificationList
get /list (AdminGetNotificationListReq) returns (AdminGetNotificationListResp)
}
}

View File

@@ -66,8 +66,8 @@ type (
Items []OrderListItem `json:"items"` // 列表
}
// 列表项
OrderListItem {
Id int64 `json:"id"` // 订单ID
OrderListItem {
Id string `json:"id"` // 订单ID
OrderNo string `json:"order_no"` // 商户订单号
PlatformOrderId string `json:"platform_order_id"` // 支付订单号
ProductName string `json:"product_name"` // 产品名称
@@ -83,12 +83,12 @@ type (
AgentProcessStatus string `json:"agent_process_status"` // 代理事务处理状态not_agent-非代理订单success-处理成功failed-处理失败pending-待处理
}
// 详情请求
AdminGetOrderDetailReq {
Id int64 `path:"id"` // 订单ID
AdminGetOrderDetailReq {
Id string `path:"id"` // 订单ID
}
// 详情响应
AdminGetOrderDetailResp {
Id int64 `json:"id"` // 订单ID
AdminGetOrderDetailResp {
Id string `json:"id"` // 订单ID
OrderNo string `json:"order_no"` // 商户订单号
PlatformOrderId string `json:"platform_order_id"` // 支付订单号
ProductName string `json:"product_name"` // 产品名称
@@ -115,12 +115,12 @@ type (
Status string `json:"status,default=pending"` // 支付状态pending-待支付paid-已支付refunded-已退款closed-已关闭failed-支付失败
}
// 创建响应
AdminCreateOrderResp {
Id int64 `json:"id"` // 订单ID
AdminCreateOrderResp {
Id string `json:"id"` // 订单ID
}
// 更新请求
AdminUpdateOrderReq {
Id int64 `path:"id"` // 订单ID
AdminUpdateOrderReq {
Id string `path:"id"` // 订单ID
OrderNo *string `json:"order_no,optional"` // 商户订单号
PlatformOrderId *string `json:"platform_order_id,optional"` // 支付订单号
ProductName *string `json:"product_name,optional"` // 产品名称
@@ -136,16 +136,16 @@ type (
Success bool `json:"success"` // 是否成功
}
// 删除请求
AdminDeleteOrderReq {
Id int64 `path:"id"` // 订单ID
AdminDeleteOrderReq {
Id string `path:"id"` // 订单ID
}
// 删除响应
AdminDeleteOrderResp {
Success bool `json:"success"` // 是否成功
}
// 退款请求
AdminRefundOrderReq {
Id int64 `path:"id"` // 订单ID
AdminRefundOrderReq {
Id string `path:"id"` // 订单ID
RefundAmount float64 `json:"refund_amount"` // 退款金额
RefundReason string `json:"refund_reason"` // 退款原因
}
@@ -156,8 +156,8 @@ type (
Amount float64 `json:"amount"` // 退款金额
}
// 重新执行代理处理请求
AdminRetryAgentProcessReq {
Id int64 `path:"id"` // 订单ID
AdminRetryAgentProcessReq {
Id string `path:"id"` // 订单ID
}
// 重新执行代理处理响应
AdminRetryAgentProcessResp {
@@ -165,4 +165,4 @@ type (
Message string `json:"message"` // 执行结果消息
ProcessedAt string `json:"processed_at"` // 处理时间
}
)
)

View File

@@ -7,9 +7,9 @@ info (
)
// 平台用户管理接口
@server(
prefix: /api/v1/admin/platform_user
group: admin_platform_user
@server (
prefix: /api/v1/admin/platform_user
group: admin_platform_user
middleware: AdminAuthInterceptor
)
service main {
@@ -37,86 +37,77 @@ service main {
type (
// 分页列表请求
AdminGetPlatformUserListReq {
Page int64 `form:"page,default=1"` // 页码
PageSize int64 `form:"pageSize,default=20"` // 每页数量
Mobile string `form:"mobile,optional"` // 手机号
Nickname string `form:"nickname,optional"` // 昵称
Inside int64 `form:"inside,optional"` // 是否内部用户 1-是 0-否
Page int64 `form:"page,default=1"` // 页码
PageSize int64 `form:"pageSize,default=20"` // 每页数量
Mobile string `form:"mobile,optional"` // 手机号
Nickname string `form:"nickname,optional"` // 昵称
Inside int64 `form:"inside,optional"` // 是否内部用户 1-是 0-否
CreateTimeStart string `form:"create_time_start,optional"` // 创建时间开始
CreateTimeEnd string `form:"create_time_end,optional"` // 创建时间结束
OrderBy string `form:"order_by,optional"` // 排序字段
OrderType string `form:"order_type,optional"` // 排序类型
CreateTimeEnd string `form:"create_time_end,optional"` // 创建时间结束
OrderBy string `form:"order_by,optional"` // 排序字段
OrderType string `form:"order_type,optional"` // 排序类型
}
// 分页列表响应
AdminGetPlatformUserListResp {
Total int64 `json:"total"` // 总数
Items []PlatformUserListItem `json:"items"` // 列表
}
// 列表项
PlatformUserListItem {
Id int64 `json:"id"` // 用户ID
Mobile string `json:"mobile"` // 手机号
Nickname string `json:"nickname"` // 昵称
Info string `json:"info"` // 备注信息
Inside int64 `json:"inside"` // 是否内部用户 1-是 0-否
Id string `json:"id"` // 用户ID
Mobile string `json:"mobile"` // 手机号
Nickname string `json:"nickname"` // 昵称
Info string `json:"info"` // 备注信息
Inside int64 `json:"inside"` // 是否内部用户 1-是 0-否
CreateTime string `json:"create_time"` // 创建时间
UpdateTime string `json:"update_time"` // 更新时间
}
// 详情请求
AdminGetPlatformUserDetailReq {
Id int64 `path:"id"` // 用户ID
Id string `path:"id"` // 用户ID
}
// 详情响应
AdminGetPlatformUserDetailResp {
Id int64 `json:"id"` // 用户ID
Mobile string `json:"mobile"` // 手机号
Nickname string `json:"nickname"` // 昵称
Info string `json:"info"` // 备注信息
Inside int64 `json:"inside"` // 是否内部用户 1-是 0-否
Id string `json:"id"` // 用户ID
Mobile string `json:"mobile"` // 手机号
Nickname string `json:"nickname"` // 昵称
Info string `json:"info"` // 备注信息
Inside int64 `json:"inside"` // 是否内部用户 1-是 0-否
CreateTime string `json:"create_time"` // 创建时间
UpdateTime string `json:"update_time"` // 更新时间
}
// 创建请求
AdminCreatePlatformUserReq {
Mobile string `json:"mobile"` // 手机号
Mobile string `json:"mobile"` // 手机号
Password string `json:"password"` // 密码
Nickname string `json:"nickname"` // 昵称
Info string `json:"info"` // 备注信息
Inside int64 `json:"inside"` // 是否内部用户 1-是 0-否
Info string `json:"info"` // 备注信息
Inside int64 `json:"inside"` // 是否内部用户 1-是 0-否
}
// 创建响应
AdminCreatePlatformUserResp {
Id int64 `json:"id"` // 用户ID
Id string `json:"id"` // 用户ID
}
// 更新请求
AdminUpdatePlatformUserReq {
Id int64 `path:"id"` // 用户ID
Mobile *string `json:"mobile,optional"` // 手机号
Id string `path:"id"` // 用户ID
Mobile *string `json:"mobile,optional"` // 手机号
Password *string `json:"password,optional"` // 密码
Nickname *string `json:"nickname,optional"` // 昵称
Info *string `json:"info,optional"` // 备注信息
Inside *int64 `json:"inside,optional"` // 是否内部用户 1-是 0-否
Info *string `json:"info,optional"` // 备注信息
Inside *int64 `json:"inside,optional"` // 是否内部用户 1-是 0-否
}
// 更新响应
AdminUpdatePlatformUserResp {
Success bool `json:"success"` // 是否成功
}
// 删除请求
AdminDeletePlatformUserReq {
Id int64 `path:"id"` // 用户ID
Id string `path:"id"` // 用户ID
}
// 删除响应
AdminDeletePlatformUserResp {
Success bool `json:"success"` // 是否成功
}
)
)

View File

@@ -50,25 +50,25 @@ type (
}
// 列表项
RoleListItem {
Id int64 `json:"id"` // 角色ID
RoleName string `json:"role_name"` // 角色名称
RoleListItem {
Id string `json:"id"` // 角色ID
RoleName string `json:"role_name"` // 角色名称
RoleCode string `json:"role_code"` // 角色编码
Description string `json:"description"` // 角色描述
Status int64 `json:"status"` // 状态0-禁用1-启用
Sort int64 `json:"sort"` // 排序
CreateTime string `json:"create_time"` // 创建时间
MenuIds []int64 `json:"menu_ids"` // 关联的菜单ID列表
}
MenuIds []string `json:"menu_ids"` // 关联的菜单ID列表
}
// 详情请求
GetRoleDetailReq {
Id int64 `path:"id"` // 角色ID
}
GetRoleDetailReq {
Id string `path:"id"` // 角色ID
}
// 详情响应
GetRoleDetailResp {
Id int64 `json:"id"` // 角色ID
GetRoleDetailResp {
Id string `json:"id"` // 角色ID
RoleName string `json:"role_name"` // 角色名称
RoleCode string `json:"role_code"` // 角色编码
Description string `json:"description"` // 角色描述
@@ -76,34 +76,34 @@ type (
Sort int64 `json:"sort"` // 排序
CreateTime string `json:"create_time"` // 创建时间
UpdateTime string `json:"update_time"` // 更新时间
MenuIds []int64 `json:"menu_ids"` // 关联的菜单ID列表
}
MenuIds []string `json:"menu_ids"` // 关联的菜单ID列表
}
// 创建请求
CreateRoleReq {
CreateRoleReq {
RoleName string `json:"role_name"` // 角色名称
RoleCode string `json:"role_code"` // 角色编码
Description string `json:"description"` // 角色描述
Status int64 `json:"status,default=1"` // 状态0-禁用1-启用
Sort int64 `json:"sort,default=0"` // 排序
MenuIds []int64 `json:"menu_ids"` // 关联的菜单ID列表
}
MenuIds []string `json:"menu_ids"` // 关联的菜单ID列表
}
// 创建响应
CreateRoleResp {
Id int64 `json:"id"` // 角色ID
}
CreateRoleResp {
Id string `json:"id"` // 角色ID
}
// 更新请求
UpdateRoleReq {
Id int64 `path:"id"` // 角色ID
UpdateRoleReq {
Id string `path:"id"` // 角色ID
RoleName *string `json:"role_name,optional"` // 角色名称
RoleCode *string `json:"role_code,optional"` // 角色编码
Description *string `json:"description,optional"` // 角色描述
Status *int64 `json:"status,optional"` // 状态0-禁用1-启用
Sort *int64 `json:"sort,optional"` // 排序
MenuIds []int64 `json:"menu_ids,optional"` // 关联的菜单ID列表
}
MenuIds []string `json:"menu_ids,optional"` // 关联的菜单ID列表
}
// 更新响应
UpdateRoleResp {
@@ -111,12 +111,12 @@ type (
}
// 删除请求
DeleteRoleReq {
Id int64 `path:"id"` // 角色ID
}
DeleteRoleReq {
Id string `path:"id"` // 角色ID
}
// 删除响应
DeleteRoleResp {
Success bool `json:"success"` // 是否成功
}
)
)

View File

@@ -32,8 +32,8 @@ type (
LinkIdentifier string `form:"link_identifier"` // 推广链接标识
}
GetLinkDataResp {
AgentId int64 `json:"agent_id"` // 代理ID
ProductId int64 `json:"product_id"` // 产品ID
AgentId string `json:"agent_id"` // 代理ID
ProductId string `json:"product_id"` // 产品ID
SetPrice float64 `json:"set_price"` // 代理设定价格
ActualBasePrice float64 `json:"actual_base_price"` // 实际底价
ProductName string `json:"product_name"` // 产品名称
@@ -43,31 +43,37 @@ type (
Features []Feature `json:"features"` // 产品功能列表
}
AgentApplyReq {
Region string `json:"region,optional"` // 区域(可选)
Mobile string `json:"mobile"` // 手机号
Code string `json:"code"` // 验证码
InviteCode string `json:"invite_code"` // 邀请码(必填,只能通过邀请码成为代理)
Region string `json:"region,optional"`
Mobile string `json:"mobile"`
Code string `json:"code"`
Referrer string `json:"referrer"`
InviteCode string `json:"invite_code,optional"`
AgentCode int64 `json:"agent_code,optional"`
}
AgentApplyResp {
AccessToken string `json:"accessToken"`
AccessExpire int64 `json:"accessExpire"`
RefreshAfter int64 `json:"refreshAfter"`
AgentCode int64 `json:"agent_code"`
}
// 通过邀请码注册
RegisterByInviteCodeReq {
InviteCode string `json:"invite_code"` // 邀请码
Mobile string `json:"mobile"` // 手机号
Code string `json:"code"` // 验证码
Region string `json:"region,optional"` // 区域(可选)
WechatId string `json:"wechat_id,optional"` // 微信号(可选)
Referrer string `json:"referrer"`
InviteCode string `json:"invite_code,optional"`
AgentCode int64 `json:"agent_code,optional"`
Mobile string `json:"mobile"`
Code string `json:"code"`
Region string `json:"region,optional"`
WechatId string `json:"wechat_id,optional"`
}
RegisterByInviteCodeResp {
AccessToken string `json:"accessToken"`
AccessExpire int64 `json:"accessExpire"`
RefreshAfter int64 `json:"refreshAfter"`
AgentId int64 `json:"agent_id"` // 代理ID
AgentId string `json:"agent_id"` // 代理ID
Level int64 `json:"level"` // 代理等级
LevelName string `json:"level_name"` // 等级名称
AgentCode int64 `json:"agent_code"`
}
// 生成邀请码
GenerateInviteCodeReq {
@@ -89,7 +95,7 @@ type (
List []InviteCodeItem `json:"list"` // 列表
}
InviteCodeItem {
Id int64 `json:"id"` // 记录ID
Id string `json:"id"` // 记录ID
Code string `json:"code"` // 邀请码
TargetLevel int64 `json:"target_level"` // 目标等级
Status int64 `json:"status"` // 状态0=未使用1=已使用2=已失效
@@ -100,7 +106,7 @@ type (
}
// 删除邀请码
DeleteInviteCodeReq {
Id int64 `json:"id"` // 邀请码ID
Id string `json:"id"` // 邀请码ID
}
DeleteInviteCodeResp {}
// 获取邀请链接
@@ -113,18 +119,22 @@ type (
}
// 获取代理等级特权信息
GetLevelPrivilegeResp {
Levels []LevelPrivilegeItem `json:"levels"` // 各等级特权信息列表
Levels []LevelPrivilegeItem `json:"levels"`
UpgradeToGoldFee float64 `json:"upgrade_to_gold_fee"`
UpgradeToDiamondFee float64 `json:"upgrade_to_diamond_fee"`
UpgradeToGoldRebate float64 `json:"upgrade_to_gold_rebate"`
UpgradeToDiamondRebate float64 `json:"upgrade_to_diamond_rebate"`
}
LevelPrivilegeItem {
Level int64 `json:"level"` // 等级1=普通2=黄金3=钻石
LevelName string `json:"level_name"` // 等级名称
LevelBonus float64 `json:"level_bonus"` // 等级加成(元)
PriceReduction float64 `json:"price_reduction"` // 底价降低(元,相对于当前等级)
PromoteRebate string `json:"promote_rebate"` // 推广返佣说明
MaxPromoteRebate float64 `json:"max_promote_rebate"` // 最高推广返佣金额(元)
UpgradeRebate string `json:"upgrade_rebate"` // 下级升级返佣说明
Privileges []string `json:"privileges"` // 特权列表
CanUpgradeSubordinate bool `json:"can_upgrade_subordinate"` // 是否可以升级下级
Level int64 `json:"level"` // 等级1=普通2=黄金3=钻石
LevelName string `json:"level_name"` // 等级名称
LevelBonus float64 `json:"level_bonus"` // 等级加成(元)
PriceReduction float64 `json:"price_reduction"` // 底价降低(元,相对于当前等级)
PromoteRebate string `json:"promote_rebate"` // 推广返佣说明
MaxPromoteRebate float64 `json:"max_promote_rebate"` // 最高推广返佣金额(元)
UpgradeRebate string `json:"upgrade_rebate"` // 下级升级返佣说明
Privileges []string `json:"privileges"` // 特权列表
CanUpgradeSubordinate bool `json:"can_upgrade_subordinate"` // 是否可以升级下级
}
)
@@ -229,23 +239,28 @@ service main {
// 获取代理等级特权信息
@handler GetLevelPrivilege
get /level/privilege returns (GetLevelPrivilegeResp)
// 获取推广查询报告列表
@handler GetPromotionQueryList
get /promotion/query/list (GetPromotionQueryListReq) returns (GetPromotionQueryListResp)
}
type (
// 代理信息
AgentInfoResp {
AgentId int64 `json:"agent_id"` // 代理ID
Level int64 `json:"level"` // 代理等级1=普通2=黄金3=钻石
LevelName string `json:"level_name"` // 等级名称
Region string `json:"region"` // 区域(可选)
Mobile string `json:"mobile"` // 手机号
WechatId string `json:"wechat_id"` // 微信号(可选)
TeamLeaderId int64 `json:"team_leader_id"` // 团队首领ID
IsRealName bool `json:"is_real_name"` // 是否已实名
AgentId string `json:"agent_id"`
Level int64 `json:"level"`
LevelName string `json:"level_name"`
Region string `json:"region"`
Mobile string `json:"mobile"`
WechatId string `json:"wechat_id"`
TeamLeaderId string `json:"team_leader_id"`
IsRealName bool `json:"is_real_name"`
AgentCode int64 `json:"agent_code"`
}
// 生成推广链接
AgentGeneratingLinkReq {
ProductId int64 `json:"product_id"` // 产品ID
ProductId string `json:"product_id"` // 产品ID
SetPrice float64 `json:"set_price"` // 设定价格
TargetPath string `json:"target_path,optional"` // 目标地址(可选,默认为推广报告页面)
}
@@ -258,7 +273,7 @@ type (
List []ProductConfigItem `json:"list"`
}
ProductConfigItem {
ProductId int64 `json:"product_id"` // 产品ID
ProductId string `json:"product_id"` // 产品ID
ProductName string `json:"product_name"` // 产品名称
ProductEn string `json:"product_en"` // 产品英文标识
ActualBasePrice float64 `json:"actual_base_price"` // 实际底价
@@ -305,7 +320,7 @@ type (
List []SubordinateItem `json:"list"` // 列表
}
SubordinateItem {
AgentId int64 `json:"agent_id"` // 代理ID
AgentId string `json:"agent_id"` // 代理ID
Level int64 `json:"level"` // 等级
LevelName string `json:"level_name"` // 等级名称
Mobile string `json:"mobile"` // 手机号
@@ -315,7 +330,7 @@ type (
}
// 下级贡献详情
GetSubordinateContributionDetailReq {
SubordinateId int64 `form:"subordinate_id"` // 下级代理ID
SubordinateId string `form:"subordinate_id"` // 下级代理ID
Page int64 `form:"page"` // 页码
PageSize int64 `form:"page_size"` // 每页数量
TabType string `form:"tab_type,optional"` // 标签页类型order=订单列表invite=邀请列表
@@ -349,14 +364,14 @@ type (
}
OrderItem {
OrderNo string `json:"order_no"` // 订单号
ProductId int64 `json:"product_id"` // 产品ID
ProductId string `json:"product_id"` // 产品ID
ProductName string `json:"product_name"` // 产品名称
OrderAmount float64 `json:"order_amount"` // 订单金额
RebateAmount float64 `json:"rebate_amount"` // 返佣金额
CreateTime string `json:"create_time"` // 创建时间
}
InviteItem {
AgentId int64 `json:"agent_id"` // 代理ID
AgentId string `json:"agent_id"` // 代理ID
Level int64 `json:"level"` // 等级
LevelName string `json:"level_name"` // 等级名称
Mobile string `json:"mobile"` // 手机号
@@ -385,7 +400,7 @@ type (
MonthEarnings float64 `json:"month_earnings"` // 月收益
}
TeamMemberItem {
AgentId int64 `json:"agent_id"` // 代理ID
AgentId string `json:"agent_id"` // 代理ID
Level int64 `json:"level"` // 等级
LevelName string `json:"level_name"` // 等级名称
Mobile string `json:"mobile"` // 手机号
@@ -421,8 +436,8 @@ type (
List []CommissionItem `json:"list"` // 列表
}
CommissionItem {
Id int64 `json:"id"` // 记录ID
OrderId int64 `json:"order_id"` // 订单ID
Id string `json:"id"` // 记录ID
OrderId string `json:"order_id"` // 订单ID
OrderNo string `json:"order_no"` // 订单号
ProductName string `json:"product_name"` // 产品名称
Amount float64 `json:"amount"` // 佣金金额
@@ -440,11 +455,11 @@ type (
List []RebateItem `json:"list"` // 列表
}
RebateItem {
Id int64 `json:"id"` // 记录ID
SourceAgentId int64 `json:"source_agent_id"` // 来源代理ID
Id string `json:"id"` // 记录ID
SourceAgentId string `json:"source_agent_id"` // 来源代理ID
SourceAgentMobile string `json:"source_agent_mobile"` // 来源代理手机号
SourceAgentLevel int64 `json:"source_agent_level"` // 来源代理等级1=普通2=黄金3=钻石
OrderId int64 `json:"order_id"` // 订单ID
OrderId string `json:"order_id"` // 订单ID
OrderNo string `json:"order_no"` // 订单号
RebateType int64 `json:"rebate_type"` // 返佣类型1=直接上级2=钻石上级3=黄金上级
Amount float64 `json:"amount"` // 返佣金额
@@ -460,8 +475,8 @@ type (
List []UpgradeRebateItem `json:"list"` // 列表
}
UpgradeRebateItem {
Id int64 `json:"id"` // 记录ID
SourceAgentId int64 `json:"source_agent_id"` // 来源代理ID升级的代理
Id string `json:"id"` // 记录ID
SourceAgentId string `json:"source_agent_id"` // 来源代理ID升级的代理
SourceAgentMobile string `json:"source_agent_mobile"` // 来源代理手机号
OrderNo string `json:"order_no"` // 订单号
FromLevel int64 `json:"from_level"` // 原等级
@@ -479,8 +494,8 @@ type (
List []UpgradeItem `json:"list"` // 列表
}
UpgradeItem {
Id int64 `json:"id"` // 记录ID
AgentId int64 `json:"agent_id"` // 代理ID
Id string `json:"id"` // 记录ID
AgentId string `json:"agent_id"` // 代理ID
FromLevel int64 `json:"from_level"` // 原等级
ToLevel int64 `json:"to_level"` // 目标等级
UpgradeType int64 `json:"upgrade_type"` // 升级类型1=自主付费2=钻石升级
@@ -494,13 +509,13 @@ type (
ToLevel int64 `json:"to_level"` // 目标等级2=黄金3=钻石
}
ApplyUpgradeResp {
UpgradeId int64 `json:"upgrade_id"` // 升级记录ID
UpgradeId string `json:"upgrade_id"` // 升级记录ID
OrderNo string `json:"order_no"` // 支付订单号
}
// 钻石升级下级
UpgradeSubordinateReq {
SubordinateId int64 `json:"subordinate_id"` // 下级代理ID
ToLevel int64 `json:"to_level"` // 目标等级只能是2=黄金)
SubordinateId string `json:"subordinate_id"` // 下级代理ID
ToLevel int64 `json:"to_level"` // 目标等级只能是2=黄金)
}
UpgradeSubordinateResp {
Success bool `json:"success"`
@@ -515,7 +530,7 @@ type (
List []WithdrawalItem `json:"list"` // 列表
}
WithdrawalItem {
Id int64 `json:"id"` // 记录ID
Id string `json:"id"` // 记录ID
WithdrawalNo string `json:"withdrawal_no"` // 提现单号
Amount float64 `json:"amount"` // 提现金额
TaxAmount float64 `json:"tax_amount"` // 税费金额
@@ -533,7 +548,7 @@ type (
PayeeName string `json:"payee_name"` // 收款人姓名
}
ApplyWithdrawalResp {
WithdrawalId int64 `json:"withdrawal_id"` // 提现记录ID
WithdrawalId string `json:"withdrawal_id"` // 提现记录ID
WithdrawalNo string `json:"withdrawal_no"` // 提现单号
}
// 实名认证
@@ -546,6 +561,22 @@ type (
RealNameAuthResp {
Status string `json:"status"` // 状态pending=待审核approved=已通过rejected=已拒绝
}
// 推广查询列表
GetPromotionQueryListReq {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"page_size"` // 每页数量
}
GetPromotionQueryListResp {
Total int64 `json:"total"` // 总数
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"` // 查询状态
}
)
// ============================================
@@ -563,4 +594,3 @@ service main {
type (
ShortLinkRedirectResp {}
)

View File

@@ -1,56 +1,50 @@
type (
// GetAuthorizationDocumentReq 获取授权书请求
GetAuthorizationDocumentReq {
DocumentId int64 `json:"documentId" validate:"required"` // 授权书ID
DocumentId string `json:"documentId" validate:"required"` // 授权书ID
}
// GetAuthorizationDocumentResp 获取授权书响应
GetAuthorizationDocumentResp {
DocumentId int64 `json:"documentId"` // 授权书ID
UserId int64 `json:"userId"` // 用户ID
OrderId int64 `json:"orderId"` // 订单ID
QueryId int64 `json:"queryId"` // 查询ID
FileName string `json:"fileName"` // 文件名
FileUrl string `json:"fileUrl"` // 文件访问URL
FileSize int64 `json:"fileSize"` // 文件大小
FileType string `json:"fileType"` // 文件类型
Status string `json:"status"` // 状态
CreateTime string `json:"createTime"` // 创建时间
DocumentId string `json:"documentId"` // 授权书ID
UserId string `json:"userId"` // 用户ID
OrderId string `json:"orderId"` // 订单ID
QueryId string `json:"queryId"` // 查询ID
FileName string `json:"fileName"` // 文件名
FileUrl string `json:"fileUrl"` // 文件访问URL
FileSize int64 `json:"fileSize"` // 文件大小
FileType string `json:"fileType"` // 文件类型
Status string `json:"status"` // 状态
CreateTime string `json:"createTime"` // 创建时间
}
// GetAuthorizationDocumentByOrderReq 根据订单ID获取授权书请求
GetAuthorizationDocumentByOrderReq {
OrderId int64 `json:"orderId" validate:"required"` // 订单ID
OrderId string `json:"orderId" validate:"required"` // 订单ID
}
// GetAuthorizationDocumentByOrderResp 根据订单ID获取授权书响应
GetAuthorizationDocumentByOrderResp {
Documents []AuthorizationDocumentInfo `json:"documents"` // 授权书列表
}
// AuthorizationDocumentInfo 授权书信息
AuthorizationDocumentInfo {
DocumentId int64 `json:"documentId"` // 授权书ID
UserId int64 `json:"userId"` // 用户ID
OrderId int64 `json:"orderId"` // 订单ID
QueryId int64 `json:"queryId"` // 查询ID
FileName string `json:"fileName"` // 文件名
FileUrl string `json:"fileUrl"` // 文件访问URL
FileSize int64 `json:"fileSize"` // 文件大小
FileType string `json:"fileType"` // 文件类型
Status string `json:"status"` // 状态
CreateTime string `json:"createTime"` // 创建时间
DocumentId string `json:"documentId"` // 授权书ID
UserId string `json:"userId"` // 用户ID
OrderId string `json:"orderId"` // 订单ID
QueryId string `json:"queryId"` // 查询ID
FileName string `json:"fileName"` // 文件名
FileUrl string `json:"fileUrl"` // 文件访问URL
FileSize int64 `json:"fileSize"` // 文件大小
FileType string `json:"fileType"` // 文件类型
Status string `json:"status"` // 状态
CreateTime string `json:"createTime"` // 创建时间
}
// DownloadAuthorizationDocumentReq 下载授权书请求
DownloadAuthorizationDocumentReq {
DocumentId int64 `json:"documentId" validate:"required"` // 授权书ID
DocumentId string `json:"documentId" validate:"required"` // 授权书ID
}
// DownloadAuthorizationDocumentResp 下载授权书响应
DownloadAuthorizationDocumentResp {
FileName string `json:"fileName"` // 文件名
FileUrl string `json:"fileUrl"` // 文件访问URL
FileUrl string `json:"fileUrl"` // 文件访问URL
}
)
@@ -63,12 +57,13 @@ service main {
// 获取授权书信息
@handler GetAuthorizationDocument
get /authorization/document/:documentId (GetAuthorizationDocumentReq) returns (GetAuthorizationDocumentResp)
// 根据订单ID获取授权书列表
@handler GetAuthorizationDocumentByOrder
get /authorization/document/order/:orderId (GetAuthorizationDocumentByOrderReq) returns (GetAuthorizationDocumentByOrderResp)
// 下载授权书文件
@handler DownloadAuthorizationDocument
get /authorization/download/:documentId (DownloadAuthorizationDocumentReq) returns (DownloadAuthorizationDocumentResp)
}

View File

@@ -25,11 +25,10 @@ service main {
}
@server (
prefix: api/v1
group: pay
jwt: JwtAuth
middleware: UserAuthInterceptor
prefix: api/v1
group: pay
jwt: JwtAuth
middleware: AuthInterceptor
)
service main {
// 支付
@@ -65,7 +64,8 @@ type (
type (
IapCallbackReq {
OrderID int64 `json:"order_id" validate:"required"`
OrderID string `json:"order_id" validate:"required"`
TransactionReceipt string `json:"transaction_receipt" validate:"required"`
}
)
)

View File

@@ -6,9 +6,9 @@ info (
version: "v1"
)
type Feature {
ID int64 `json:"id"` // 功能ID
ApiID string `json:"api_id"` // API标识
Name string `json:"name"` // 功能描述
ID string `json:"id"` // 功能ID
ApiID string `json:"api_id"` // API标识
Name string `json:"name"` // 功能描述
}
// 产品基本类型定义
type Product {
@@ -34,7 +34,7 @@ service main {
}
type GetProductByIDRequest {
Id int64 `path:"id"`
Id string `path:"id"`
}
type GetProductByEnRequest {
@@ -52,4 +52,4 @@ type ProductResponse {
service main {
@handler GetProductAppByEn
get /app_en/:product_en (GetProductByEnRequest) returns (ProductResponse)
}
}

View File

@@ -9,9 +9,9 @@ info (
//============================> query v1 <============================
// 查询基本类型定义
type Query {
Id int64 `json:"id"` // 主键ID
OrderId int64 `json:"order_id"` // 订单ID
UserId int64 `json:"user_id"` // 用户ID
Id string `json:"id"` // 主键ID
OrderId string `json:"order_id"` // 订单ID
UserId string `json:"user_id"` // 用户ID
Product string `json:"product"` // 产品ID
ProductName string `json:"product_name"` // 产品ID
QueryParams map[string]interface{} `json:"query_params"`
@@ -68,7 +68,7 @@ type (
prefix: api/v1
group: query
jwt: JwtAuth
middleware: UserAuthInterceptor
middleware: AuthInterceptor
)
service main {
@doc "query service"
@@ -80,7 +80,7 @@ service main {
prefix: api/v1
group: query
jwt: JwtAuth
middleware: UserAuthInterceptor
middleware: AuthInterceptor
)
service main {
@doc "获取查询临时订单"
@@ -114,7 +114,7 @@ service main {
type (
QueryGenerateShareLinkReq {
OrderId *int64 `json:"order_id,optional"`
OrderId *string `json:"order_id,optional"`
OrderNo *string `json:"order_no,optional"`
}
QueryGenerateShareLinkResp {
@@ -154,7 +154,7 @@ type (
type (
QueryDetailByOrderIdReq {
OrderId int64 `path:"order_id"`
OrderId string `path:"order_id"`
}
)
@@ -166,7 +166,7 @@ type (
type (
QueryRetryReq {
Id int64 `path:"id"`
Id string `path:"id"`
}
QueryRetryResp {
Query
@@ -175,11 +175,11 @@ type (
type (
UpdateQueryDataReq {
Id int64 `json:"id"` // 查询ID
Id string `json:"id"` // 查询ID
QueryData string `json:"query_data"` // 查询数据(未加密的JSON)
}
UpdateQueryDataResp {
Id int64 `json:"id"`
Id string `json:"id"`
UpdatedAt string `json:"updated_at"` // 更新时间
}
)

View File

@@ -9,10 +9,10 @@ info (
//============================> user v1 <============================
// 用户基本类型定义
type User {
Id int64 `json:"id"`
Mobile string `json:"mobile"`
NickName string `json:"nickName"`
UserType int64 `json:"userType"`
Id string `json:"id"`
Mobile string `json:"mobile"`
NickName string `json:"nickName"`
UserType int64 `json:"userType"`
}
//no need login
@@ -21,6 +21,9 @@ type User {
group: user
)
service main {
@doc "unified auth"
@handler auth
post /user/auth (AuthReq) returns (AuthResp)
@doc "mobile code login"
@handler mobileCodeLogin
post /user/mobileCodeLogin (MobileCodeLoginReq) returns (MobileCodeLoginResp)
@@ -38,6 +41,18 @@ service main {
}
type (
AuthReq {
Platform string `json:"platform"` // browser|wxh5|wxmini
Code string `json:"code,optional"`
}
AuthResp {
AccessToken string `json:"accessToken"`
AccessExpire int64 `json:"accessExpire"`
RefreshAfter int64 `json:"refreshAfter"`
UserType int64 `json:"userType"`
HasMobile bool `json:"hasMobile"`
IsAgent bool `json:"isAgent"`
}
MobileCodeLoginReq {
Mobile string `json:"mobile"`
Code string `json:"code" validate:"required"`

View File

@@ -1,6 +1,7 @@
Name: main
Host: 0.0.0.0
Port: 8888
Timeout: 0
DataSource: "ycc:5vg67b3UNHu8@tcp(127.0.0.1:21001)/ycc?charset=utf8mb4&parseTime=True&loc=Local"
CacheRedis:
- Host: "127.0.0.1:21002"

View File

@@ -0,0 +1,31 @@
package agent
import (
"net/http"
"ycc-server/app/main/api/internal/logic/agent"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/common/result"
"ycc-server/pkg/lzkit/validator"
"github.com/zeromicro/go-zero/rest/httpx"
)
func GetPromotionQueryListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GetPromotionQueryListReq
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.NewGetPromotionQueryListLogic(r.Context(), svcCtx)
resp, err := l.GetPromotionQueryList(&req)
result.HttpResult(r, w, resp, err)
}
}

View File

@@ -0,0 +1,17 @@
package app
import (
"net/http"
"ycc-server/app/main/api/internal/logic/app"
"ycc-server/app/main/api/internal/svc"
"ycc-server/common/result"
)
func GetAppConfigHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
l := app.NewGetAppConfigLogic(r.Context(), svcCtx)
resp, err := l.GetAppConfig()
result.HttpResult(r, w, resp, err)
}
}

View File

@@ -662,6 +662,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/product_config",
Handler: agent.GetAgentProductConfigHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/promotion/query/list",
Handler: agent.GetPromotionQueryListHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/real_name",
@@ -745,6 +750,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes(
[]rest.Route{
{
Method: http.MethodGet,
Path: "/app/config",
Handler: app.GetAppConfigHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/app/version",
@@ -828,7 +838,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes(
rest.WithMiddlewares(
[]rest.Middleware{serverCtx.UserAuthInterceptor},
[]rest.Middleware{serverCtx.AuthInterceptor},
[]rest.Route{
{
Method: http.MethodPost,
@@ -900,7 +910,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes(
rest.WithMiddlewares(
[]rest.Middleware{serverCtx.UserAuthInterceptor},
[]rest.Middleware{serverCtx.AuthInterceptor},
[]rest.Route{
{
// query service
@@ -916,7 +926,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes(
rest.WithMiddlewares(
[]rest.Middleware{serverCtx.UserAuthInterceptor},
[]rest.Middleware{serverCtx.AuthInterceptor},
[]rest.Route{
{
// 生成分享链接
@@ -991,6 +1001,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes(
[]rest.Route{
{
// unified auth
Method: http.MethodPost,
Path: "/user/auth",
Handler: user.AuthHandler(serverCtx),
},
{
// mobile code login
Method: http.MethodPost,

View File

@@ -0,0 +1,25 @@
package user
import (
"net/http"
logic "ycc-server/app/main/api/internal/logic/user"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/common/result"
"github.com/zeromicro/go-zero/rest/httpx"
)
func AuthHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.AuthReq
if err := httpx.Parse(r, &req); err != nil {
result.ParamErrorResult(r, w, err)
return
}
l := logic.NewAuthLogic(r.Context(), svcCtx)
resp, err := l.Auth(&req)
result.HttpResult(r, w, resp, err)
}
}

View File

@@ -1,20 +1,21 @@
package admin_agent
import (
"context"
"database/sql"
"time"
"ycc-server/app/main/model"
"ycc-server/common/tool"
"ycc-server/common/xerr"
"context"
"database/sql"
"time"
"ycc-server/app/main/model"
"ycc-server/common/tool"
"ycc-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/logx"
"github.com/google/uuid"
)
type AdminGenerateDiamondInviteCodeLogic struct {
@@ -70,14 +71,15 @@ func (l *AdminGenerateDiamondInviteCodeLogic) AdminGenerateDiamondInviteCode(req
}
// 创建邀请码记录(平台发放的钻石邀请码)
inviteCode := &model.AgentInviteCode{
Code: code,
AgentId: sql.NullInt64{Valid: false}, // NULL表示平台发放
TargetLevel: 3, // 钻石代理
Status: 0, // 未使用
ExpireTime: expireTime,
Remark: sql.NullString{String: req.Remark, Valid: req.Remark != ""},
}
inviteCode := &model.AgentInviteCode{
Id: uuid.NewString(),
Code: code,
AgentId: sql.NullString{Valid: false}, // NULL表示平台发放
TargetLevel: 3, // 钻石代理
Status: 0, // 未使用
ExpireTime: expireTime,
Remark: sql.NullString{String: req.Remark, Valid: req.Remark != ""},
}
_, err := l.svcCtx.AgentInviteCodeModel.Insert(transCtx, session, inviteCode)
if err != nil {

View File

@@ -41,13 +41,13 @@ func (l *AdminGetAgentCommissionListLogic) AdminGetAgentCommissionList(req *type
}
// 批量查product_name
productIds := make(map[int64]struct{})
productIds := make(map[string]struct{})
for _, v := range list {
productIds[v.ProductId] = struct{}{}
}
productNameMap := make(map[int64]string)
productNameMap := make(map[string]string)
if len(productIds) > 0 {
ids := make([]int64, 0, len(productIds))
ids := make([]string, 0, len(productIds))
for id := range productIds {
ids = append(ids, id)
}

View File

@@ -69,6 +69,8 @@ func (l *AdminGetAgentConfigLogic) AdminGetAgentConfig() (resp *types.AdminGetAg
commissionFreezeThreshold := getConfigFloat("commission_freeze_threshold")
commissionFreezeDays := getConfigInt("commission_freeze_days")
goldUplift := getConfigFloat("gold_max_uplift_amount")
diamondUplift := getConfigFloat("diamond_max_uplift_amount")
return &types.AdminGetAgentConfigResp{
LevelBonus: types.LevelBonusConfig{
Normal: int64(level1Bonus),
@@ -78,7 +80,6 @@ func (l *AdminGetAgentConfigLogic) AdminGetAgentConfig() (resp *types.AdminGetAg
UpgradeFee: types.UpgradeFeeConfig{
NormalToGold: upgradeToGoldFee,
NormalToDiamond: upgradeToDiamondFee,
GoldToDiamond: upgradeToDiamondFee - upgradeToGoldFee,
},
UpgradeRebate: types.UpgradeRebateConfig{
NormalToGoldRebate: upgradeToGoldRebate,
@@ -95,7 +96,9 @@ func (l *AdminGetAgentConfigLogic) AdminGetAgentConfig() (resp *types.AdminGetAg
Threshold: commissionFreezeThreshold,
Days: commissionFreezeDays,
},
TaxRate: getConfigFloat("tax_rate"),
TaxExemptionAmount: getConfigFloat("tax_exemption_amount"),
TaxRate: getConfigFloat("tax_rate"),
TaxExemptionAmount: getConfigFloat("tax_exemption_amount"),
GoldMaxUpliftAmount: goldUplift,
DiamondMaxUpliftAmount: diamondUplift,
}, nil
}

View File

@@ -44,15 +44,15 @@ func (l *AdminGetAgentLinkListLogic) AdminGetAgentLinkList(req *types.AdminGetAg
}
// 批量查product_id->name避免N+1
productIdSet := make(map[int64]struct{})
productIdSet := make(map[string]struct{})
for _, link := range links {
productIdSet[link.ProductId] = struct{}{}
}
productIdList := make([]int64, 0, len(productIdSet))
productIdList := make([]string, 0, len(productIdSet))
for id := range productIdSet {
productIdList = append(productIdList, id)
}
productNameMap := make(map[int64]string)
productNameMap := make(map[string]string)
if len(productIdList) > 0 {
products, _ := l.svcCtx.ProductModel.FindAll(l.ctx, l.svcCtx.ProductModel.SelectBuilder().Where(squirrel.Eq{"id": productIdList}), "")
for _, p := range products {
@@ -63,14 +63,14 @@ func (l *AdminGetAgentLinkListLogic) AdminGetAgentLinkList(req *types.AdminGetAg
items := make([]types.AgentLinkListItem, 0, len(links))
for _, link := range links {
items = append(items, types.AgentLinkListItem{
Id: link.Id,
AgentId: link.AgentId,
ProductId: link.ProductId,
ProductName: productNameMap[link.ProductId],
SetPrice: link.SetPrice,
Id: link.Id,
AgentId: link.AgentId,
ProductId: link.ProductId,
ProductName: productNameMap[link.ProductId],
SetPrice: link.SetPrice,
ActualBasePrice: link.ActualBasePrice,
LinkIdentifier: link.LinkIdentifier,
CreateTime: link.CreateTime.Format("2006-01-02 15:04:05"),
LinkIdentifier: link.LinkIdentifier,
CreateTime: link.CreateTime.Format("2006-01-02 15:04:05"),
})
}

View File

@@ -29,7 +29,7 @@ func NewAdminGetAgentListLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *AdminGetAgentListLogic) AdminGetAgentList(req *types.AdminGetAgentListReq) (resp *types.AdminGetAgentListResp, err error) {
builder := l.svcCtx.AgentModel.SelectBuilder()
// 如果传入TeamLeaderId则查找该团队首领下的所有代理
if req.TeamLeaderId != nil {
builder = builder.Where(squirrel.Eq{"team_leader_id": *req.TeamLeaderId})
@@ -78,7 +78,7 @@ func (l *AdminGetAgentListLogic) AdminGetAgentList(req *types.AdminGetAgentListR
// 查询钱包信息
wallet, _ := l.svcCtx.AgentWalletModel.FindOneByAgentId(l.ctx, agent.Id)
// 查询实名认证信息
realNameInfo, _ := l.svcCtx.AgentRealNameModel.FindOneByAgentId(l.ctx, agent.Id)
isRealName := false
@@ -90,9 +90,9 @@ func (l *AdminGetAgentListLogic) AdminGetAgentList(req *types.AdminGetAgentListR
if agent.WechatId.Valid {
wechatId = agent.WechatId.String
}
teamLeaderId := int64(0)
teamLeaderId := ""
if agent.TeamLeaderId.Valid {
teamLeaderId = agent.TeamLeaderId.Int64
teamLeaderId = agent.TeamLeaderId.String
}
// 获取区域
@@ -102,22 +102,23 @@ func (l *AdminGetAgentListLogic) AdminGetAgentList(req *types.AdminGetAgentListR
}
item := types.AgentListItem{
Id: agent.Id,
UserId: agent.UserId,
Level: agent.Level,
LevelName: levelName,
Region: region,
Mobile: agent.Mobile,
WechatId: wechatId,
TeamLeaderId: teamLeaderId,
Balance: 0,
TotalEarnings: 0,
FrozenBalance: 0,
Id: agent.Id,
UserId: agent.UserId,
Level: agent.Level,
LevelName: levelName,
Region: region,
Mobile: agent.Mobile,
WechatId: wechatId,
TeamLeaderId: teamLeaderId,
AgentCode: agent.AgentCode,
Balance: 0,
TotalEarnings: 0,
FrozenBalance: 0,
WithdrawnAmount: 0,
IsRealName: isRealName,
CreateTime: agent.CreateTime.Format("2006-01-02 15:04:05"),
IsRealName: isRealName,
CreateTime: agent.CreateTime.Format("2006-01-02 15:04:05"),
}
if wallet != nil {
item.Balance = wallet.Balance
item.TotalEarnings = wallet.TotalEarnings

View File

@@ -58,15 +58,15 @@ func (l *AdminGetAgentOrderListLogic) AdminGetAgentOrderList(req *types.AdminGet
}
// 批量查询产品名称
productIdSet := make(map[int64]struct{})
productIdSet := make(map[string]struct{})
for _, order := range orders {
productIdSet[order.ProductId] = struct{}{}
}
productIdList := make([]int64, 0, len(productIdSet))
productIdList := make([]string, 0, len(productIdSet))
for id := range productIdSet {
productIdList = append(productIdList, id)
}
productNameMap := make(map[int64]string)
productNameMap := make(map[string]string)
if len(productIdList) > 0 {
products, _ := l.svcCtx.ProductModel.FindAll(l.ctx, l.svcCtx.ProductModel.SelectBuilder().Where(squirrel.Eq{"id": productIdList}), "")
for _, p := range products {

View File

@@ -58,15 +58,15 @@ func (l *AdminGetAgentRebateListLogic) AdminGetAgentRebateList(req *types.AdminG
}
// 批量查询产品名称
productIdSet := make(map[int64]struct{})
productIdSet := make(map[string]struct{})
for _, rebate := range rebates {
productIdSet[rebate.ProductId] = struct{}{}
}
productIdList := make([]int64, 0, len(productIdSet))
productIdList := make([]string, 0, len(productIdSet))
for id := range productIdSet {
productIdList = append(productIdList, id)
}
productNameMap := make(map[int64]string)
productNameMap := make(map[string]string)
if len(productIdList) > 0 {
products, _ := l.svcCtx.ProductModel.FindAll(l.ctx, l.svcCtx.ProductModel.SelectBuilder().Where(squirrel.Eq{"id": productIdList}), "")
for _, p := range products {
@@ -79,12 +79,12 @@ func (l *AdminGetAgentRebateListLogic) AdminGetAgentRebateList(req *types.AdminG
for _, rebate := range rebates {
items = append(items, types.AgentRebateListItem{
Id: rebate.Id,
AgentId: rebate.AgentId,
AgentId: rebate.AgentId,
SourceAgentId: rebate.SourceAgentId,
OrderId: rebate.OrderId,
RebateType: rebate.RebateType,
Amount: rebate.RebateAmount,
CreateTime: rebate.CreateTime.Format("2006-01-02 15:04:05"),
OrderId: rebate.OrderId,
RebateType: rebate.RebateType,
Amount: rebate.RebateAmount,
CreateTime: rebate.CreateTime.Format("2006-01-02 15:04:05"),
})
}

View File

@@ -37,8 +37,8 @@ func (l *AdminGetInviteCodeListLogic) AdminGetInviteCodeList(req *types.AdminGet
if req.Code != nil && *req.Code != "" {
builder = builder.Where("code = ?", *req.Code)
}
if req.AgentId != nil {
if *req.AgentId == 0 {
if req.AgentId != nil && *req.AgentId != "" {
if *req.AgentId == "0" {
// agent_id = 0 表示查询平台发放的邀请码agent_id为NULL
builder = builder.Where("agent_id IS NULL")
} else {
@@ -59,16 +59,16 @@ func (l *AdminGetInviteCodeListLogic) AdminGetInviteCodeList(req *types.AdminGet
}
// 3. 批量查询代理信息(用于显示代理手机号)
agentIds := make(map[int64]struct{})
agentIds := make(map[string]struct{})
for _, v := range list {
if v.AgentId.Valid && v.AgentId.Int64 > 0 {
agentIds[v.AgentId.Int64] = struct{}{}
if v.AgentId.Valid && v.AgentId.String != "" {
agentIds[v.AgentId.String] = struct{}{}
}
}
agentMobileMap := make(map[int64]string)
agentMobileMap := make(map[string]string)
if len(agentIds) > 0 {
agentIdList := make([]int64, 0, len(agentIds))
agentIdList := make([]string, 0, len(agentIds))
for id := range agentIds {
agentIdList = append(agentIdList, id)
}
@@ -90,7 +90,7 @@ func (l *AdminGetInviteCodeListLogic) AdminGetInviteCodeList(req *types.AdminGet
item := types.InviteCodeListItem{
Id: v.Id,
Code: v.Code,
AgentId: 0,
AgentId: "",
AgentMobile: "",
TargetLevel: v.TargetLevel,
Status: v.Status,
@@ -98,15 +98,15 @@ func (l *AdminGetInviteCodeListLogic) AdminGetInviteCodeList(req *types.AdminGet
}
if v.AgentId.Valid {
item.AgentId = v.AgentId.Int64
item.AgentMobile = agentMobileMap[v.AgentId.Int64]
item.AgentId = v.AgentId.String
item.AgentMobile = agentMobileMap[v.AgentId.String]
}
if v.UsedUserId.Valid {
item.UsedUserId = v.UsedUserId.Int64
item.UsedUserId = v.UsedUserId.String
}
if v.UsedAgentId.Valid {
item.UsedAgentId = v.UsedAgentId.Int64
item.UsedAgentId = v.UsedAgentId.String
}
if v.UsedTime.Valid {
item.UsedTime = v.UsedTime.Time.Format("2006-01-02 15:04:05")

View File

@@ -2,6 +2,7 @@ package admin_agent
import (
"context"
"database/sql"
"strconv"
"ycc-server/common/xerr"
@@ -9,6 +10,7 @@ import (
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"github.com/zeromicro/go-zero/core/logx"
)
@@ -28,17 +30,77 @@ func NewAdminUpdateAgentConfigLogic(ctx context.Context, svcCtx *svc.ServiceCont
}
func (l *AdminUpdateAgentConfigLogic) AdminUpdateAgentConfig(req *types.AdminUpdateAgentConfigReq) (resp *types.AdminUpdateAgentConfigResp, err error) {
// 更新配置的辅助函数
configTypeForKey := func(key string) string {
switch key {
case "level_1_bonus", "level_2_bonus", "level_3_bonus":
return "bonus"
case "upgrade_to_gold_fee", "upgrade_to_diamond_fee", "upgrade_to_gold_rebate", "upgrade_to_diamond_rebate":
return "upgrade"
case "direct_parent_amount_diamond", "direct_parent_amount_gold", "direct_parent_amount_normal", "max_gold_rebate_amount":
return "rebate"
case "commission_freeze_ratio", "commission_freeze_threshold", "commission_freeze_days":
return "rebate"
case "tax_rate", "tax_exemption_amount":
return "tax"
case "gold_max_uplift_amount", "diamond_max_uplift_amount":
return "price"
default:
return "rebate"
}
}
updateConfig := func(key string, value *float64) error {
if value == nil {
return nil
}
valStr := strconv.FormatFloat(*value, 'f', -1, 64)
config, err := l.svcCtx.AgentConfigModel.FindOneByConfigKey(l.ctx, key)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
cfg := &model.AgentConfig{
ConfigKey: key,
ConfigValue: valStr,
ConfigType: configTypeForKey(key),
Description: sql.NullString{},
DeleteTime: sql.NullTime{},
Version: 0,
}
_, insErr := l.svcCtx.AgentConfigModel.Insert(l.ctx, nil, cfg)
if insErr != nil {
return errors.Wrapf(insErr, "创建配置失败, key: %s", key)
}
return nil
}
return errors.Wrapf(err, "查询配置失败, key: %s", key)
}
config.ConfigValue = strconv.FormatFloat(*value, 'f', -1, 64)
return l.svcCtx.AgentConfigModel.UpdateWithVersion(l.ctx, nil, config)
config.ConfigValue = valStr
if uErr := l.svcCtx.AgentConfigModel.UpdateWithVersion(l.ctx, nil, config); uErr != nil {
if errors.Is(uErr, model.ErrNoRowsUpdate) {
latestByKey, reErr := l.svcCtx.AgentConfigModel.FindOneByConfigKey(l.ctx, key)
if reErr != nil {
if errors.Is(reErr, model.ErrNotFound) {
cfg := &model.AgentConfig{
ConfigKey: key,
ConfigValue: valStr,
ConfigType: configTypeForKey(key),
Description: sql.NullString{},
DeleteTime: sql.NullTime{},
Version: 0,
}
_, insErr := l.svcCtx.AgentConfigModel.Insert(l.ctx, nil, cfg)
if insErr != nil {
return errors.Wrapf(insErr, "创建配置失败, key: %s", key)
}
return nil
}
return errors.Wrapf(reErr, "查询最新配置失败, key: %s", key)
}
latestByKey.ConfigValue = valStr
return l.svcCtx.AgentConfigModel.UpdateWithVersion(l.ctx, nil, latestByKey)
}
return uErr
}
return nil
}
// 更新等级加成配置
@@ -118,6 +180,13 @@ func (l *AdminUpdateAgentConfigLogic) AdminUpdateAgentConfig(req *types.AdminUpd
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新免税额度失败, %v", err)
}
if err := updateConfig("gold_max_uplift_amount", req.GoldMaxUpliftAmount); err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新黄金代理最高价上调金额失败, %v", err)
}
if err := updateConfig("diamond_max_uplift_amount", req.DiamondMaxUpliftAmount); err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新钻石代理最高价上调金额失败, %v", err)
}
return &types.AdminUpdateAgentConfigResp{
Success: true,
}, nil

View File

@@ -40,7 +40,7 @@ func (l *AdminBatchUpdateApiStatusLogic) AdminBatchUpdateApiStatus(req *types.Ad
// 2. 批量更新API状态
successCount := 0
for _, id := range req.Ids {
if id <= 0 {
if id == "" {
continue
}
@@ -50,7 +50,7 @@ func (l *AdminBatchUpdateApiStatusLogic) AdminBatchUpdateApiStatus(req *types.Ad
if errors.Is(err, model.ErrNotFound) {
continue // 跳过不存在的API
}
logx.Errorf("查询API失败, err: %v, id: %d", err, id)
logx.Errorf("查询API失败, err: %v, id: %s", err, id)
continue
}

View File

@@ -8,6 +8,7 @@ import (
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
)
@@ -58,6 +59,7 @@ func (l *AdminCreateApiLogic) AdminCreateApi(req *types.AdminCreateApiReq) (resp
// 3. 创建API记录
apiData := &model.AdminApi{
Id: uuid.NewString(),
ApiName: req.ApiName,
ApiCode: req.ApiCode,
Method: req.Method,
@@ -71,8 +73,7 @@ func (l *AdminCreateApiLogic) AdminCreateApi(req *types.AdminCreateApiReq) (resp
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
"创建API失败, err: %v", err)
}
// 4. 返回结果
apiId, _ := result.LastInsertId()
return &types.AdminCreateApiResp{Id: apiId}, nil
_ = result
return &types.AdminCreateApiResp{Id: apiData.Id}, nil
}

View File

@@ -28,9 +28,9 @@ func NewAdminDeleteApiLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ad
func (l *AdminDeleteApiLogic) AdminDeleteApi(req *types.AdminDeleteApiReq) (resp *types.AdminDeleteApiResp, err error) {
// 1. 参数验证
if req.Id <= 0 {
if req.Id == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
"API ID必须大于0, id: %d", req.Id)
"API ID不能为空, id: %s", req.Id)
}
// 2. 查询API是否存在

View File

@@ -28,9 +28,9 @@ func NewAdminGetApiDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *AdminGetApiDetailLogic) AdminGetApiDetail(req *types.AdminGetApiDetailReq) (resp *types.AdminGetApiDetailResp, err error) {
// 1. 参数验证
if req.Id <= 0 {
if req.Id == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
"API ID必须大于0, id: %d", req.Id)
"API ID不能为空, id: %s", req.Id)
}
// 2. 查询API详情

View File

@@ -28,9 +28,9 @@ func NewAdminUpdateApiLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ad
func (l *AdminUpdateApiLogic) AdminUpdateApi(req *types.AdminUpdateApiReq) (resp *types.AdminUpdateApiResp, err error) {
// 1. 参数验证
if req.Id <= 0 {
if req.Id == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
"API ID必须大于0, id: %d", req.Id)
"API ID不能为空, id: %s", req.Id)
}
if req.ApiName == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),

View File

@@ -57,7 +57,7 @@ func (l *AdminLoginLogic) AdminLogin(req *types.AdminLoginReq) (resp *types.Admi
}
// 获取角色ID数组
roleIds := make([]int64, 0)
roleIds := make([]string, 0)
for _, permission := range permissions {
roleIds = append(roleIds, permission.RoleId)
}
@@ -77,7 +77,7 @@ func (l *AdminLoginLogic) AdminLogin(req *types.AdminLoginReq) (resp *types.Admi
expiresAt := l.svcCtx.Config.AdminConfig.AccessExpire
claims := jwtx.JwtClaims{
UserId: user.Id,
AgentId: 0,
AgentId: "",
Platform: model.PlatformAdmin,
UserType: model.UserTypeAdmin,
IsAgent: model.AgentStatusNo,

View File

@@ -1,17 +1,18 @@
package admin_feature
import (
"context"
"encoding/hex"
"context"
"encoding/hex"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/crypto"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/crypto"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/google/uuid"
)
type AdminConfigFeatureExampleLogic struct {
@@ -62,11 +63,12 @@ func (l *AdminConfigFeatureExampleLogic) AdminConfigFeatureExample(req *types.Ad
}
// 4. 准备示例数据
exampleData := &model.Example{
ApiId: feature.ApiId,
FeatureId: req.FeatureId,
Content: encryptedData,
}
exampleData := &model.Example{
Id: uuid.NewString(),
ApiId: feature.ApiId,
FeatureId: req.FeatureId,
Content: encryptedData,
}
// 4. 根据是否存在决定新增或更新
if existingExample == nil {

View File

@@ -8,6 +8,7 @@ import (
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
)
@@ -29,6 +30,7 @@ func NewAdminCreateFeatureLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *AdminCreateFeatureLogic) AdminCreateFeature(req *types.AdminCreateFeatureReq) (resp *types.AdminCreateFeatureResp, err error) {
// 1. 数据转换
data := &model.Feature{
Id: uuid.NewString(),
ApiId: req.ApiId,
Name: req.Name,
}
@@ -41,6 +43,6 @@ func (l *AdminCreateFeatureLogic) AdminCreateFeature(req *types.AdminCreateFeatu
}
// 3. 返回结果
id, _ := result.LastInsertId()
return &types.AdminCreateFeatureResp{Id: id}, nil
_ = result
return &types.AdminCreateFeatureResp{Id: data.Id}, nil
}

View File

@@ -35,7 +35,7 @@ func (l *AdminGetFeatureExampleLogic) AdminGetFeatureExample(req *types.AdminGet
if errors.Is(err, model.ErrNotFound) {
// 示例数据不存在,返回空数据
return &types.AdminGetFeatureExampleResp{
Id: 0,
Id: "",
FeatureId: req.FeatureId,
ApiId: "",
Data: "",

View File

@@ -27,9 +27,9 @@ func NewAdminUpdateFeatureLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *AdminUpdateFeatureLogic) AdminUpdateFeature(req *types.AdminUpdateFeatureReq) (resp *types.AdminUpdateFeatureResp, err error) {
// 1. 参数验证
if req.Id <= 0 {
if req.Id == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
"功能ID必须大于0, id: %d", req.Id)
"功能ID不能为空, id: %s", req.Id)
}
// 2. 查询记录是否存在

View File

@@ -1,18 +1,19 @@
package admin_menu
import (
"context"
"database/sql"
"encoding/json"
"time"
"context"
"database/sql"
"encoding/json"
"time"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/google/uuid"
)
type CreateMenuLogic struct {
@@ -48,13 +49,13 @@ func (l *CreateMenuLogic) CreateMenu(req *types.CreateMenuReq) (resp *types.Crea
}
// 3. 检查父菜单是否存在(如果不是根菜单)
if req.Pid > 0 {
if req.Pid != "" {
parentMenu, err := l.svcCtx.AdminMenuModel.FindOne(l.ctx, req.Pid)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询父菜单失败, id: %d, err: %v", req.Pid, err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询父菜单失败, id: %s, err: %v", req.Pid, err)
}
if parentMenu == nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "父菜单不存在, id: %d", req.Pid)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "父菜单不存在, id: %s", req.Pid)
}
}
@@ -65,18 +66,19 @@ func (l *CreateMenuLogic) CreateMenu(req *types.CreateMenuReq) (resp *types.Crea
}
// 5. 创建菜单记录
menu := &model.AdminMenu{
Pid: req.Pid,
Name: req.Name,
Path: req.Path,
Component: req.Component,
Redirect: sql.NullString{String: req.Redirect, Valid: req.Redirect != ""},
Status: req.Status,
Type: typeValue,
Sort: req.Sort,
CreateTime: time.Now(),
UpdateTime: time.Now(),
}
menu := &model.AdminMenu{
Id: uuid.NewString(),
Pid: sql.NullString{String: req.Pid, Valid: req.Pid != ""},
Name: req.Name,
Path: req.Path,
Component: req.Component,
Redirect: sql.NullString{String: req.Redirect, Valid: req.Redirect != ""},
Status: req.Status,
Type: typeValue,
Sort: req.Sort,
CreateTime: time.Now(),
UpdateTime: time.Now(),
}
// 将Meta转换为JSON字符串
metaJson, err := json.Marshal(req.Meta)

View File

@@ -27,16 +27,16 @@ func NewDeleteMenuLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Delete
func (l *DeleteMenuLogic) DeleteMenu(req *types.DeleteMenuReq) (resp *types.DeleteMenuResp, err error) {
// 1. 参数验证
if req.Id <= 0 {
if req.Id == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
"菜单ID必须大于0, id: %d", req.Id)
"菜单ID不能为空, id: %s", req.Id)
}
// 2. 查询菜单是否存在
menu, err := l.svcCtx.AdminMenuModel.FindOne(l.ctx, req.Id)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
"查找菜单失败, err: %v, id: %d", err, req.Id)
"查找菜单失败, err: %v, id: %s", err, req.Id)
}
// 3. 检查是否有子菜单

View File

@@ -2,8 +2,8 @@ package admin_menu
import (
"context"
"database/sql"
"sort"
"strconv"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
@@ -38,14 +38,14 @@ func (l *GetMenuAllLogic) GetMenuAll(req *types.GetMenuAllReq) (resp *[]types.Ge
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户ID失败, %+v", err)
}
// 使用MapReduceVoid并发获取用户角色
var roleIds []int64
// 使用MapReduceVoid并发获取用户角色UUID 字符串)
var roleIds []string
var permissions []*struct {
RoleId int64
RoleId string
}
type UserRoleResult struct {
RoleId int64
RoleId string
}
err = mr.MapReduceVoid(
@@ -67,7 +67,7 @@ func (l *GetMenuAllLogic) GetMenuAll(req *types.GetMenuAllReq) (resp *[]types.Ge
},
func(pipe <-chan *UserRoleResult, cancel func(error)) {
for item := range pipe {
permissions = append(permissions, &struct{ RoleId int64 }{RoleId: item.RoleId})
permissions = append(permissions, &struct{ RoleId string }{RoleId: item.RoleId})
}
},
)
@@ -79,14 +79,14 @@ func (l *GetMenuAllLogic) GetMenuAll(req *types.GetMenuAllReq) (resp *[]types.Ge
roleIds = append(roleIds, permission.RoleId)
}
// 使用MapReduceVoid并发获取角色菜单
var menuIds []int64
// 使用MapReduceVoid并发获取角色菜单UUID 字符串)
var menuIds []string
var roleMenus []*struct {
MenuId int64
MenuId string
}
type RoleMenuResult struct {
MenuId int64
MenuId string
}
err = mr.MapReduceVoid(
@@ -108,7 +108,7 @@ func (l *GetMenuAllLogic) GetMenuAll(req *types.GetMenuAllReq) (resp *[]types.Ge
},
func(pipe <-chan *RoleMenuResult, cancel func(error)) {
for item := range pipe {
roleMenus = append(roleMenus, &struct{ MenuId int64 }{MenuId: item.MenuId})
roleMenus = append(roleMenus, &struct{ MenuId string }{MenuId: item.MenuId})
}
},
)
@@ -122,8 +122,8 @@ func (l *GetMenuAllLogic) GetMenuAll(req *types.GetMenuAllReq) (resp *[]types.Ge
// 使用MapReduceVoid并发获取菜单
type AdminMenuStruct struct {
Id int64
Pid int64
Id string
Pid sql.NullString
Name string
Path string
Component string
@@ -199,8 +199,7 @@ func (l *GetMenuAllLogic) GetMenuAll(req *types.GetMenuAllReq) (resp *[]types.Ge
return ""
}()
menuId := strconv.FormatInt(menu.Id, 10)
menuMap[menuId] = types.GetMenuAllResp{
menuMap[menu.Id] = types.GetMenuAllResp{
Name: menu.Name,
Path: menu.Path,
Redirect: redirect,
@@ -211,14 +210,17 @@ func (l *GetMenuAllLogic) GetMenuAll(req *types.GetMenuAllReq) (resp *[]types.Ge
}
}
// 按ParentId将菜单分组
menuGroups := lo.GroupBy(menus, func(item *AdminMenuStruct) int64 {
return item.Pid
// 按ParentId将菜单分组(字符串键)
menuGroups := lo.GroupBy(menus, func(item *AdminMenuStruct) string {
if item.Pid.Valid {
return item.Pid.String
}
return "0"
})
// 递归构建菜单树
var buildMenuTree func(parentId int64) []types.GetMenuAllResp
buildMenuTree = func(parentId int64) []types.GetMenuAllResp {
// 递归构建菜单树(字符串键)
var buildMenuTree func(parentId string) []types.GetMenuAllResp
buildMenuTree = func(parentId string) []types.GetMenuAllResp {
children := make([]types.GetMenuAllResp, 0)
childMenus, ok := menuGroups[parentId]
@@ -232,8 +234,7 @@ func (l *GetMenuAllLogic) GetMenuAll(req *types.GetMenuAllReq) (resp *[]types.Ge
})
for _, childMenu := range childMenus {
menuId := strconv.FormatInt(childMenu.Id, 10)
if menu, exists := menuMap[menuId]; exists && childMenu.Status == 1 {
if menu, exists := menuMap[childMenu.Id]; exists && childMenu.Status == 1 {
// 递归构建子菜单
menu.Children = buildMenuTree(childMenu.Id)
children = append(children, menu)
@@ -243,8 +244,8 @@ func (l *GetMenuAllLogic) GetMenuAll(req *types.GetMenuAllReq) (resp *[]types.Ge
return children
}
// 从根菜单开始构建ParentId为0的是根菜单)
menuTree := buildMenuTree(0)
// 从根菜单开始构建ParentId为"0"的是根菜单)
menuTree := buildMenuTree("0")
return &menuTree, nil
}

View File

@@ -54,7 +54,7 @@ func (l *GetMenuListLogic) GetMenuList(req *types.GetMenuListReq) (resp []types.
}
// 将菜单按ID存入map
menuMap := make(map[int64]types.MenuListItem)
menuMap := make(map[string]types.MenuListItem)
for _, menu := range menus {
var meta map[string]interface{}
err := json.Unmarshal([]byte(menu.Meta), &meta)
@@ -69,7 +69,7 @@ func (l *GetMenuListLogic) GetMenuList(req *types.GetMenuListReq) (resp []types.
}
item := types.MenuListItem{
Id: menu.Id,
Pid: menu.Pid,
Pid: menu.Pid.String,
Name: menu.Name,
Path: menu.Path,
Component: menu.Component,
@@ -86,13 +86,13 @@ func (l *GetMenuListLogic) GetMenuList(req *types.GetMenuListReq) (resp []types.
// 构建父子关系
for _, menu := range menus {
if menu.Pid > 0 {
if menu.Pid.Valid && menu.Pid.String != "0" {
// 找到父菜单
if parent, exists := menuMap[menu.Pid]; exists {
if parent, exists := menuMap[menu.Pid.String]; exists {
// 添加当前菜单到父菜单的子菜单列表
children := append(parent.Children, menuMap[menu.Id])
parent.Children = children
menuMap[menu.Pid] = parent
menuMap[menu.Pid.String] = parent
}
}
}
@@ -100,7 +100,7 @@ func (l *GetMenuListLogic) GetMenuList(req *types.GetMenuListReq) (resp []types.
// 提取顶级菜单ParentId为0到响应列表
result := make([]types.MenuListItem, 0)
for _, menu := range menus {
if menu.Pid == 0 {
if menu.Pid.Valid && menu.Pid.String == "0" {
result = append(result, menuMap[menu.Id])
}
}

View File

@@ -45,13 +45,13 @@ func (l *UpdateMenuLogic) UpdateMenu(req *types.UpdateMenuReq) (resp *types.Upda
}
// 3. 检查父菜单是否存在(如果不是根菜单)
if req.Pid > 0 {
parentMenu, err := l.svcCtx.AdminMenuModel.FindOne(l.ctx, req.Pid)
if req.Pid != nil && *req.Pid != "0" {
parentMenu, err := l.svcCtx.AdminMenuModel.FindOne(l.ctx, *req.Pid)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询父菜单失败, id: %d, err: %v", req.Pid, err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询父菜单失败, id: %s, err: %v", *req.Pid, err)
}
if parentMenu == nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "父菜单不存在, id: %d", req.Pid)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "父菜单不存在, id: %s", *req.Pid)
}
}
@@ -68,7 +68,7 @@ func (l *UpdateMenuLogic) UpdateMenu(req *types.UpdateMenuReq) (resp *types.Upda
// 5. 更新菜单信息
menu.Pid = req.Pid
menu.Pid = sql.NullString{String: *req.Pid, Valid: req.Pid != nil}
menu.Name = req.Name
menu.Path = req.Path
menu.Component = req.Component

View File

@@ -10,6 +10,7 @@ import (
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
)
@@ -32,6 +33,7 @@ func (l *AdminCreateNotificationLogic) AdminCreateNotification(req *types.AdminC
startDate, _ := time.Parse("2006-01-02", req.StartDate)
endDate, _ := time.Parse("2006-01-02", req.EndDate)
data := &model.GlobalNotifications{
Id: uuid.NewString(),
Title: req.Title,
Content: req.Content,
NotificationPage: req.NotificationPage,
@@ -45,6 +47,6 @@ func (l *AdminCreateNotificationLogic) AdminCreateNotification(req *types.AdminC
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建通知失败, err: %v, req: %+v", err, req)
}
id, _ := result.LastInsertId()
return &types.AdminCreateNotificationResp{Id: id}, nil
_ = result
return &types.AdminCreateNotificationResp{Id: data.Id}, nil
}

View File

@@ -11,6 +11,7 @@ import (
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
@@ -48,6 +49,7 @@ func (l *AdminCreateOrderLogic) AdminCreateOrder(req *types.AdminCreateOrderReq)
// 创建订单对象
order := &model.Order{
Id: uuid.NewString(),
OrderNo: orderNo,
PlatformOrderId: sql.NullString{String: req.PlatformOrderId, Valid: req.PlatformOrderId != ""},
ProductId: product.Id,
@@ -58,19 +60,14 @@ func (l *AdminCreateOrderLogic) AdminCreateOrder(req *types.AdminCreateOrderReq)
}
// 使用事务处理订单创建
var orderId int64
var orderId string
err = l.svcCtx.OrderModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
// 插入订单
result, err := l.svcCtx.OrderModel.Insert(ctx, session, order)
_, err := l.svcCtx.OrderModel.Insert(ctx, session, order)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "AdminCreateOrder, 创建订单失败 err: %v", err)
}
// 获取订单ID
orderId, err = result.LastInsertId()
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "AdminCreateOrder, 获取订单ID失败 err: %v", err)
}
orderId = order.Id
return nil
})

View File

@@ -97,16 +97,16 @@ func (l *AdminGetOrderListLogic) AdminGetOrderList(req *types.AdminGetOrderListR
}
// 并发获取产品信息和查询状态
productMap := make(map[int64]string)
queryStateMap := make(map[int64]string)
agentOrderMap := make(map[int64]bool) // 代理订单映射
agentProcessStatusMap := make(map[int64]string) // 代理处理状态映射
productMap := make(map[string]string)
queryStateMap := make(map[string]string)
agentOrderMap := make(map[string]bool) // 代理订单映射
agentProcessStatusMap := make(map[string]string) // 代理处理状态映射
var mu sync.Mutex
// 批量获取查询状态
if len(orders) > 0 {
orderIds := make([]int64, 0, len(orders))
orderIds := make([]string, 0, len(orders))
for _, order := range orders {
orderIds = append(orderIds, order.Id)
}
@@ -121,14 +121,14 @@ func (l *AdminGetOrderListLogic) AdminGetOrderList(req *types.AdminGetOrderListR
}
// 2. 记录已找到查询状态的订单ID
foundOrderIds := make(map[int64]bool)
foundOrderIds := make(map[string]bool)
for _, query := range queries {
queryStateMap[query.OrderId] = query.QueryState
foundOrderIds[query.OrderId] = true
}
// 3. 查找未找到查询状态的订单是否在清理日志中
notFoundOrderIds := make([]int64, 0)
notFoundOrderIds := make([]string, 0)
for _, orderId := range orderIds {
if !foundOrderIds[orderId] {
notFoundOrderIds = append(notFoundOrderIds, orderId)
@@ -175,7 +175,7 @@ func (l *AdminGetOrderListLogic) AdminGetOrderList(req *types.AdminGetOrderListR
// 对于代理订单,查询代理处理状态
if len(agentOrders) > 0 {
agentOrderIds := make([]int64, 0, len(agentOrders))
agentOrderIds := make([]string, 0, len(agentOrders))
for _, agentOrder := range agentOrders {
agentOrderIds = append(agentOrderIds, agentOrder.OrderId)
}
@@ -188,13 +188,13 @@ func (l *AdminGetOrderListLogic) AdminGetOrderList(req *types.AdminGetOrderListR
}
// 记录有佣金记录的订单为处理成功
processedOrderIds := make(map[int64]bool)
processedOrderIds := make(map[string]bool)
for _, commission := range commissions {
processedOrderIds[commission.OrderId] = true
}
// 创建订单状态映射,避免重复查找
orderStatusMap := make(map[int64]string)
orderStatusMap := make(map[string]string)
for _, order := range orders {
orderStatusMap[order.Id] = order.Status
}

View File

@@ -1,19 +1,20 @@
package admin_order
import (
"context"
"database/sql"
"fmt"
"time"
"context"
"database/sql"
"fmt"
"time"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/google/uuid"
)
const (
@@ -55,7 +56,7 @@ func (l *AdminRefundOrderLogic) AdminRefundOrder(req *types.AdminRefundOrderReq)
}
// getAndValidateOrder 获取并验证订单信息
func (l *AdminRefundOrderLogic) getAndValidateOrder(orderId int64, refundAmount float64) (*model.Order, error) {
func (l *AdminRefundOrderLogic) getAndValidateOrder(orderId string, refundAmount float64) (*model.Order, error) {
order, err := l.svcCtx.OrderModel.FindOne(l.ctx, orderId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "AdminRefundOrder, 查询订单失败 err: %v", err)
@@ -132,17 +133,18 @@ func (l *AdminRefundOrderLogic) handleWechatRefund(order *model.Order, req *type
func (l *AdminRefundOrderLogic) createRefundRecordAndUpdateOrder(order *model.Order, req *types.AdminRefundOrderReq, refundNo, platformRefundId, orderStatus, refundStatus string) error {
return l.svcCtx.OrderModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
// 创建退款记录
refund := &model.OrderRefund{
RefundNo: refundNo,
PlatformRefundId: l.createNullString(platformRefundId),
OrderId: order.Id,
UserId: order.UserId,
ProductId: order.ProductId,
RefundAmount: req.RefundAmount,
RefundReason: l.createNullString(req.RefundReason),
Status: refundStatus, // 使用传入的状态,不再硬编码
RefundTime: sql.NullTime{Time: time.Now(), Valid: true},
}
refund := &model.OrderRefund{
Id: uuid.NewString(),
RefundNo: refundNo,
PlatformRefundId: l.createNullString(platformRefundId),
OrderId: order.Id,
UserId: order.UserId,
ProductId: order.ProductId,
RefundAmount: req.RefundAmount,
RefundReason: l.createNullString(req.RefundReason),
Status: refundStatus, // 使用传入的状态,不再硬编码
RefundTime: sql.NullTime{Time: time.Now(), Valid: true},
}
if _, err := l.svcCtx.OrderRefundModel.Insert(ctx, session, refund); err != nil {
return fmt.Errorf("创建退款记录失败: %v", err)
@@ -160,17 +162,18 @@ func (l *AdminRefundOrderLogic) createRefundRecordAndUpdateOrder(order *model.Or
// createRefundRecordOnly 仅创建退款记录,不更新订单状态(用于退款失败的情况)
func (l *AdminRefundOrderLogic) createRefundRecordOnly(order *model.Order, req *types.AdminRefundOrderReq, refundNo, platformRefundId, refundStatus string) error {
refund := &model.OrderRefund{
RefundNo: refundNo,
PlatformRefundId: l.createNullString(platformRefundId),
OrderId: order.Id,
UserId: order.UserId,
ProductId: order.ProductId,
RefundAmount: req.RefundAmount,
RefundReason: l.createNullString(req.RefundReason),
Status: refundStatus,
RefundTime: sql.NullTime{Time: time.Now(), Valid: true},
}
refund := &model.OrderRefund{
Id: uuid.NewString(),
RefundNo: refundNo,
PlatformRefundId: l.createNullString(platformRefundId),
OrderId: order.Id,
UserId: order.UserId,
ProductId: order.ProductId,
RefundAmount: req.RefundAmount,
RefundReason: l.createNullString(req.RefundReason),
Status: refundStatus,
RefundTime: sql.NullTime{Time: time.Now(), Valid: true},
}
_, err := l.svcCtx.OrderRefundModel.Insert(l.ctx, nil, refund)
if err != nil {

View File

@@ -11,6 +11,7 @@ import (
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/google/uuid"
)
type AdminCreatePlatformUserLogic struct {
@@ -37,21 +38,19 @@ func (l *AdminCreatePlatformUserLogic) AdminCreatePlatformUser(req *types.AdminC
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询手机号失败: %v", err)
}
user := &model.User{
Mobile: sql.NullString{String: req.Mobile, Valid: req.Mobile != ""},
Password: sql.NullString{String: req.Password, Valid: req.Password != ""},
Nickname: sql.NullString{String: req.Nickname, Valid: req.Nickname != ""},
Info: req.Info,
Inside: req.Inside,
}
result, err := l.svcCtx.UserModel.Insert(l.ctx, nil, user)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建用户失败: %v", err)
}
id, err := result.LastInsertId()
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取用户ID失败: %v", err)
}
resp = &types.AdminCreatePlatformUserResp{Id: id}
return resp, nil
user := &model.User{
Id: uuid.NewString(),
Mobile: sql.NullString{String: req.Mobile, Valid: req.Mobile != ""},
Password: sql.NullString{String: req.Password, Valid: req.Password != ""},
Nickname: sql.NullString{String: req.Nickname, Valid: req.Nickname != ""},
Info: req.Info,
Inside: req.Inside,
}
result, err := l.svcCtx.UserModel.Insert(l.ctx, nil, user)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建用户失败: %v", err)
}
_ = result
resp = &types.AdminCreatePlatformUserResp{Id: user.Id}
return resp, nil
}

View File

@@ -8,6 +8,7 @@ import (
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
@@ -30,6 +31,7 @@ func NewAdminCreateProductLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *AdminCreateProductLogic) AdminCreateProduct(req *types.AdminCreateProductReq) (resp *types.AdminCreateProductResp, err error) {
// 1. 数据转换
data := &model.Product{
Id: uuid.NewString(),
ProductName: req.ProductName,
ProductEn: req.ProductEn,
Description: req.Description,
@@ -39,23 +41,19 @@ func (l *AdminCreateProductLogic) AdminCreateProduct(req *types.AdminCreateProdu
}
// 2. 数据库操作(使用事务确保产品表和代理产品配置表同步)
var productId int64
var productId string
err = l.svcCtx.ProductModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
// 2.1 插入产品
result, err := l.svcCtx.ProductModel.Insert(ctx, session, data)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
"创建产品失败, err: %v, req: %+v", err, req)
}
productId, err = result.LastInsertId()
_, err := l.svcCtx.ProductModel.Insert(ctx, session, data)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
"获取产品ID失败, err: %v", err)
"创建产品失败, err: %v, req: %+v", err, req)
}
productId = data.Id
// 2.2 同步创建代理产品配置(使用默认值)
agentProductConfig := &model.AgentProductConfig{
Id: uuid.NewString(),
ProductId: productId,
BasePrice: 0.00, // 默认基础底价
SystemMaxPrice: 9999.99, // 默认系统价格上限
@@ -66,7 +64,7 @@ func (l *AdminCreateProductLogic) AdminCreateProduct(req *types.AdminCreateProdu
_, err = l.svcCtx.AgentProductConfigModel.Insert(ctx, session, agentProductConfig)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
"创建代理产品配置失败, err: %v, productId: %d", err, productId)
"创建代理产品配置失败, err: %v, productId: %s", err, productId)
}
return nil

View File

@@ -39,7 +39,7 @@ func (l *AdminGetProductFeatureListLogic) AdminGetProductFeatureList(req *types.
}
// 3. 获取所有功能ID
featureIds := make([]int64, 0, len(list))
featureIds := make([]string, 0, len(list))
for _, item := range list {
featureIds = append(featureIds, item.FeatureId)
}
@@ -55,13 +55,13 @@ func (l *AdminGetProductFeatureListLogic) AdminGetProductFeatureList(req *types.
for i, id := range featureIds {
source <- struct {
index int
id int64
id string
}{i, id}
}
}, func(item interface{}, writer mr.Writer[featureResult], cancel func(error)) {
data := item.(struct {
index int
id int64
id string
})
feature, err := l.svcCtx.FeatureModel.FindOne(l.ctx, data.id)
writer.Write(featureResult{
@@ -71,7 +71,7 @@ func (l *AdminGetProductFeatureListLogic) AdminGetProductFeatureList(req *types.
}, func(pipe <-chan featureResult, cancel func(error)) {
for result := range pipe {
if result.err != nil {
l.Logger.Errorf("查询功能详情失败, feature_id: %d, err: %v", result.feature.Id, result.err)
l.Logger.Errorf("查询功能详情失败, feature_id: %s, err: %v", result.feature.Id, result.err)
continue
}
results = append(results, result)
@@ -84,7 +84,7 @@ func (l *AdminGetProductFeatureListLogic) AdminGetProductFeatureList(req *types.
}
// 5. 构建功能ID到详情的映射
featureMap := make(map[int64]*model.Feature)
featureMap := make(map[string]*model.Feature)
for _, result := range results {
if result.feature != nil {
featureMap[result.feature.Id] = result.feature

View File

@@ -1,17 +1,18 @@
package admin_product
import (
"context"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"sync"
"context"
"sync"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/mr"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/mr"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/google/uuid"
)
type AdminUpdateProductFeaturesLogic struct {
@@ -39,13 +40,13 @@ func (l *AdminUpdateProductFeaturesLogic) AdminUpdateProductFeatures(req *types.
}
// 2. 构建现有关联的映射
existingMap := make(map[int64]*model.ProductFeature)
existingMap := make(map[string]*model.ProductFeature)
for _, item := range existingList {
existingMap[item.FeatureId] = item
}
// 3. 构建新关联的映射
newMap := make(map[int64]*types.ProductFeatureItem)
newMap := make(map[string]*types.ProductFeatureItem)
for _, item := range req.Features {
newMap[item.FeatureId] = &item
}
@@ -54,7 +55,7 @@ func (l *AdminUpdateProductFeaturesLogic) AdminUpdateProductFeatures(req *types.
err = l.svcCtx.ProductFeatureModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
// 4.1 处理需要删除的关联
var mu sync.Mutex
var deleteIds []int64
var deleteIds []string
err = mr.MapReduceVoid(func(source chan<- interface{}) {
for featureId, existing := range existingMap {
if _, exists := newMap[featureId]; !exists {
@@ -62,7 +63,7 @@ func (l *AdminUpdateProductFeaturesLogic) AdminUpdateProductFeatures(req *types.
}
}
}, func(item interface{}, writer mr.Writer[struct{}], cancel func(error)) {
id := item.(int64)
id := item.(string)
mu.Lock()
deleteIds = append(deleteIds, id)
mu.Unlock()
@@ -90,7 +91,7 @@ func (l *AdminUpdateProductFeaturesLogic) AdminUpdateProductFeatures(req *types.
err = mr.MapReduceVoid(func(source chan<- interface{}) {
for featureId, newItem := range newMap {
source <- struct {
featureId int64
featureId string
newItem *types.ProductFeatureItem
existing *model.ProductFeature
}{
@@ -101,7 +102,7 @@ func (l *AdminUpdateProductFeaturesLogic) AdminUpdateProductFeatures(req *types.
}
}, func(item interface{}, writer mr.Writer[struct{}], cancel func(error)) {
data := item.(struct {
featureId int64
featureId string
newItem *types.ProductFeatureItem
existing *model.ProductFeature
})
@@ -119,14 +120,15 @@ func (l *AdminUpdateProductFeaturesLogic) AdminUpdateProductFeatures(req *types.
return
}
} else {
// 新增关联
newFeature := &model.ProductFeature{
ProductId: req.ProductId,
FeatureId: data.featureId,
Sort: data.newItem.Sort,
Enable: data.newItem.Enable,
IsImportant: data.newItem.IsImportant,
}
// 新增关联
newFeature := &model.ProductFeature{
Id: uuid.NewString(),
ProductId: req.ProductId,
FeatureId: data.featureId,
Sort: data.newItem.Sort,
Enable: data.newItem.Enable,
IsImportant: data.newItem.IsImportant,
}
_, err = l.svcCtx.ProductFeatureModel.Insert(ctx, session, newFeature)
if err != nil {
updateErr = errors.Wrapf(err, "新增产品功能关联失败, product_id: %d, feature_id: %d",

View File

@@ -2,12 +2,12 @@ package admin_query
import (
"context"
"sync"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/globalkey"
"ycc-server/common/xerr"
"sync"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
@@ -66,23 +66,23 @@ func (l *AdminGetQueryCleanupDetailListLogic) AdminGetQueryCleanupDetailList(req
}
// 4. 获取所有产品ID
productIds := make([]int64, 0, len(details))
productIds := make([]string, 0, len(details))
for _, detail := range details {
productIds = append(productIds, detail.ProductId)
}
// 5. 并发获取产品信息
productMap := make(map[int64]string)
productMap := make(map[string]string)
var mu sync.Mutex
err = mr.MapReduceVoid(func(source chan<- interface{}) {
for _, productId := range productIds {
source <- productId
}
}, func(item interface{}, writer mr.Writer[struct{}], cancel func(error)) {
productId := item.(int64)
productId := item.(string)
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, productId)
if err != nil && !errors.Is(err, model.ErrNotFound) {
cancel(errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询产品信息失败, product_id: %d, err: %v", productId, err))
cancel(errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询产品信息失败, product_id: %s, err: %v", productId, err))
return
}
mu.Lock()

View File

@@ -135,7 +135,7 @@ func ProcessQueryParams(QueryParams string, target *map[string]interface{}, key
return nil
}
func (l *AdminGetQueryDetailByOrderIdLogic) UpdateFeatureAndProductFeature(productID int64, target *[]types.AdminQueryItem) error {
func (l *AdminGetQueryDetailByOrderIdLogic) UpdateFeatureAndProductFeature(productID string, target *[]types.AdminQueryItem) error {
// 遍历 target 数组,使用倒序遍历,以便删除元素时不影响索引
for i := len(*target) - 1; i >= 0; i-- {
queryItem := &(*target)[i]

View File

@@ -11,6 +11,7 @@ import (
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/google/uuid"
)
type CreateRoleLogic struct {
@@ -37,37 +38,36 @@ func (l *CreateRoleLogic) CreateRole(req *types.CreateRoleReq) (resp *types.Crea
return nil, errors.Wrapf(xerr.NewErrMsg("角色名称已存在"), "创建角色失败, 角色名称已存在: %v", err)
}
// 创建角色
role := &model.AdminRole{
RoleName: req.RoleName,
RoleCode: req.RoleCode,
Description: req.Description,
Status: req.Status,
Sort: req.Sort,
}
var roleId int64
role := &model.AdminRole{
Id: uuid.NewString(),
RoleName: req.RoleName,
RoleCode: req.RoleCode,
Description: req.Description,
Status: req.Status,
Sort: req.Sort,
}
var roleId string
// 使用事务创建角色和关联菜单
err = l.svcCtx.AdminRoleModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
// 创建角色
result, err := l.svcCtx.AdminRoleModel.Insert(ctx, session, role)
if err != nil {
return errors.New("插入新角色失败")
}
roleId, err = result.LastInsertId()
if err != nil {
return errors.New("获取新角色ID失败")
}
_, err := l.svcCtx.AdminRoleModel.Insert(ctx, session, role)
if err != nil {
return errors.New("插入新角色失败")
}
roleId = role.Id
// 创建角色菜单关联
if len(req.MenuIds) > 0 {
for _, menuId := range req.MenuIds {
roleMenu := &model.AdminRoleMenu{
RoleId: roleId,
MenuId: menuId,
}
_, err = l.svcCtx.AdminRoleMenuModel.Insert(ctx, session, roleMenu)
if err != nil {
return errors.New("插入角色菜单关联失败")
}
roleMenu := &model.AdminRoleMenu{
Id: uuid.NewString(),
RoleId: roleId,
MenuId: menuId,
}
_, err = l.svcCtx.AdminRoleMenuModel.Insert(ctx, session, roleMenu)
if err != nil {
return errors.New("插入角色菜单关联失败")
}
}
}
@@ -77,7 +77,7 @@ func (l *CreateRoleLogic) CreateRole(req *types.CreateRoleReq) (resp *types.Crea
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建角色失败: %v", err)
}
return &types.CreateRoleResp{
Id: roleId,
}, nil
return &types.CreateRoleResp{
Id: roleId,
}, nil
}

View File

@@ -32,7 +32,7 @@ func NewGetRoleDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Get
func (l *GetRoleDetailLogic) GetRoleDetail(req *types.GetRoleDetailReq) (resp *types.GetRoleDetailResp, err error) {
// 使用MapReduceVoid并发获取角色信息和菜单ID
var role *model.AdminRole
var menuIds []int64
var menuIds []string
var mutex sync.Mutex
var wg sync.WaitGroup
@@ -62,7 +62,7 @@ func (l *GetRoleDetailLogic) GetRoleDetail(req *types.GetRoleDetailReq) (resp *t
return
}
mutex.Lock()
menuIds = lo.Map(menus, func(item *model.AdminRoleMenu, _ int) int64 {
menuIds = lo.Map(menus, func(item *model.AdminRoleMenu, _ int) string {
return item.MenuId
})
mutex.Unlock()

View File

@@ -106,7 +106,7 @@ func (l *GetRoleListLogic) GetRoleList(req *types.GetRoleListReq) (resp *types.G
for _, role := range roles {
source <- role
}
}, func(item interface{}, writer mr.Writer[[]int64], cancel func(error)) {
}, func(item interface{}, writer mr.Writer[[]string], cancel func(error)) {
role := item.(*model.AdminRole)
// 获取角色关联的菜单ID
@@ -117,12 +117,12 @@ func (l *GetRoleListLogic) GetRoleList(req *types.GetRoleListReq) (resp *types.G
cancel(err)
return
}
menuIds := lo.Map(menus, func(item *model.AdminRoleMenu, _ int) int64 {
menuIds := lo.Map(menus, func(item *model.AdminRoleMenu, _ int) string {
return item.MenuId
})
writer.Write(menuIds)
}, func(pipe <-chan []int64, cancel func(error)) {
}, func(pipe <-chan []string, cancel func(error)) {
for _, role := range roles {
menuIds := <-pipe
item := types.RoleListItem{

View File

@@ -1,17 +1,18 @@
package admin_role
import (
"context"
"context"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/pkg/errors"
"github.com/samber/lo"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/pkg/errors"
"github.com/samber/lo"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/google/uuid"
)
type UpdateRoleLogic struct {
@@ -83,7 +84,7 @@ func (l *UpdateRoleLogic) UpdateRole(req *types.UpdateRoleReq) (resp *types.Upda
}
// 2. 转换为map便于查找
currentMenuMap := make(map[int64]*model.AdminRoleMenu)
currentMenuMap := make(map[string]*model.AdminRoleMenu)
for _, menu := range currentMenus {
currentMenuMap[menu.MenuId] = menu
}
@@ -92,13 +93,13 @@ func (l *UpdateRoleLogic) UpdateRole(req *types.UpdateRoleReq) (resp *types.Upda
for _, menuId := range req.MenuIds {
exists, err := l.svcCtx.AdminMenuModel.FindOne(ctx, menuId)
if err != nil || exists == nil {
return errors.Wrapf(xerr.NewErrMsg("菜单不存在"), "菜单ID: %d", menuId)
return errors.Wrapf(xerr.NewErrMsg("菜单不存在"), "菜单ID: %s", menuId)
}
}
// 4. 找出需要删除和新增的关联
var toDelete []*model.AdminRoleMenu
var toInsert []int64
var toInsert []string
// 需要删除的:当前存在但新列表中没有的
for menuId, roleMenu := range currentMenuMap {
@@ -123,16 +124,17 @@ func (l *UpdateRoleLogic) UpdateRole(req *types.UpdateRoleReq) (resp *types.Upda
}
// 6. 添加新的关联
for _, menuId := range toInsert {
roleMenu := &model.AdminRoleMenu{
RoleId: req.Id,
MenuId: menuId,
}
_, err = l.svcCtx.AdminRoleMenuModel.Insert(ctx, session, roleMenu)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "添加角色菜单关联失败: %v", err)
}
}
for _, menuId := range toInsert {
roleMenu := &model.AdminRoleMenu{
Id: uuid.NewString(),
RoleId: req.Id,
MenuId: menuId,
}
_, err = l.svcCtx.AdminRoleMenuModel.Insert(ctx, session, roleMenu)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "添加角色菜单关联失败: %v", err)
}
}
}
return nil

View File

@@ -1,15 +1,16 @@
package admin_role_api
import (
"context"
"context"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/google/uuid"
)
type AdminAssignRoleApiLogic struct {
@@ -28,9 +29,9 @@ func NewAdminAssignRoleApiLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *AdminAssignRoleApiLogic) AdminAssignRoleApi(req *types.AdminAssignRoleApiReq) (resp *types.AdminAssignRoleApiResp, err error) {
// 1. 参数验证
if req.RoleId <= 0 {
if req.RoleId == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
"角色ID必须大于0, roleId: %d", req.RoleId)
"角色ID不能为空, roleId: %s", req.RoleId)
}
if len(req.ApiIds) == 0 {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
@@ -51,7 +52,7 @@ func (l *AdminAssignRoleApiLogic) AdminAssignRoleApi(req *types.AdminAssignRoleA
// 3. 批量分配API权限
successCount := 0
for _, apiId := range req.ApiIds {
if apiId <= 0 {
if apiId == "" {
continue
}
@@ -59,10 +60,10 @@ func (l *AdminAssignRoleApiLogic) AdminAssignRoleApi(req *types.AdminAssignRoleA
_, err := l.svcCtx.AdminApiModel.FindOne(l.ctx, apiId)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
logx.Errorf("API不存在, apiId: %d", apiId)
logx.Errorf("API不存在, apiId: %s", apiId)
continue
}
logx.Errorf("查询API失败, err: %v, apiId: %d", err, apiId)
logx.Errorf("查询API失败, err: %v, apiId: %s", err, apiId)
continue
}
@@ -77,10 +78,11 @@ func (l *AdminAssignRoleApiLogic) AdminAssignRoleApi(req *types.AdminAssignRoleA
}
// 创建关联
roleApiData := &model.AdminRoleApi{
RoleId: req.RoleId,
ApiId: apiId,
}
roleApiData := &model.AdminRoleApi{
Id: uuid.NewString(),
RoleId: req.RoleId,
ApiId: apiId,
}
_, err = l.svcCtx.AdminRoleApiModel.Insert(l.ctx, nil, roleApiData)
if err != nil {

View File

@@ -28,7 +28,7 @@ func NewAdminGetAllApiListLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *AdminGetAllApiListLogic) AdminGetAllApiList(req *types.AdminGetAllApiListReq) (resp *types.AdminGetAllApiListResp, err error) {
// 1. 构建查询条件
builder := l.svcCtx.AdminApiModel.SelectBuilder()
// 添加状态过滤
if req.Status > 0 {
builder = builder.Where("status = ?", req.Status)
@@ -45,8 +45,8 @@ func (l *AdminGetAllApiListLogic) AdminGetAllApiList(req *types.AdminGetAllApiLi
var apiList []types.AdminRoleApiInfo
for _, api := range apis {
apiList = append(apiList, types.AdminRoleApiInfo{
Id: 0, // 这里不是关联ID而是API ID
RoleId: 0, // 这里不是角色ID
Id: api.Id,
RoleId: "",
ApiId: api.Id,
ApiName: api.ApiName,
ApiCode: api.ApiCode,

View File

@@ -28,9 +28,9 @@ func NewAdminGetRoleApiListLogic(ctx context.Context, svcCtx *svc.ServiceContext
func (l *AdminGetRoleApiListLogic) AdminGetRoleApiList(req *types.AdminGetRoleApiListReq) (resp *types.AdminGetRoleApiListResp, err error) {
// 1. 参数验证
if req.RoleId <= 0 {
if req.RoleId == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
"角色ID必须大于0, roleId: %d", req.RoleId)
"角色ID不能为空, roleId: %s", req.RoleId)
}
// 2. 查询角色是否存在
@@ -38,7 +38,7 @@ func (l *AdminGetRoleApiListLogic) AdminGetRoleApiList(req *types.AdminGetRoleAp
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
"角色不存在, roleId: %d", req.RoleId)
"角色不存在, roleId: %s", req.RoleId)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
"查询角色失败, err: %v, roleId: %d", err, req.RoleId)
@@ -47,7 +47,7 @@ func (l *AdminGetRoleApiListLogic) AdminGetRoleApiList(req *types.AdminGetRoleAp
// 3. 查询角色API权限列表
builder := l.svcCtx.AdminRoleApiModel.SelectBuilder().
Where("role_id = ?", req.RoleId)
roleApis, err := l.svcCtx.AdminRoleApiModel.FindAll(l.ctx, builder, "")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),

View File

@@ -28,9 +28,9 @@ func NewAdminRemoveRoleApiLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *AdminRemoveRoleApiLogic) AdminRemoveRoleApi(req *types.AdminRemoveRoleApiReq) (resp *types.AdminRemoveRoleApiResp, err error) {
// 1. 参数验证
if req.RoleId <= 0 {
if req.RoleId == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
"角色ID必须大于0, roleId: %d", req.RoleId)
"角色ID不能为空, roleId: %s", req.RoleId)
}
if len(req.ApiIds) == 0 {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
@@ -51,7 +51,7 @@ func (l *AdminRemoveRoleApiLogic) AdminRemoveRoleApi(req *types.AdminRemoveRoleA
// 3. 批量移除API权限
successCount := 0
for _, apiId := range req.ApiIds {
if apiId <= 0 {
if apiId == "" {
continue
}
@@ -61,7 +61,7 @@ func (l *AdminRemoveRoleApiLogic) AdminRemoveRoleApi(req *types.AdminRemoveRoleA
if errors.Is(err, model.ErrNotFound) {
continue // 不存在,跳过
}
logx.Errorf("查询角色API关联失败, err: %v, roleId: %d, apiId: %d", err, req.RoleId, apiId)
logx.Errorf("查询角色API关联失败, err: %v, roleId: %s, apiId: %s", err, req.RoleId, apiId)
continue
}

View File

@@ -1,15 +1,16 @@
package admin_role_api
import (
"context"
"context"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/google/uuid"
)
type AdminUpdateRoleApiLogic struct {
@@ -28,9 +29,9 @@ func NewAdminUpdateRoleApiLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *AdminUpdateRoleApiLogic) AdminUpdateRoleApi(req *types.AdminUpdateRoleApiReq) (resp *types.AdminUpdateRoleApiResp, err error) {
// 1. 参数验证
if req.RoleId <= 0 {
if req.RoleId == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
"角色ID必须大于0, roleId: %d", req.RoleId)
"角色ID不能为空, roleId: %s", req.RoleId)
}
// 2. 查询角色是否存在
@@ -38,10 +39,10 @@ func (l *AdminUpdateRoleApiLogic) AdminUpdateRoleApi(req *types.AdminUpdateRoleA
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
"角色不存在, roleId: %d", req.RoleId)
"角色不存在, roleId: %s", req.RoleId)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
"查询角色失败, err: %v, roleId: %d", err, req.RoleId)
"查询角色失败, err: %v, roleId: %s", err, req.RoleId)
}
// 3. 删除该角色的所有API权限
@@ -63,7 +64,7 @@ func (l *AdminUpdateRoleApiLogic) AdminUpdateRoleApi(req *types.AdminUpdateRoleA
// 4. 添加新的API权限
if len(req.ApiIds) > 0 {
for _, apiId := range req.ApiIds {
if apiId <= 0 {
if apiId == "" {
continue
}
@@ -71,18 +72,19 @@ func (l *AdminUpdateRoleApiLogic) AdminUpdateRoleApi(req *types.AdminUpdateRoleA
_, err := l.svcCtx.AdminApiModel.FindOne(l.ctx, apiId)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
logx.Errorf("API不存在, apiId: %d", apiId)
logx.Errorf("API不存在, apiId: %s", apiId)
continue
}
logx.Errorf("查询API失败, err: %v, apiId: %d", err, apiId)
logx.Errorf("查询API失败, err: %v, apiId: %s", err, apiId)
continue
}
// 创建新的关联
roleApiData := &model.AdminRoleApi{
RoleId: req.RoleId,
ApiId: apiId,
}
roleApiData := &model.AdminRoleApi{
Id: uuid.NewString(),
RoleId: req.RoleId,
ApiId: apiId,
}
_, err = l.svcCtx.AdminRoleApiModel.Insert(l.ctx, nil, roleApiData)
if err != nil {

View File

@@ -9,6 +9,7 @@ import (
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/crypto"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
@@ -43,8 +44,9 @@ func (l *AdminCreateUserLogic) AdminCreateUser(req *types.AdminCreateUserReq) (r
}
// 创建用户
user := &model.AdminUser{
Id: uuid.NewString(),
Username: req.Username,
Password: password, // 注意:实际应用中需要加密密码
Password: password,
RealName: req.RealName,
Status: req.Status,
}
@@ -52,20 +54,16 @@ func (l *AdminCreateUserLogic) AdminCreateUser(req *types.AdminCreateUserReq) (r
// 使用事务创建用户和关联角色
err = l.svcCtx.AdminUserModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
// 创建用户
result, err := l.svcCtx.AdminUserModel.Insert(ctx, session, user)
_, err := l.svcCtx.AdminUserModel.Insert(ctx, session, user)
if err != nil {
return err
}
userId, err := result.LastInsertId()
if err != nil {
return err
}
// 创建用户角色关联
if len(req.RoleIds) > 0 {
for _, roleId := range req.RoleIds {
userRole := &model.AdminUserRole{
UserId: userId,
Id: uuid.NewString(),
UserId: user.Id,
RoleId: roleId,
}
_, err = l.svcCtx.AdminUserRoleModel.Insert(ctx, session, userRole)

View File

@@ -31,7 +31,7 @@ func NewAdminGetUserDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *AdminGetUserDetailLogic) AdminGetUserDetail(req *types.AdminGetUserDetailReq) (resp *types.AdminGetUserDetailResp, err error) {
// 使用MapReduceVoid并发获取用户信息和角色ID
var user *model.AdminUser
var roleIds []int64
var roleIds []string
var mutex sync.Mutex
var wg sync.WaitGroup
@@ -61,7 +61,7 @@ func (l *AdminGetUserDetailLogic) AdminGetUserDetail(req *types.AdminGetUserDeta
return
}
mutex.Lock()
roleIds = lo.Map(roles, func(item *model.AdminUserRole, _ int) int64 {
roleIds = lo.Map(roles, func(item *model.AdminUserRole, _ int) string {
return item.RoleId
})
mutex.Unlock()

View File

@@ -109,7 +109,7 @@ func (l *AdminGetUserListLogic) AdminGetUserList(req *types.AdminGetUserListReq)
for _, user := range users {
source <- user
}
}, func(item interface{}, writer mr.Writer[[]int64], cancel func(error)) {
}, func(item interface{}, writer mr.Writer[[]string], cancel func(error)) {
user := item.(*model.AdminUser)
// 获取用户关联的角色ID
@@ -120,12 +120,12 @@ func (l *AdminGetUserListLogic) AdminGetUserList(req *types.AdminGetUserListReq)
cancel(err)
return
}
roleIds := lo.Map(roles, func(item *model.AdminUserRole, _ int) int64 {
roleIds := lo.Map(roles, func(item *model.AdminUserRole, _ int) string {
return item.RoleId
})
writer.Write(roleIds)
}, func(pipe <-chan []int64, cancel func(error)) {
}, func(pipe <-chan []string, cancel func(error)) {
for _, user := range users {
roleIds := <-pipe
item := types.AdminUserListItem{

View File

@@ -1,17 +1,18 @@
package admin_user
import (
"context"
"context"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/pkg/errors"
"github.com/samber/lo"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/pkg/errors"
"github.com/samber/lo"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/google/uuid"
)
type AdminUpdateUserLogic struct {
@@ -76,7 +77,7 @@ func (l *AdminUpdateUserLogic) AdminUpdateUser(req *types.AdminUpdateUserReq) (r
}
// 2. 转换为map便于查找
currentRoleMap := make(map[int64]*model.AdminUserRole)
currentRoleMap := make(map[string]*model.AdminUserRole)
for _, role := range currentRoles {
currentRoleMap[role.RoleId] = role
}
@@ -85,13 +86,13 @@ func (l *AdminUpdateUserLogic) AdminUpdateUser(req *types.AdminUpdateUserReq) (r
for _, roleId := range req.RoleIds {
exists, err := l.svcCtx.AdminRoleModel.FindOne(ctx, roleId)
if err != nil || exists == nil {
return errors.Wrapf(xerr.NewErrMsg("角色不存在"), "角色ID: %d", roleId)
return errors.Wrapf(xerr.NewErrMsg("角色不存在"), "角色ID: %s", roleId)
}
}
// 4. 找出需要删除和新增的关联
var toDelete []*model.AdminUserRole
var toInsert []int64
var toInsert []string
// 需要删除的:当前存在但新列表中没有的
for roleId, userRole := range currentRoleMap {
@@ -116,16 +117,17 @@ func (l *AdminUpdateUserLogic) AdminUpdateUser(req *types.AdminUpdateUserReq) (r
}
// 6. 添加新的关联
for _, roleId := range toInsert {
userRole := &model.AdminUserRole{
UserId: req.Id,
RoleId: roleId,
}
_, err = l.svcCtx.AdminUserRoleModel.Insert(ctx, session, userRole)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "添加用户角色关联失败: %v", err)
}
}
for _, roleId := range toInsert {
userRole := &model.AdminUserRole{
Id: uuid.NewString(),
UserId: req.Id,
RoleId: roleId,
}
_, err = l.svcCtx.AdminUserRoleModel.Insert(ctx, session, userRole)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "添加用户角色关联失败: %v", err)
}
}
}
return nil

View File

@@ -45,7 +45,7 @@ func (l *AdminUserInfoLogic) AdminUserInfo(req *types.AdminUserInfoReq) (resp *t
}
// 获取角色ID数组
roleIds := make([]int64, 0)
roleIds := make([]string, 0)
for _, permission := range permissions {
roleIds = append(roleIds, permission.RoleId)
}

View File

@@ -1,19 +1,22 @@
package agent
import (
"context"
"database/sql"
"fmt"
"os"
"time"
"ycc-server/app/main/model"
"ycc-server/common/ctxdata"
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/crypto"
"context"
"database/sql"
"fmt"
"os"
"time"
"ycc-server/app/main/model"
"ycc-server/common/ctxdata"
"ycc-server/common/globalkey"
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/crypto"
"strconv"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
@@ -47,10 +50,9 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "加密手机号失败: %v", err)
}
// 1. 必须提供邀请码,用户不能自主成为代理
if req.InviteCode == "" {
return nil, errors.Wrapf(xerr.NewErrMsg("必须提供邀请码才能成为代理,请联系平台或代理获取邀请码"), "")
}
if req.Referrer == "" {
return nil, errors.Wrapf(xerr.NewErrMsg("请填写邀请信息"), "")
}
// 2. 校验验证码(开发环境下跳过验证码校验)
if os.Getenv("ENV") != "development" {
@@ -67,7 +69,7 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
}
}
var userID int64
var userID string
transErr := l.svcCtx.AgentModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
// 1. 处理用户注册/绑定
user, findUserErr := l.svcCtx.UserModel.FindOneByMobile(l.ctx, sql.NullString{String: encryptedMobile, Valid: true})
@@ -88,15 +90,11 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
// 用户已存在
if claims != nil && claims.UserType == model.UserTypeTemp {
// 临时用户,检查手机号是否已绑定其他微信号
userTemp, err := l.svcCtx.UserTempModel.FindOne(l.ctx, claims.UserId)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询临时用户失败, %v", err)
userAuth, findUserAuthErr := l.svcCtx.UserAuthModel.FindOneByUserIdAuthType(l.ctx, user.Id, claims.AuthType)
if findUserAuthErr != nil && !errors.Is(findUserAuthErr, model.ErrNotFound) {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询用户认证失败, %v", findUserAuthErr)
}
userAuth, err := l.svcCtx.UserAuthModel.FindOneByUserIdAuthType(l.ctx, user.Id, userTemp.AuthType)
if err != nil && !errors.Is(err, model.ErrNotFound) {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询用户认证失败, %v", err)
}
if userAuth != nil && userAuth.AuthKey != userTemp.AuthKey {
if userAuth != nil && userAuth.AuthKey != claims.AuthKey {
return errors.Wrapf(xerr.NewErrMsg("该手机号已绑定其他微信号"), "")
}
// 临时用户,转为正式用户
@@ -117,40 +115,53 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
return errors.Wrapf(xerr.NewErrMsg("您已经是代理"), "")
}
// 4. 必须通过邀请码成为代理(没有其他途径)
// 4.1 查询邀请码
inviteCodeModel, err := l.svcCtx.AgentInviteCodeModel.FindOneByCode(transCtx, req.InviteCode)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return errors.Wrapf(xerr.NewErrMsg("邀请码不存在"), "")
}
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询邀请码失败, %v", err)
}
var inviteCodeModel *model.AgentInviteCode
var parentAgentId string
var targetLevel int64
// 4.2 验证邀请码状态
// 钻石级别的邀请码只能使用一次,使用后立即失效
// 普通级别的邀请码可以无限使用
if inviteCodeModel.Status != 0 {
if inviteCodeModel.Status == 1 {
return errors.Wrapf(xerr.NewErrMsg("邀请码已使用"), "")
}
return errors.Wrapf(xerr.NewErrMsg("邀请码已失效"), "")
}
// 4.3 验证邀请码是否过期
if inviteCodeModel.ExpireTime.Valid && inviteCodeModel.ExpireTime.Time.Before(time.Now()) {
return errors.Wrapf(xerr.NewErrMsg("邀请码已过期"), "")
}
// 4.4 获取邀请码信息
targetLevel := inviteCodeModel.TargetLevel
var parentAgentId int64 = 0
if inviteCodeModel.AgentId.Valid {
parentAgentId = inviteCodeModel.AgentId.Int64
}
inviteCodeModel, err = l.svcCtx.AgentInviteCodeModel.FindOneByCode(transCtx, req.Referrer)
if err != nil && !errors.Is(err, model.ErrNotFound) {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询邀请码失败, %v", err)
}
if inviteCodeModel != nil {
if inviteCodeModel.Status != 0 {
if inviteCodeModel.Status == 1 {
return errors.Wrapf(xerr.NewErrMsg("邀请码已使用"), "")
}
return errors.Wrapf(xerr.NewErrMsg("邀请码已失效"), "")
}
if inviteCodeModel.ExpireTime.Valid && inviteCodeModel.ExpireTime.Time.Before(time.Now()) {
return errors.Wrapf(xerr.NewErrMsg("邀请码已过期"), "")
}
targetLevel = inviteCodeModel.TargetLevel
if inviteCodeModel.AgentId.Valid {
parentAgentId = inviteCodeModel.AgentId.String
}
} else {
if codeVal, parseErr := strconv.ParseInt(req.Referrer, 10, 64); parseErr == nil && codeVal > 0 {
parentAgent, err := l.findAgentByCode(transCtx, codeVal)
if err != nil {
return err
}
parentAgentId = parentAgent.Id
targetLevel = 1
} else {
encRefMobile, _ := crypto.EncryptMobile(req.Referrer, l.svcCtx.Config.Encrypt.SecretKey)
agents, findErr := l.svcCtx.AgentModel.FindAll(transCtx, l.svcCtx.AgentModel.SelectBuilder().Where("mobile = ? AND del_state = ?", encRefMobile, globalkey.DelStateNo).Limit(1), "")
if findErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询上级代理失败, %v", findErr)
}
if len(agents) == 0 {
return errors.Wrapf(xerr.NewErrMsg("邀请信息无效"), "")
}
parentAgentId = agents[0].Id
targetLevel = 1
}
}
// 4.5 创建代理记录
newAgent := &model.Agent{
Id: uuid.NewString(),
UserId: userID,
Level: targetLevel,
Mobile: encryptedMobile,
@@ -160,7 +171,7 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
}
// 4.6 处理上级关系
if parentAgentId > 0 {
if parentAgentId != "" {
// 代理发放的邀请码,成为该代理的下级
parentAgent, err := l.svcCtx.AgentModel.FindOne(transCtx, parentAgentId)
if err != nil {
@@ -177,23 +188,23 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
if err != nil {
return errors.Wrapf(err, "查找团队首领失败")
}
if teamLeaderId > 0 {
newAgent.TeamLeaderId = sql.NullInt64{Int64: teamLeaderId, Valid: true}
if teamLeaderId != "" {
newAgent.TeamLeaderId = sql.NullString{String: teamLeaderId, Valid: true}
}
// 先插入代理记录
agentResult, err := l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
newAgent.AgentCode = 0
_, err = l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
if err != nil {
return errors.Wrapf(err, "创建代理记录失败")
}
agentId, _ := agentResult.LastInsertId()
newAgent.Id = agentId
// 已设置newAgent.Id为UUID
// 建立关系
relation := &model.AgentRelation{
Id: uuid.NewString(),
ParentId: parentAgent.Id,
ChildId: agentId,
RelationType: 1, // 直接关系
ChildId: newAgent.Id,
RelationType: 1,
}
if _, err := l.svcCtx.AgentRelationModel.Insert(transCtx, session, relation); err != nil {
return errors.Wrapf(err, "建立代理关系失败")
@@ -201,29 +212,28 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
} else {
// 平台发放的钻石邀请码,独立成团队
if targetLevel == 3 {
agentResult, err := l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
newAgent.AgentCode = 0
_, err = l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
if err != nil {
return errors.Wrapf(err, "创建代理记录失败")
}
agentId, _ := agentResult.LastInsertId()
newAgent.Id = agentId
// 设置自己为团队首领
newAgent.TeamLeaderId = sql.NullInt64{Int64: agentId, Valid: true}
newAgent.TeamLeaderId = sql.NullString{String: newAgent.Id, Valid: true}
if err := l.svcCtx.AgentModel.UpdateInTransaction(transCtx, session, newAgent); err != nil {
return errors.Wrapf(err, "更新团队首领失败")
}
} else {
agentResult, err := l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
newAgent.AgentCode = 0
_, err = l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
if err != nil {
return errors.Wrapf(err, "创建代理记录失败")
}
_, _ = agentResult.LastInsertId()
}
}
// 4.7 初始化钱包
wallet := &model.AgentWallet{
Id: uuid.NewString(),
AgentId: newAgent.Id,
}
if _, err := l.svcCtx.AgentWalletModel.Insert(transCtx, session, wallet); err != nil {
@@ -238,15 +248,18 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
inviteCodeModel.Status = 1 // 已使用(使用后立即失效)
}
// 记录使用信息(用于统计,普通邀请码可以多次使用)
inviteCodeModel.UsedUserId = sql.NullInt64{Int64: userID, Valid: true}
inviteCodeModel.UsedAgentId = sql.NullInt64{Int64: newAgent.Id, Valid: true}
inviteCodeModel.UsedTime = sql.NullTime{Time: time.Now(), Valid: true}
if err := l.svcCtx.AgentInviteCodeModel.UpdateWithVersion(transCtx, session, inviteCodeModel); err != nil {
return errors.Wrapf(err, "更新邀请码状态失败")
inviteCodeModel.UsedUserId = sql.NullString{String: userID, Valid: true}
if inviteCodeModel != nil {
inviteCodeModel.UsedAgentId = sql.NullString{String: newAgent.Id, Valid: true}
inviteCodeModel.UsedTime = sql.NullTime{Time: time.Now(), Valid: true}
if err := l.svcCtx.AgentInviteCodeModel.UpdateWithVersion(transCtx, session, inviteCodeModel); err != nil {
return errors.Wrapf(err, "更新邀请码状态失败")
}
}
// 4.9 记录邀请码使用历史(用于统计和查询)
usage := &model.AgentInviteCodeUsage{
Id: uuid.NewString(),
InviteCodeId: inviteCodeModel.Id,
Code: inviteCodeModel.Code,
UserId: userID,
@@ -272,15 +285,46 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
}
now := time.Now().Unix()
agent, _ := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
var code int64
if agent != nil {
code = agent.AgentCode
}
return &types.AgentApplyResp{
AccessToken: token,
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
AgentCode: code,
}, nil
}
func (l *ApplyForAgentLogic) findAgentByCode(ctx context.Context, code int64) (*model.Agent, error) {
builder := l.svcCtx.AgentModel.SelectBuilder().Where("agent_code = ? AND del_state = ?", code, globalkey.DelStateNo).Limit(1)
agents, err := l.svcCtx.AgentModel.FindAll(ctx, builder, "")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询上级代理失败, %v", err)
}
if len(agents) == 0 {
return nil, errors.Wrapf(xerr.NewErrMsg("上级邀请码不存在"), "")
}
return agents[0], nil
}
func (l *ApplyForAgentLogic) allocateAgentCode(ctx context.Context, session sqlx.Session) (int64, error) {
builder := l.svcCtx.AgentModel.SelectBuilder().OrderBy("agent_code DESC").Limit(1)
rows, err := l.svcCtx.AgentModel.FindAll(ctx, builder, "")
if err != nil {
return 0, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理编码失败, %v", err)
}
var next int64 = 16800
if len(rows) > 0 && rows[0].AgentCode > 0 {
next = rows[0].AgentCode + 1
}
return next, nil
}
// findTeamLeader 查找团队首领(钻石代理)
func (l *ApplyForAgentLogic) findTeamLeader(ctx context.Context, agentId int64) (int64, error) {
func (l *ApplyForAgentLogic) findTeamLeader(ctx context.Context, agentId string) (string, error) {
currentId := agentId
maxDepth := 100
depth := 0
@@ -290,22 +334,22 @@ func (l *ApplyForAgentLogic) findTeamLeader(ctx context.Context, agentId int64)
Where("child_id = ? AND relation_type = ? AND del_state = ?", currentId, 1, 0)
relations, err := l.svcCtx.AgentRelationModel.FindAll(ctx, builder, "")
if err != nil {
return 0, err
return "", err
}
if len(relations) == 0 {
agent, err := l.svcCtx.AgentModel.FindOne(ctx, currentId)
if err != nil {
return 0, err
return "", err
}
if agent.Level == 3 {
return agent.Id, nil
}
return 0, nil
return "", nil
}
parentAgent, err := l.svcCtx.AgentModel.FindOne(ctx, relations[0].ParentId)
if err != nil {
return 0, err
return "", err
}
if parentAgent.Level == 3 {
@@ -316,5 +360,5 @@ func (l *ApplyForAgentLogic) findTeamLeader(ctx context.Context, agentId int64)
depth++
}
return 0, nil
return "", nil
}

View File

@@ -7,6 +7,7 @@ import (
"ycc-server/common/ctxdata"
"ycc-server/common/xerr"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/sqlx"
@@ -64,7 +65,7 @@ func (l *ApplyUpgradeLogic) ApplyUpgrade(req *types.ApplyUpgradeReq) (resp *type
}
// 4. 查找原直接上级(用于返佣)
var rebateAgentId int64
var rebateAgentId string
parent, err := l.svcCtx.AgentService.FindDirectParent(l.ctx, agent.Id)
if err != nil && !errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(err, "查找直接上级失败")
@@ -74,10 +75,11 @@ func (l *ApplyUpgradeLogic) ApplyUpgrade(req *types.ApplyUpgradeReq) (resp *type
}
// 5. 创建升级记录(待支付状态)
var upgradeId int64
var upgradeId string
err = l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
// 5.1 创建升级记录(状态为待支付)
upgradeRecord := &model.AgentUpgrade{
Id: uuid.NewString(),
AgentId: agent.Id,
FromLevel: fromLevel,
ToLevel: toLevel,
@@ -86,17 +88,16 @@ func (l *ApplyUpgradeLogic) ApplyUpgrade(req *types.ApplyUpgradeReq) (resp *type
RebateAmount: rebateAmount,
Status: 1, // 待支付1=待支付2=已支付3=已完成4=已取消)
}
if rebateAgentId > 0 {
upgradeRecord.RebateAgentId = sql.NullInt64{Int64: rebateAgentId, Valid: true}
if rebateAgentId != "" {
upgradeRecord.RebateAgentId = sql.NullString{String: rebateAgentId, Valid: true}
}
upgradeResult, err := l.svcCtx.AgentUpgradeModel.Insert(transCtx, session, upgradeRecord)
_, err := l.svcCtx.AgentUpgradeModel.Insert(transCtx, session, upgradeRecord)
if err != nil {
return errors.Wrapf(err, "创建升级记录失败")
}
upgradeId, _ = upgradeResult.LastInsertId()
// 注意:升级操作将在支付成功后通过支付回调完成
upgradeId = upgradeRecord.Id
return nil
})

View File

@@ -10,6 +10,7 @@ import (
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/lzUtils"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/sqlx"
@@ -88,7 +89,7 @@ func (l *ApplyWithdrawalLogic) ApplyWithdrawal(req *types.ApplyWithdrawalReq) (r
withdrawNo := fmt.Sprintf("WD%d%d", time.Now().Unix(), agent.Id)
// 8. 使用事务处理提现申请
var withdrawalId int64
var withdrawalId string
err = l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
// 8.1 冻结余额
wallet.FrozenBalance += req.Amount
@@ -99,6 +100,7 @@ func (l *ApplyWithdrawalLogic) ApplyWithdrawal(req *types.ApplyWithdrawalReq) (r
// 8.2 创建提现记录
withdrawal := &model.AgentWithdrawal{
Id: uuid.New().String(),
AgentId: agent.Id,
WithdrawNo: withdrawNo,
PayeeAccount: req.PayeeAccount,
@@ -109,11 +111,11 @@ func (l *ApplyWithdrawalLogic) ApplyWithdrawal(req *types.ApplyWithdrawalReq) (r
Status: 1, // 处理中(待审核)
}
withdrawalResult, err := l.svcCtx.AgentWithdrawalModel.Insert(transCtx, session, withdrawal)
_, err := l.svcCtx.AgentWithdrawalModel.Insert(transCtx, session, withdrawal)
if err != nil {
return errors.Wrapf(err, "创建提现记录失败")
}
withdrawalId, _ = withdrawalResult.LastInsertId()
withdrawalId = withdrawal.Id
// 8.3 创建扣税记录
taxRecord := &model.AgentWithdrawalTax{
@@ -154,7 +156,7 @@ type TaxInfo struct {
}
// calculateTax 计算税费
func (l *ApplyWithdrawalLogic) calculateTax(ctx context.Context, agentId int64, amount float64, yearMonth int64) (*TaxInfo, error) {
func (l *ApplyWithdrawalLogic) calculateTax(ctx context.Context, agentId string, amount float64, yearMonth int64) (*TaxInfo, error) {
// 获取税率配置默认6%
taxRate := 0.06
config, err := l.svcCtx.AgentConfigModel.FindOneByConfigKey(ctx, "tax_rate")

View File

@@ -53,7 +53,7 @@ func (l *DeleteInviteCodeLogic) DeleteInviteCode(req *types.DeleteInviteCodeReq)
}
// 3. 验证邀请码是否属于当前代理
if !inviteCode.AgentId.Valid || inviteCode.AgentId.Int64 != agent.Id {
if !inviteCode.AgentId.Valid || inviteCode.AgentId.String != agent.Id {
return nil, errors.Wrapf(xerr.NewErrMsg("无权删除此邀请码"), "")
}

View File

@@ -87,9 +87,9 @@ func (l *GenerateInviteCodeLogic) GenerateInviteCode(req *types.GenerateInviteCo
// 创建邀请码记录
inviteCode := &model.AgentInviteCode{
Code: code,
AgentId: sql.NullInt64{Int64: agent.Id, Valid: true},
AgentId: sql.NullString{String: agent.Id, Valid: true},
TargetLevel: 1, // 代理发放的邀请码,目标等级为普通代理
Status: 0, // 未使用
Status: 0, // 未使用
ExpireTime: expireTime,
Remark: sql.NullString{String: req.Remark, Valid: req.Remark != ""},
}

View File

@@ -22,6 +22,7 @@ import (
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"github.com/google/uuid"
"github.com/zeromicro/go-zero/core/logx"
)
@@ -69,15 +70,17 @@ func (l *GeneratingLinkLogic) GeneratingLink(req *types.AgentGeneratingLinkReq)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取等级加成配置失败, %v", err)
}
// 4. 计算实际底价(产品基础底价 + 等级加成)
basePrice := productConfig.BasePrice
actualBasePrice := basePrice + float64(levelBonus)
systemMaxPrice := productConfig.SystemMaxPrice
// 5. 验证设定价格范围
if req.SetPrice < actualBasePrice || req.SetPrice > systemMaxPrice {
return nil, errors.Wrapf(xerr.NewErrMsg("设定价格必须在 %.2f 到 %.2f 之间"), "设定价格必须在 %.2f 到 %.2f 之间", actualBasePrice, systemMaxPrice)
}
basePrice := productConfig.BasePrice
actualBasePrice := basePrice + float64(levelBonus)
systemMaxPrice := productConfig.SystemMaxPrice
upliftAmount, err := l.getLevelMaxUpliftAmount(agentModel.Level)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取等级上调金额失败, %v", err)
}
levelMaxPrice := systemMaxPrice + upliftAmount
if req.SetPrice < actualBasePrice || req.SetPrice > levelMaxPrice {
return nil, errors.Wrapf(xerr.NewErrMsg("设定价格必须在 %.2f 到 %.2f 之间"), "设定价格必须在 %.2f 到 %.2f 之间", actualBasePrice, levelMaxPrice)
}
// 6. 检查是否已存在相同的链接(同一代理、同一产品、同一价格)
builder := l.svcCtx.AgentLinkModel.SelectBuilder().Where(squirrel.And{
@@ -98,7 +101,7 @@ func (l *GeneratingLinkLogic) GeneratingLink(req *types.AgentGeneratingLinkReq)
if targetPath == "" {
targetPath = "/agent/promotionInquire/"
}
shortLink, err := l.getOrCreateShortLink(1, existingLinks[0].Id, 0, existingLinks[0].LinkIdentifier, "", targetPath)
shortLink, err := l.getOrCreateShortLink(1, existingLinks[0].Id, "", existingLinks[0].LinkIdentifier, "", targetPath)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取或创建短链失败, %v", err)
}
@@ -132,6 +135,7 @@ func (l *GeneratingLinkLogic) GeneratingLink(req *types.AgentGeneratingLinkReq)
// 9. 保存推广链接
agentLink := &model.AgentLink{
// Id: uuid.NewString(),
AgentId: agentModel.Id,
UserId: userID,
ProductId: req.ProductId,
@@ -140,16 +144,12 @@ func (l *GeneratingLinkLogic) GeneratingLink(req *types.AgentGeneratingLinkReq)
ActualBasePrice: actualBasePrice,
}
result, err := l.svcCtx.AgentLinkModel.Insert(l.ctx, nil, agentLink)
_, err = l.svcCtx.AgentLinkModel.Insert(l.ctx, nil, agentLink)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "保存推广链接失败, %v", err)
}
// 获取插入的ID
linkId, err := result.LastInsertId()
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取推广链接ID失败, %v", err)
}
linkId := agentLink.Id
// 使用默认target_path如果未提供
targetPath := req.TargetPath
@@ -158,7 +158,7 @@ func (l *GeneratingLinkLogic) GeneratingLink(req *types.AgentGeneratingLinkReq)
}
// 生成短链类型1=推广报告)
shortLink, err := l.createShortLink(1, linkId, 0, encrypted, "", targetPath)
shortLink, err := l.createShortLink(1, linkId, "", encrypted, "", targetPath)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成短链失败, %v", err)
}
@@ -205,6 +205,30 @@ func (l *GeneratingLinkLogic) getLevelBonus(level int64) (int64, error) {
return int64(value), nil
}
func (l *GeneratingLinkLogic) getLevelMaxUpliftAmount(level int64) (float64, error) {
var key string
switch level {
case 2:
key = "gold_max_uplift_amount"
case 3:
key = "diamond_max_uplift_amount"
default:
return 0, nil
}
config, err := l.svcCtx.AgentConfigModel.FindOneByConfigKey(l.ctx, key)
if err != nil {
return 0, nil
}
v, err := strconv.ParseFloat(config.ConfigValue, 64)
if err != nil {
return 0, nil
}
if v < 0 {
return 0, nil
}
return v, nil
}
// getOrCreateShortLink 获取或创建短链
// type: 1=推广报告(promotion), 2=邀请好友(invite)
// linkId: 推广链接ID仅推广报告使用
@@ -212,20 +236,20 @@ func (l *GeneratingLinkLogic) getLevelBonus(level int64) (int64, error) {
// linkIdentifier: 推广链接标识(仅推广报告使用)
// inviteCode: 邀请码(仅邀请好友使用)
// targetPath: 目标地址(前端传入)
func (l *GeneratingLinkLogic) getOrCreateShortLink(linkType int64, linkId, inviteCodeId int64, linkIdentifier, inviteCode, targetPath string) (string, error) {
func (l *GeneratingLinkLogic) getOrCreateShortLink(linkType int64, linkId, inviteCodeId string, linkIdentifier, inviteCode, targetPath string) (string, error) {
// 先查询是否已存在短链
var existingShortLink *model.AgentShortLink
var err error
if linkType == 1 {
// 推广报告类型使用link_id查询
if linkId > 0 {
existingShortLink, err = l.svcCtx.AgentShortLinkModel.FindOneByLinkIdTypeDelState(l.ctx, sql.NullInt64{Int64: linkId, Valid: true}, linkType, globalkey.DelStateNo)
if linkId != "" {
existingShortLink, err = l.svcCtx.AgentShortLinkModel.FindOneByLinkIdTypeDelState(l.ctx, sql.NullString{String: linkId, Valid: true}, linkType, globalkey.DelStateNo)
}
} else {
// 邀请好友类型使用invite_code_id查询
if inviteCodeId > 0 {
existingShortLink, err = l.svcCtx.AgentShortLinkModel.FindOneByInviteCodeIdTypeDelState(l.ctx, sql.NullInt64{Int64: inviteCodeId, Valid: true}, linkType, globalkey.DelStateNo)
if inviteCodeId != "" {
existingShortLink, err = l.svcCtx.AgentShortLinkModel.FindOneByInviteCodeIdTypeDelState(l.ctx, sql.NullString{String: inviteCodeId, Valid: true}, linkType, globalkey.DelStateNo)
}
}
@@ -244,7 +268,7 @@ func (l *GeneratingLinkLogic) getOrCreateShortLink(linkType int64, linkId, invit
// createShortLink 创建短链
// type: 1=推广报告(promotion), 2=邀请好友(invite)
func (l *GeneratingLinkLogic) createShortLink(linkType int64, linkId, inviteCodeId int64, linkIdentifier, inviteCode, targetPath string) (string, error) {
func (l *GeneratingLinkLogic) createShortLink(linkType int64, linkId, inviteCodeId string, linkIdentifier, inviteCode, targetPath string) (string, error) {
promotionConfig := l.svcCtx.Config.Promotion
// 如果没有配置推广域名,返回空字符串(保持向后兼容)
@@ -291,6 +315,7 @@ func (l *GeneratingLinkLogic) createShortLink(linkType int64, linkId, inviteCode
// 创建短链记录
shortLink := &model.AgentShortLink{
Id: uuid.NewString(),
Type: linkType,
ShortCode: shortCode,
TargetPath: targetPath,
@@ -300,13 +325,13 @@ func (l *GeneratingLinkLogic) createShortLink(linkType int64, linkId, inviteCode
// 根据类型设置对应字段
if linkType == 1 {
// 推广报告类型
shortLink.LinkId = sql.NullInt64{Int64: linkId, Valid: linkId > 0}
shortLink.LinkId = sql.NullString{String: linkId, Valid: linkId != ""}
if linkIdentifier != "" {
shortLink.LinkIdentifier = sql.NullString{String: linkIdentifier, Valid: true}
}
} else if linkType == 2 {
// 邀请好友类型
shortLink.InviteCodeId = sql.NullInt64{Int64: inviteCodeId, Valid: inviteCodeId > 0}
shortLink.InviteCodeId = sql.NullString{String: inviteCodeId, Valid: inviteCodeId != ""}
if inviteCode != "" {
shortLink.InviteCode = sql.NullString{String: inviteCode, Valid: true}
}

View File

@@ -40,14 +40,14 @@ func (l *GetAgentInfoLogic) GetAgentInfo() (resp *types.AgentInfoResp, err error
if errors.Is(err, model.ErrNotFound) {
// 不是代理,返回空信息
return &types.AgentInfoResp{
AgentId: 0,
Level: 0,
LevelName: "",
Region: "",
Mobile: "",
WechatId: "",
TeamLeaderId: 0,
IsRealName: false,
AgentId: "",
Level: 0,
LevelName: "",
Region: "",
Mobile: "",
WechatId: "",
TeamLeaderId: "",
IsRealName: false,
}, nil
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败, %v", err)
@@ -76,9 +76,9 @@ func (l *GetAgentInfoLogic) GetAgentInfo() (resp *types.AgentInfoResp, err error
}
// 获取团队首领ID
teamLeaderId := int64(0)
teamLeaderId := ""
if agent.TeamLeaderId.Valid {
teamLeaderId = agent.TeamLeaderId.Int64
teamLeaderId = agent.TeamLeaderId.String
}
// 获取区域
@@ -88,14 +88,15 @@ func (l *GetAgentInfoLogic) GetAgentInfo() (resp *types.AgentInfoResp, err error
}
return &types.AgentInfoResp{
AgentId: agent.Id,
Level: agent.Level,
LevelName: l.getLevelName(agent.Level),
Region: region,
Mobile: mobile,
WechatId: wechatId,
TeamLeaderId: teamLeaderId,
IsRealName: isRealName,
AgentId: agent.Id,
Level: agent.Level,
LevelName: l.getLevelName(agent.Level),
Region: region,
Mobile: mobile,
WechatId: wechatId,
TeamLeaderId: teamLeaderId,
IsRealName: isRealName,
AgentCode: agent.AgentCode,
}, nil
}

View File

@@ -78,9 +78,9 @@ func (l *GetAgentProductConfigLogic) GetAgentProductConfig() (resp *types.AgentP
// 计算该产品的实际底价
productActualBasePrice := productBasePrice + float64(levelBonus)
// 价格范围:实际底价 ≤ 设定价格 ≤ 产品配置的最高价格
priceRangeMin := productActualBasePrice
priceRangeMax := productConfig.SystemMaxPrice
priceRangeMin := productActualBasePrice
upliftAmount, _ := l.getLevelMaxUpliftAmount(agentModel.Level)
priceRangeMax := productConfig.SystemMaxPrice + upliftAmount
// 使用产品配置的提价阈值和手续费比例如果为NULL则使用0
productPriceThreshold := 0.0
@@ -144,3 +144,27 @@ func (l *GetAgentProductConfigLogic) getLevelBonus(level int64) (int64, error) {
}
return int64(value), nil
}
func (l *GetAgentProductConfigLogic) getLevelMaxUpliftAmount(level int64) (float64, error) {
var key string
switch level {
case 2:
key = "gold_max_uplift_amount"
case 3:
key = "diamond_max_uplift_amount"
default:
return 0, nil
}
config, err := l.svcCtx.AgentConfigModel.FindOneByConfigKey(l.ctx, key)
if err != nil {
return 0, nil
}
v, err := strconv.ParseFloat(config.ConfigValue, 64)
if err != nil {
return 0, nil
}
if v < 0 {
return 0, nil
}
return v, nil
}

View File

@@ -78,7 +78,7 @@ func (l *GetCommissionListLogic) GetCommissionList(req *types.GetCommissionListR
for _, commission := range commissions {
// 查询产品名称
productName := ""
if commission.ProductId > 0 {
if commission.ProductId != "" {
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, commission.ProductId)
if err == nil {
productName = product.ProductName
@@ -87,7 +87,7 @@ func (l *GetCommissionListLogic) GetCommissionList(req *types.GetCommissionListR
// 查询订单号
orderNo := ""
if commission.OrderId > 0 {
if commission.OrderId != "" {
order, err := l.svcCtx.OrderModel.FindOne(l.ctx, commission.OrderId)
if err == nil {
orderNo = order.OrderNo

View File

@@ -59,7 +59,7 @@ func (l *GetConversionRateLogic) GetConversionRate() (resp *types.ConversionRate
}
// calculateSubordinateConversionRate 计算下级转化率(考虑历史关系)
func (l *GetConversionRateLogic) calculateSubordinateConversionRate(parentAgentId int64) types.ConversionRateData {
func (l *GetConversionRateLogic) calculateSubordinateConversionRate(parentAgentId string) types.ConversionRateData {
// 使用Asia/Shanghai时区与数据库保持一致
loc, _ := time.LoadLocation("Asia/Shanghai")
now := time.Now().In(loc)
@@ -120,7 +120,7 @@ func (l *GetConversionRateLogic) calculateSubordinateConversionRate(parentAgentI
// calculateConversionRate 计算转化率
// agentId > 0 时统计该代理的转化率,否则统计 subordinateIds 列表的转化率
func (l *GetConversionRateLogic) calculateConversionRate(agentId int64, subordinateIds []int64) types.ConversionRateData {
func (l *GetConversionRateLogic) calculateConversionRate(agentId string, subordinateIds []string) types.ConversionRateData {
// 使用Asia/Shanghai时区与数据库保持一致
loc, _ := time.LoadLocation("Asia/Shanghai")
now := time.Now().In(loc)
@@ -182,13 +182,13 @@ func (l *GetConversionRateLogic) calculateConversionRate(agentId int64, subordin
}
// calculatePeriodConversion 计算指定时间段的转化率数据
func (l *GetConversionRateLogic) calculatePeriodConversion(agentId int64, subordinateIds []int64, periodLabel string, startTime, endTime time.Time) types.PeriodConversionData {
func (l *GetConversionRateLogic) calculatePeriodConversion(agentId string, subordinateIds []string, periodLabel string, startTime, endTime time.Time) types.PeriodConversionData {
// 构建 agent_order 查询条件
agentOrderBuilder := l.svcCtx.AgentOrderModel.SelectBuilder().
Where("del_state = ?", globalkey.DelStateNo).
Where("create_time >= ? AND create_time < ?", startTime, endTime)
if agentId > 0 {
if agentId != "" {
// 统计我的转化率
agentOrderBuilder = agentOrderBuilder.Where("agent_id = ?", agentId)
} else if len(subordinateIds) > 0 {
@@ -208,7 +208,7 @@ func (l *GetConversionRateLogic) calculatePeriodConversion(agentId int64, subord
}
// 添加调试日志
if agentId == 0 && len(subordinateIds) > 0 {
if agentId == "" && len(subordinateIds) > 0 {
l.Infof("calculatePeriodConversion: 统计下级转化率periodLabel=%s, startTime=%v, endTime=%v, subordinateIds数量=%d",
periodLabel, startTime, endTime, len(subordinateIds))
}
@@ -228,7 +228,7 @@ func (l *GetConversionRateLogic) calculatePeriodConversion(agentId int64, subord
}
if len(agentOrders) == 0 {
if agentId == 0 && len(subordinateIds) > 0 {
if agentId == "" && len(subordinateIds) > 0 {
l.Infof("calculatePeriodConversion: 未找到代理订单periodLabel=%s, startTime=%v, endTime=%v",
periodLabel, startTime, endTime)
}
@@ -245,7 +245,7 @@ func (l *GetConversionRateLogic) calculatePeriodConversion(agentId int64, subord
l.Infof("calculatePeriodConversion: 找到代理订单数量=%d, periodLabel=%s", len(agentOrders), periodLabel)
// 收集订单ID
orderIds := make([]int64, 0, len(agentOrders))
orderIds := make([]string, 0, len(agentOrders))
for _, ao := range agentOrders {
orderIds = append(orderIds, ao.OrderId)
}
@@ -271,8 +271,8 @@ func (l *GetConversionRateLogic) calculatePeriodConversion(agentId int64, subord
// 统计查询订单数、付费订单数、用户数和总金额
var totalAmount float64
paidOrderCount := 0
queryUserSet := make(map[int64]bool)
paidUserSet := make(map[int64]bool)
queryUserSet := make(map[string]bool)
paidUserSet := make(map[string]bool)
for _, order := range orders {
// 查询用户数(所有订单的用户,去重)
@@ -303,7 +303,7 @@ func (l *GetConversionRateLogic) calculatePeriodConversion(agentId int64, subord
// 结合使用agent_rebate表和agent_order表
// 1. 查询量通过agent_order表统计所有查询包括未付费的
// 2. 付费量和金额通过agent_rebate表统计只有付费的订单才会产生返佣
func (l *GetConversionRateLogic) calculateSubordinatePeriodConversion(parentAgentId int64, periodLabel string, startTime, endTime time.Time) types.PeriodConversionData {
func (l *GetConversionRateLogic) calculateSubordinatePeriodConversion(parentAgentId string, periodLabel string, startTime, endTime time.Time) types.PeriodConversionData {
// 1. 查询agent_rebate表获取所有曾经给当前用户产生返佣的source_agent_id这些代理在某个时间点是下级
// 不限制时间,获取所有历史返佣记录,用于确定哪些代理曾经是下级
rebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder().
@@ -324,9 +324,9 @@ func (l *GetConversionRateLogic) calculateSubordinatePeriodConversion(parentAgen
}
// 收集所有曾经产生返佣的source_agent_id这些代理在某个时间点是下级
sourceAgentIdSet := make(map[int64]bool)
paidOrderIdSet := make(map[int64]bool) // 已付费的订单ID有返佣的订单
paidOrderIdToAmount := make(map[int64]float64) // 已付费订单的金额
sourceAgentIdSet := make(map[string]bool)
paidOrderIdSet := make(map[string]bool) // 已付费的订单ID有返佣的订单
paidOrderIdToAmount := make(map[string]float64) // 已付费订单的金额
for _, rebate := range allRebates {
sourceAgentIdSet[rebate.SourceAgentId] = true
@@ -351,7 +351,7 @@ func (l *GetConversionRateLogic) calculateSubordinatePeriodConversion(parentAgen
}
}
sourceAgentIds := make([]int64, 0, len(sourceAgentIdSet))
sourceAgentIds := make([]string, 0, len(sourceAgentIdSet))
for agentId := range sourceAgentIdSet {
sourceAgentIds = append(sourceAgentIds, agentId)
}
@@ -391,8 +391,8 @@ func (l *GetConversionRateLogic) calculateSubordinatePeriodConversion(parentAgen
}
// 3. 通过order_id去重获取所有订单ID用于查询订单详情
orderIdSet := make(map[int64]bool)
orderIdToAgentOrder := make(map[int64]*model.AgentOrder)
orderIdSet := make(map[string]bool)
orderIdToAgentOrder := make(map[string]*model.AgentOrder)
for _, ao := range agentOrders {
orderIdSet[ao.OrderId] = true
@@ -406,7 +406,7 @@ func (l *GetConversionRateLogic) calculateSubordinatePeriodConversion(parentAgen
}
}
orderIds := make([]int64, 0, len(orderIdSet))
orderIds := make([]string, 0, len(orderIdSet))
for orderId := range orderIdSet {
orderIds = append(orderIds, orderId)
}
@@ -459,8 +459,8 @@ func (l *GetConversionRateLogic) calculateSubordinatePeriodConversion(parentAgen
// 6. 统计查询订单数、付费订单数、用户数和总金额
var totalAmount float64
paidOrderCount := 0
queryUserSet := make(map[int64]bool)
paidUserSet := make(map[int64]bool)
queryUserSet := make(map[string]bool)
paidUserSet := make(map[string]bool)
for _, order := range orders {
// 查询用户数(所有订单的用户,去重)

View File

@@ -4,18 +4,22 @@ import (
"context"
"database/sql"
"fmt"
"strconv"
"strings"
"time"
"ycc-server/app/main/model"
"ycc-server/common/ctxdata"
"ycc-server/common/globalkey"
"ycc-server/common/tool"
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/crypto"
"github.com/pkg/errors"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"github.com/google/uuid"
"github.com/zeromicro/go-zero/core/logx"
)
@@ -53,41 +57,51 @@ func (l *GetInviteLinkLogic) GetInviteLink(req *types.GetInviteLinkReq) (resp *t
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码不能为空"), "")
}
// 3. 查询邀请码是否存在且属于当前代理
inviteCodeRecord, err := l.svcCtx.AgentInviteCodeModel.FindOneByCode(l.ctx, req.InviteCode)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码不存在"), "")
}
ref := strings.TrimSpace(req.InviteCode)
var inviteCodeRecord *model.AgentInviteCode
inviteCodeRecord, err = l.svcCtx.AgentInviteCodeModel.FindOneByCode(l.ctx, ref)
if err != nil && !errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询邀请码失败, %v", err)
}
// 4. 验证邀请码是否属于当前代理
if !inviteCodeRecord.AgentId.Valid || inviteCodeRecord.AgentId.Int64 != agent.Id {
return nil, errors.Wrapf(xerr.NewErrMsg("无权使用此邀请码"), "")
}
// 5. 验证邀请码状态
if inviteCodeRecord.Status != 0 {
if inviteCodeRecord.Status == 1 {
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已使用"), "")
if inviteCodeRecord != nil {
if !inviteCodeRecord.AgentId.Valid || inviteCodeRecord.AgentId.String != agent.Id {
return nil, errors.Wrapf(xerr.NewErrMsg("无权使用此邀请码"), "")
}
if inviteCodeRecord.Status != 0 {
if inviteCodeRecord.Status == 1 {
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已使用"), "")
}
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已失效"), "")
}
if inviteCodeRecord.ExpireTime.Valid && inviteCodeRecord.ExpireTime.Time.Before(time.Now()) {
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已过期"), "")
}
} else {
if codeVal, parseErr := strconv.ParseInt(ref, 10, 64); parseErr == nil && codeVal > 0 {
if agent.AgentCode != codeVal {
return nil, errors.Wrapf(xerr.NewErrMsg("无权使用此邀请码"), "")
}
} else {
encMobile, _ := crypto.EncryptMobile(ref, l.svcCtx.Config.Encrypt.SecretKey)
if encMobile != agent.Mobile {
return nil, errors.Wrapf(xerr.NewErrMsg("邀请信息无效"), "")
}
}
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已失效"), "")
}
// 6. 验证邀请码是否过期
if inviteCodeRecord.ExpireTime.Valid && inviteCodeRecord.ExpireTime.Time.Before(time.Now()) {
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已过期"), "")
}
// 7. 使用默认target_path如果未提供
targetPath := req.TargetPath
if targetPath == "" {
targetPath = fmt.Sprintf("/register?invite_code=%s", req.InviteCode)
targetPath = fmt.Sprintf("/register?invite_code=%s", ref)
}
// 8. 生成短链类型2=邀请好友)
shortLink, err := l.createInviteShortLink(inviteCodeRecord.Id, req.InviteCode, targetPath)
shortLink, err := l.createInviteShortLink(func() string {
if inviteCodeRecord != nil {
return inviteCodeRecord.Id
}
return ""
}(), ref, targetPath)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成短链失败, %v", err)
}
@@ -98,7 +112,7 @@ func (l *GetInviteLinkLogic) GetInviteLink(req *types.GetInviteLinkReq) (resp *t
}
// createInviteShortLink 创建邀请好友短链
func (l *GetInviteLinkLogic) createInviteShortLink(inviteCodeId int64, inviteCode, targetPath string) (string, error) {
func (l *GetInviteLinkLogic) createInviteShortLink(inviteCodeId string, inviteCode, targetPath string) (string, error) {
promotionConfig := l.svcCtx.Config.Promotion
// 如果没有配置推广域名,返回空字符串(保持向后兼容)
@@ -108,7 +122,7 @@ func (l *GetInviteLinkLogic) createInviteShortLink(inviteCodeId int64, inviteCod
}
// 先查询是否已存在短链
existingShortLink, err := l.svcCtx.AgentShortLinkModel.FindOneByInviteCodeIdTypeDelState(l.ctx, sql.NullInt64{Int64: inviteCodeId, Valid: true}, 2, globalkey.DelStateNo)
existingShortLink, err := l.svcCtx.AgentShortLinkModel.FindOneByInviteCodeIdTypeDelState(l.ctx, sql.NullString{String: inviteCodeId, Valid: inviteCodeId != ""}, 2, globalkey.DelStateNo)
if err == nil && existingShortLink != nil {
// 已存在短链,直接返回
return fmt.Sprintf("%s/s/%s", promotionConfig.PromotionDomain, existingShortLink.ShortCode), nil
@@ -118,6 +132,17 @@ func (l *GetInviteLinkLogic) createInviteShortLink(inviteCodeId int64, inviteCod
return "", errors.Wrapf(err, "查询短链失败")
}
// 如果没有邀请码ID例如使用手机号或代理码按邀请码字符串尝试查找以避免重复创建
if inviteCodeId == "" && inviteCode != "" {
existingByCode, err2 := l.svcCtx.AgentShortLinkModel.FindOneByInviteCodeTypeDelState(l.ctx, sql.NullString{String: inviteCode, Valid: true}, 2, globalkey.DelStateNo)
if err2 == nil && existingByCode != nil {
return fmt.Sprintf("%s/s/%s", promotionConfig.PromotionDomain, existingByCode.ShortCode), nil
}
if err2 != nil && !errors.Is(err2, model.ErrNotFound) {
return "", errors.Wrapf(err2, "查询短链失败")
}
}
// 生成短链标识6位随机字符串大小写字母+数字)
var shortCode string
maxRetries := 10 // 最大重试次数
@@ -140,8 +165,9 @@ func (l *GetInviteLinkLogic) createInviteShortLink(inviteCodeId int64, inviteCod
// 创建短链记录类型2=邀请好友)
shortLink := &model.AgentShortLink{
Id: uuid.NewString(),
Type: 2, // 邀请好友
InviteCodeId: sql.NullInt64{Int64: inviteCodeId, Valid: inviteCodeId > 0},
InviteCodeId: sql.NullString{String: inviteCodeId, Valid: inviteCodeId != ""},
InviteCode: sql.NullString{String: inviteCode, Valid: inviteCode != ""},
ShortCode: shortCode,
TargetPath: targetPath,

View File

@@ -76,9 +76,11 @@ func (l *GetLevelPrivilegeLogic) GetLevelPrivilege() (resp *types.GetLevelPrivil
currentBonus = level1Bonus
}
// 获取升级返佣配置
// 获取升级返佣与费用配置
upgradeToGoldRebate := getConfigFloat("upgrade_to_gold_rebate", 139.0)
upgradeToDiamondRebate := getConfigFloat("upgrade_to_diamond_rebate", 680.0)
upgradeToGoldFee := getConfigFloat("upgrade_to_gold_fee", 199.0)
upgradeToDiamondFee := getConfigFloat("upgrade_to_diamond_fee", 980.0)
// 获取直接上级返佣配置
directParentAmountDiamond := getConfigFloat("direct_parent_amount_diamond", 6.0)
@@ -140,7 +142,11 @@ func (l *GetLevelPrivilegeLogic) GetLevelPrivilege() (resp *types.GetLevelPrivil
}
return &types.GetLevelPrivilegeResp{
Levels: levels,
Levels: levels,
UpgradeToGoldFee: upgradeToGoldFee,
UpgradeToDiamondFee: upgradeToDiamondFee,
UpgradeToGoldRebate: upgradeToGoldRebate,
UpgradeToDiamondRebate: upgradeToDiamondRebate,
}, nil
}

View File

@@ -52,7 +52,7 @@ func (l *GetLinkDataLogic) GetLinkData(req *types.GetLinkDataReq) (resp *types.G
}
// 创建featureId到sort的映射用于后续排序
featureSortMap := make(map[int64]int64)
featureSortMap := make(map[string]int64)
for _, productFeature := range productFeatureAll {
featureSortMap[productFeature.FeatureId] = productFeature.Sort
}
@@ -62,18 +62,18 @@ func (l *GetLinkDataLogic) GetLinkData(req *types.GetLinkDataReq) (resp *types.G
for _, productFeature := range productFeatureAll {
source <- productFeature.FeatureId
}
}, func(item interface{}, writer mr.Writer[*model.Feature], cancel func(error)) {
id := item.(int64)
}, func(item interface{}, writer mr.Writer[*model.Feature], cancel func(error)) {
id := item.(string)
feature, findFeatureErr := l.svcCtx.FeatureModel.FindOne(l.ctx, id)
if findFeatureErr != nil {
logx.WithContext(l.ctx).Errorf("获取产品功能失败: %d, err:%v", id, findFeatureErr)
return
}
if feature != nil && feature.Id > 0 {
writer.Write(feature)
}
}, func(pipe <-chan *model.Feature, cancel func(error)) {
feature, findFeatureErr := l.svcCtx.FeatureModel.FindOne(l.ctx, id)
if findFeatureErr != nil {
logx.WithContext(l.ctx).Errorf("获取产品功能失败: %s, err:%v", id, findFeatureErr)
return
}
if feature != nil && feature.Id != "" {
writer.Write(feature)
}
}, func(pipe <-chan *model.Feature, cancel func(error)) {
for item := range pipe {
var feature types.Feature
_ = copier.Copy(&feature, item)

View File

@@ -0,0 +1,88 @@
package agent
import (
"context"
"ycc-server/app/main/model"
"ycc-server/common/ctxdata"
"ycc-server/common/globalkey"
"ycc-server/common/xerr"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
)
type GetPromotionQueryListLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetPromotionQueryListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPromotionQueryListLogic {
return &GetPromotionQueryListLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetPromotionQueryListLogic) GetPromotionQueryList(req *types.GetPromotionQueryListReq) (resp *types.GetPromotionQueryListResp, err error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户信息失败, %v", err)
}
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)
}
// 查询当前代理的代理订单,按创建时间倒序分页
builder := l.svcCtx.AgentOrderModel.SelectBuilder().
Where("agent_id = ? AND del_state = ?", agent.Id, globalkey.DelStateNo)
orders, _, err := l.svcCtx.AgentOrderModel.FindPageListByPageWithTotal(l.ctx, builder, req.Page, req.PageSize, "create_time DESC")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理订单失败, %v", err)
}
// 组装查询报告列表(只展示已创建的查询)
list := make([]types.PromotionQueryItem, 0, len(orders))
for _, ao := range orders {
// 查询对应的报告
q, qErr := l.svcCtx.QueryModel.FindOneByOrderId(l.ctx, ao.OrderId)
if qErr != nil {
if errors.Is(qErr, model.ErrNotFound) {
// 订单对应的查询尚未创建,跳过展示
continue
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询报告失败, %v", qErr)
}
// 获取产品名称
product, pErr := l.svcCtx.ProductModel.FindOne(l.ctx, ao.ProductId)
if pErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询产品信息失败, %v", pErr)
}
item := types.PromotionQueryItem{}
_ = copier.Copy(&item, q)
item.Id = q.Id
item.OrderId = q.OrderId
item.ProductName = product.ProductName
item.CreateTime = q.CreateTime.Format("2006-01-02 15:04:05")
item.QueryState = q.QueryState
list = append(list, item)
}
return &types.GetPromotionQueryListResp{
Total: int64(len(list)), // 前端仅展示已创建查询条目
List: list,
}, nil
}

View File

@@ -85,7 +85,7 @@ func (l *GetRebateListLogic) GetRebateList(req *types.GetRebateListReq) (resp *t
for _, rebate := range rebates {
// 查询订单号
orderNo := ""
if rebate.OrderId > 0 {
if rebate.OrderId != "" {
order, err := l.svcCtx.OrderModel.FindOne(l.ctx, rebate.OrderId)
if err == nil {
orderNo = order.OrderNo
@@ -95,7 +95,7 @@ func (l *GetRebateListLogic) GetRebateList(req *types.GetRebateListReq) (resp *t
// 查询来源代理手机号和等级
sourceAgentMobile := ""
sourceAgentLevel := int64(0)
if rebate.SourceAgentId > 0 {
if rebate.SourceAgentId != "" {
sourceAgent, err := l.svcCtx.AgentModel.FindOne(l.ctx, rebate.SourceAgentId)
if err == nil {
if sourceAgent.Mobile != "" {

View File

@@ -184,7 +184,7 @@ func (l *GetSubordinateContributionDetailLogic) GetSubordinateContributionDetail
}
// isSubordinate 递归检查 targetId 是否是 parentId 的下级(直接或间接)
func (l *GetSubordinateContributionDetailLogic) isSubordinate(parentId, targetId int64) bool {
func (l *GetSubordinateContributionDetailLogic) isSubordinate(parentId, targetId string) bool {
// 查询直接下级
builder := l.svcCtx.AgentRelationModel.SelectBuilder().
Where("parent_id = ? AND relation_type = ? AND del_state = ?", parentId, 1, globalkey.DelStateNo)
@@ -215,7 +215,7 @@ func (l *GetSubordinateContributionDetailLogic) countDistinctOrders(ctx context.
return 0
}
orderIdSet := make(map[int64]bool)
orderIdSet := make(map[string]bool)
for _, rebate := range rebates {
orderIdSet[rebate.OrderId] = true
}
@@ -224,7 +224,7 @@ func (l *GetSubordinateContributionDetailLogic) countDistinctOrders(ctx context.
}
// getOrderList 获取订单列表(仅显示有返佣的订单)
func (l *GetSubordinateContributionDetailLogic) getOrderList(ctx context.Context, agentId, subordinateId int64, page, pageSize int64) ([]types.OrderItem, int64, error) {
func (l *GetSubordinateContributionDetailLogic) getOrderList(ctx context.Context, agentId, subordinateId string, page, pageSize int64) ([]types.OrderItem, int64, error) {
// 1. 查询所有返佣记录
rebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder().
Where("agent_id = ? AND source_agent_id = ? AND del_state = ?", agentId, subordinateId, globalkey.DelStateNo).
@@ -247,14 +247,14 @@ func (l *GetSubordinateContributionDetailLogic) getOrderList(ctx context.Context
// 2. 在内存中去重订单ID并按创建时间排序
type OrderRebateInfo struct {
OrderId int64
RebateId int64
ProductId int64
OrderId string
RebateId string
ProductId string
RebateAmount float64
CreateTime time.Time
}
orderMap := make(map[int64]*OrderRebateInfo) // orderId -> 最新的返佣信息
orderMap := make(map[string]*OrderRebateInfo) // orderId -> 最新的返佣信息
for _, rebate := range allRebates {
if existing, ok := orderMap[rebate.OrderId]; ok {
// 如果已存在,保留创建时间最新的
@@ -303,7 +303,7 @@ func (l *GetSubordinateContributionDetailLogic) getOrderList(ctx context.Context
// 5. 组装订单列表
var resultList []types.OrderItem
productCache := make(map[int64]string) // 产品ID -> 产品名称缓存
productCache := make(map[string]string) // 产品ID -> 产品名称缓存
for _, orderInfo := range pagedOrderList {
// 查询订单信息
@@ -344,7 +344,7 @@ func (l *GetSubordinateContributionDetailLogic) getOrderList(ctx context.Context
}
// getInviteList 获取邀请列表
func (l *GetSubordinateContributionDetailLogic) getInviteList(ctx context.Context, subordinateId int64, page, pageSize int64) ([]types.InviteItem, int64, error) {
func (l *GetSubordinateContributionDetailLogic) getInviteList(ctx context.Context, subordinateId string, page, pageSize int64) ([]types.InviteItem, int64, error) {
// 查询总数
builder := l.svcCtx.AgentRelationModel.SelectBuilder().
Where("parent_id = ? AND relation_type = ? AND del_state = ?", subordinateId, 1, globalkey.DelStateNo)

View File

@@ -50,12 +50,12 @@ func (l *GetTeamListLogic) GetTeamList(req *types.GetTeamListReq) (resp *types.G
}
// 2. 递归查询所有下级(直接+间接)
allSubordinateIds := make(map[int64]bool)
directSubordinateIds := make(map[int64]bool)
allSubordinateIds := make(map[string]bool)
directSubordinateIds := make(map[string]bool)
// 递归函数收集所有下级ID
var collectSubordinates func(int64) error
collectSubordinates = func(parentId int64) error {
var collectSubordinates func(string) error
collectSubordinates = func(parentId string) error {
// 查询直接下级
builder := l.svcCtx.AgentRelationModel.SelectBuilder().
Where("parent_id = ? AND relation_type = ? AND del_state = ?", parentId, 1, globalkey.DelStateNo)
@@ -94,7 +94,7 @@ func (l *GetTeamListLogic) GetTeamList(req *types.GetTeamListReq) (resp *types.G
}
// 4. 将下级ID转换为切片用于查询
subordinateIds := make([]int64, 0, len(allSubordinateIds))
subordinateIds := make([]string, 0, len(allSubordinateIds))
for id := range allSubordinateIds {
subordinateIds = append(subordinateIds, id)
}
@@ -183,7 +183,7 @@ func (l *GetTeamListLogic) GetTeamList(req *types.GetTeamListReq) (resp *types.G
// calculateTeamStatistics 计算团队统计数据
// 注意:所有统计都基于 subordinateIds下级ID列表不包含自己的数据
func (l *GetTeamListLogic) calculateTeamStatistics(agentId int64, subordinateIds []int64, todayStart, monthStart time.Time) types.TeamStatistics {
func (l *GetTeamListLogic) calculateTeamStatistics(agentId string, subordinateIds []string, todayStart, monthStart time.Time) types.TeamStatistics {
// 团队成员总数:只统计下级,不包括自己
stats := types.TeamStatistics{
TotalMembers: int64(len(subordinateIds)),
@@ -213,7 +213,7 @@ func (l *GetTeamListLogic) calculateTeamStatistics(agentId int64, subordinateIds
Where("agent_id = ? AND del_state = ?", agentId, globalkey.DelStateNo).
Where("source_agent_id != ?", agentId). // 明确排除自己
Where(squirrel.Eq{"source_agent_id": subordinateIds})
// 统计去重的订单数量
totalQueries := l.countDistinctOrders(l.ctx, rebateBuilder)
stats.TotalQueries = totalQueries
@@ -259,7 +259,7 @@ func (l *GetTeamListLogic) countDistinctOrders(ctx context.Context, builder squi
return 0
}
orderIdSet := make(map[int64]bool)
orderIdSet := make(map[string]bool)
for _, rebate := range rebates {
orderIdSet[rebate.OrderId] = true
}
@@ -275,7 +275,7 @@ func (l *GetTeamListLogic) countDistinctOrdersForMember(ctx context.Context, bui
return 0
}
orderIdSet := make(map[int64]bool)
orderIdSet := make(map[string]bool)
for _, rebate := range rebates {
orderIdSet[rebate.OrderId] = true
}
@@ -284,7 +284,7 @@ func (l *GetTeamListLogic) countDistinctOrdersForMember(ctx context.Context, bui
}
// buildTeamMemberItem 构建团队成员项
func (l *GetTeamListLogic) buildTeamMemberItem(agentId int64, member *model.Agent, directSubordinateIds map[int64]bool, todayStart time.Time) types.TeamMemberItem {
func (l *GetTeamListLogic) buildTeamMemberItem(agentId string, member *model.Agent, directSubordinateIds map[string]bool, todayStart time.Time) types.TeamMemberItem {
levelName := ""
switch member.Level {
case 1:

View File

@@ -47,12 +47,12 @@ func (l *GetTeamStatisticsLogic) GetTeamStatistics() (resp *types.TeamStatistics
}
// 2. 递归查询所有下级(直接+间接)
allSubordinateIds := make(map[int64]bool)
directSubordinateIds := make(map[int64]bool)
allSubordinateIds := make(map[string]bool)
directSubordinateIds := make(map[string]bool)
// 递归函数收集所有下级ID
var collectSubordinates func(int64) error
collectSubordinates = func(parentId int64) error {
var collectSubordinates func(string) error
collectSubordinates = func(parentId string) error {
// 查询直接下级
builder := l.svcCtx.AgentRelationModel.SelectBuilder().
Where("parent_id = ? AND relation_type = ? AND del_state = ?", parentId, 1, globalkey.DelStateNo)
@@ -63,23 +63,23 @@ func (l *GetTeamStatisticsLogic) GetTeamStatistics() (resp *types.TeamStatistics
for _, relation := range relations {
// 如果是第一层,标记为直接下级
if parentId == agent.Id {
directSubordinateIds[relation.ChildId] = true
}
// 添加到所有下级集合
allSubordinateIds[relation.ChildId] = true
// 递归查询下级的下级
if err := collectSubordinates(relation.ChildId); err != nil {
return err
}
}
return nil
}
if parentId == agent.Id {
directSubordinateIds[relation.ChildId] = true
}
// 添加到所有下级集合
allSubordinateIds[relation.ChildId] = true
// 递归查询下级的下级
if err := collectSubordinates(relation.ChildId); err != nil {
return err
}
}
return nil
}
// 开始递归收集所有下级
if err := collectSubordinates(agent.Id); err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询下级关系失败, %v", err)
}
if err := collectSubordinates(agent.Id); err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询下级关系失败, %v", err)
}
// 3. 获取当前时间用于统计今日和本月新增
now := time.Now()
@@ -100,10 +100,10 @@ func (l *GetTeamStatisticsLogic) GetTeamStatistics() (resp *types.TeamStatistics
}
// 5. 将下级ID转换为切片用于查询
subordinateIds := make([]int64, 0, len(allSubordinateIds))
for id := range allSubordinateIds {
subordinateIds = append(subordinateIds, id)
}
subordinateIds := make([]string, 0, len(allSubordinateIds))
for id := range allSubordinateIds {
subordinateIds = append(subordinateIds, id)
}
// 6. 查询所有下级代理信息
builder := l.svcCtx.AgentModel.SelectBuilder().

View File

@@ -82,7 +82,7 @@ func (l *GetUpgradeRebateListLogic) GetUpgradeRebateList(req *types.GetUpgradeRe
for _, upgrade := range upgrades {
// 查询来源代理手机号(升级的代理)
sourceAgentMobile := ""
if upgrade.AgentId > 0 {
if upgrade.AgentId != "" {
sourceAgent, err := l.svcCtx.AgentModel.FindOne(l.ctx, upgrade.AgentId)
if err == nil {
if sourceAgent.Mobile != "" {

View File

@@ -5,12 +5,15 @@ import (
"database/sql"
"fmt"
"os"
"strconv"
"time"
"ycc-server/app/main/model"
"ycc-server/common/ctxdata"
"ycc-server/common/globalkey"
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/crypto"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/core/stores/sqlx"
@@ -57,33 +60,26 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
}
}
// 1. 查询邀请码
inviteCodeModel, err := l.svcCtx.AgentInviteCodeModel.FindOneByCode(l.ctx, req.InviteCode)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码不存在"), "")
}
var inviteCodeModel *model.AgentInviteCode
inviteCodeModel, err = l.svcCtx.AgentInviteCodeModel.FindOneByCode(l.ctx, req.Referrer)
if err != nil && !errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询邀请码失败, %v", err)
}
// 2. 验证邀请码状态
// 钻石级别的邀请码只能使用一次,使用后立即失效
// 普通级别的邀请码可以无限使用
if inviteCodeModel.Status != 0 {
if inviteCodeModel.Status == 1 {
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已使用"), "")
if inviteCodeModel != nil {
if inviteCodeModel.Status != 0 {
if inviteCodeModel.Status == 1 {
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已使用"), "")
}
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已失效"), "")
}
if inviteCodeModel.ExpireTime.Valid && inviteCodeModel.ExpireTime.Time.Before(time.Now()) {
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已过期"), "")
}
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已失效"), "")
}
// 3. 验证邀请码是否过期
if inviteCodeModel.ExpireTime.Valid && inviteCodeModel.ExpireTime.Time.Before(time.Now()) {
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已过期"), "")
}
// 4. 使用事务处理注册
var userID int64
var agentID int64
var userID string
var agentID string
var agentLevel int64
err = l.svcCtx.AgentInviteCodeModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
@@ -113,15 +109,11 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
// 注意:非微信环境下 claims 为 nil此逻辑不会执行直接使用已存在的 user.Id
claims, err := ctxdata.GetClaimsFromCtx(l.ctx)
if err == nil && claims != nil && claims.UserType == model.UserTypeTemp {
userTemp, err := l.svcCtx.UserTempModel.FindOne(l.ctx, claims.UserId)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询临时用户失败, %v", err)
}
userAuth, err := l.svcCtx.UserAuthModel.FindOneByUserIdAuthType(l.ctx, user.Id, userTemp.AuthType)
userAuth, err := l.svcCtx.UserAuthModel.FindOneByUserIdAuthType(l.ctx, user.Id, claims.AuthType)
if err != nil && !errors.Is(err, model.ErrNotFound) {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询用户认证失败, %v", err)
}
if userAuth != nil && userAuth.AuthKey != userTemp.AuthKey {
if userAuth != nil && userAuth.AuthKey != claims.AuthKey {
return errors.Wrapf(xerr.NewErrMsg("该手机号已绑定其他微信号"), "")
}
// 绑定临时用户到正式用户
@@ -134,19 +126,37 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
userID = user.Id
}
// 4.2 获取邀请码信息
targetLevel := inviteCodeModel.TargetLevel
var parentAgentId int64 = 0
if inviteCodeModel.AgentId.Valid {
parentAgentId = inviteCodeModel.AgentId.Int64
var targetLevel int64
var parentAgentId string
if inviteCodeModel != nil {
targetLevel = inviteCodeModel.TargetLevel
if inviteCodeModel.AgentId.Valid {
parentAgentId = inviteCodeModel.AgentId.String
}
} else {
if codeVal, parseErr := strconv.ParseInt(req.Referrer, 10, 64); parseErr == nil && codeVal > 0 {
parentAgent, err := l.findAgentByCode(transCtx, codeVal)
if err != nil {
return errors.Wrapf(err, "")
}
parentAgentId = parentAgent.Id
targetLevel = 1
} else {
encRefMobile, _ := crypto.EncryptMobile(req.Referrer, l.svcCtx.Config.Encrypt.SecretKey)
agents, findErr := l.svcCtx.AgentModel.FindAll(transCtx, l.svcCtx.AgentModel.SelectBuilder().Where("mobile = ? AND del_state = ?", encRefMobile, globalkey.DelStateNo).Limit(1), "")
if findErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询上级代理失败, %v", findErr)
}
if len(agents) == 0 {
return errors.Wrapf(xerr.NewErrMsg("邀请信息无效"), "")
}
parentAgentId = agents[0].Id
targetLevel = 1
}
}
// 4.3 创建代理记录
newAgent := &model.Agent{
UserId: userID,
Level: targetLevel,
Mobile: encryptedMobile,
}
newAgent := &model.Agent{Id: uuid.NewString(), UserId: userID, Level: targetLevel, Mobile: encryptedMobile}
if req.Region != "" {
newAgent.Region = sql.NullString{String: req.Region, Valid: true}
}
@@ -155,7 +165,7 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
}
// 4.4 处理上级关系
if parentAgentId > 0 {
if parentAgentId != "" {
// 查找上级代理
parentAgent, err := l.svcCtx.AgentModel.FindOne(transCtx, parentAgentId)
if err != nil {
@@ -172,57 +182,50 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
if err != nil {
return errors.Wrapf(err, "查找团队首领失败")
}
if teamLeaderId > 0 {
newAgent.TeamLeaderId = sql.NullInt64{Int64: teamLeaderId, Valid: true}
if teamLeaderId != "" {
newAgent.TeamLeaderId = sql.NullString{String: teamLeaderId, Valid: true}
}
// 先插入代理记录
agentResult, err := l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
newAgent.AgentCode = 0
_, err = l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
if err != nil {
return errors.Wrapf(err, "创建代理记录失败")
}
agentID, _ = agentResult.LastInsertId()
newAgent.Id = agentID
agentID = newAgent.Id
// 建立关系
relation := &model.AgentRelation{
ParentId: parentAgent.Id,
ChildId: agentID,
RelationType: 1, // 直接关系
}
relation := &model.AgentRelation{Id: uuid.NewString(), ParentId: parentAgent.Id, ChildId: agentID, RelationType: 1}
if _, err := l.svcCtx.AgentRelationModel.Insert(transCtx, session, relation); err != nil {
return errors.Wrapf(err, "建立代理关系失败")
}
} else {
// 平台发放的钻石邀请码,独立成团队
if targetLevel == 3 {
// 先插入代理记录
agentResult, err := l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
newAgent.AgentCode = 0
_, err = l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
if err != nil {
return errors.Wrapf(err, "创建代理记录失败")
}
agentID, _ = agentResult.LastInsertId()
newAgent.Id = agentID
agentID = newAgent.Id
// 设置自己为团队首领
newAgent.TeamLeaderId = sql.NullInt64{Int64: agentID, Valid: true}
newAgent.TeamLeaderId = sql.NullString{String: agentID, Valid: true}
if err := l.svcCtx.AgentModel.UpdateInTransaction(transCtx, session, newAgent); err != nil {
return errors.Wrapf(err, "更新团队首领失败")
}
} else {
// 普通/黄金代理,但没有上级(异常情况)
agentResult, err := l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
newAgent.AgentCode = 0
_, err = l.svcCtx.AgentModel.Insert(transCtx, session, newAgent)
if err != nil {
return errors.Wrapf(err, "创建代理记录失败")
}
agentID, _ = agentResult.LastInsertId()
agentID = newAgent.Id
}
}
// 4.5 初始化钱包
wallet := &model.AgentWallet{
AgentId: agentID,
}
wallet := &model.AgentWallet{Id: uuid.NewString(), AgentId: agentID}
if _, err := l.svcCtx.AgentWalletModel.Insert(transCtx, session, wallet); err != nil {
return errors.Wrapf(err, "初始化钱包失败")
}
@@ -234,25 +237,21 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
// 钻石邀请码:使用后失效
inviteCodeModel.Status = 1 // 已使用(使用后立即失效)
}
// 记录使用信息(用于统计,普通邀请码可以多次使用)
inviteCodeModel.UsedUserId = sql.NullInt64{Int64: userID, Valid: true}
inviteCodeModel.UsedAgentId = sql.NullInt64{Int64: agentID, Valid: true}
inviteCodeModel.UsedTime = sql.NullTime{Time: time.Now(), Valid: true}
if err := l.svcCtx.AgentInviteCodeModel.UpdateWithVersion(transCtx, session, inviteCodeModel); err != nil {
return errors.Wrapf(err, "更新邀请码状态失败")
if inviteCodeModel != nil {
inviteCodeModel.UsedUserId = sql.NullString{String: userID, Valid: true}
inviteCodeModel.UsedAgentId = sql.NullString{String: agentID, Valid: true}
inviteCodeModel.UsedTime = sql.NullTime{Time: time.Now(), Valid: true}
if err := l.svcCtx.AgentInviteCodeModel.UpdateWithVersion(transCtx, session, inviteCodeModel); err != nil {
return errors.Wrapf(err, "更新邀请码状态失败")
}
}
// 4.7 记录邀请码使用历史(用于统计和查询)
usage := &model.AgentInviteCodeUsage{
InviteCodeId: inviteCodeModel.Id,
Code: inviteCodeModel.Code,
UserId: userID,
AgentId: agentID,
AgentLevel: targetLevel,
UsedTime: time.Now(),
}
if _, err := l.svcCtx.AgentInviteCodeUsageModel.Insert(transCtx, session, usage); err != nil {
return errors.Wrapf(err, "记录邀请码使用历史失败")
if inviteCodeModel != nil {
usage := &model.AgentInviteCodeUsage{Id: uuid.NewString(), InviteCodeId: inviteCodeModel.Id, Code: inviteCodeModel.Code, UserId: userID, AgentId: agentID, AgentLevel: targetLevel, UsedTime: time.Now()}
if _, err := l.svcCtx.AgentInviteCodeUsageModel.Insert(transCtx, session, usage); err != nil {
return errors.Wrapf(err, "记录邀请码使用历史失败")
}
}
agentLevel = targetLevel
@@ -280,6 +279,7 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
case 3:
levelName = "钻石"
}
agent, _ := l.svcCtx.AgentModel.FindOne(l.ctx, agentID)
return &types.RegisterByInviteCodeResp{
AccessToken: token,
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
@@ -287,11 +287,17 @@ func (l *RegisterByInviteCodeLogic) RegisterByInviteCode(req *types.RegisterByIn
AgentId: agentID,
Level: agentLevel,
LevelName: levelName,
AgentCode: func() int64 {
if agent != nil {
return agent.AgentCode
}
return 0
}(),
}, nil
}
// findTeamLeader 查找团队首领(钻石代理)
func (l *RegisterByInviteCodeLogic) findTeamLeader(ctx context.Context, agentId int64) (int64, error) {
func (l *RegisterByInviteCodeLogic) findTeamLeader(ctx context.Context, agentId string) (string, error) {
currentId := agentId
maxDepth := 100
depth := 0
@@ -301,22 +307,22 @@ func (l *RegisterByInviteCodeLogic) findTeamLeader(ctx context.Context, agentId
Where("child_id = ? AND relation_type = ? AND del_state = ?", currentId, 1, 0)
relations, err := l.svcCtx.AgentRelationModel.FindAll(ctx, builder, "")
if err != nil {
return 0, err
return "", err
}
if len(relations) == 0 {
agent, err := l.svcCtx.AgentModel.FindOne(ctx, currentId)
if err != nil {
return 0, err
return "", err
}
if agent.Level == 3 {
return agent.Id, nil
}
return 0, nil
return "", nil
}
parentAgent, err := l.svcCtx.AgentModel.FindOne(ctx, relations[0].ParentId)
if err != nil {
return 0, err
return "", err
}
if parentAgent.Level == 3 {
@@ -327,5 +333,30 @@ func (l *RegisterByInviteCodeLogic) findTeamLeader(ctx context.Context, agentId
depth++
}
return 0, nil
return "", nil
}
func (l *RegisterByInviteCodeLogic) findAgentByCode(ctx context.Context, code int64) (*model.Agent, error) {
builder := l.svcCtx.AgentModel.SelectBuilder().Where("agent_code = ? AND del_state = ?", code, globalkey.DelStateNo).Limit(1)
agents, err := l.svcCtx.AgentModel.FindAll(ctx, builder, "")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询上级代理失败, %v", err)
}
if len(agents) == 0 {
return nil, errors.Wrapf(xerr.NewErrMsg("上级邀请码不存在"), "")
}
return agents[0], nil
}
func (l *RegisterByInviteCodeLogic) allocateAgentCode(ctx context.Context, session sqlx.Session) (int64, error) {
builder := l.svcCtx.AgentModel.SelectBuilder().OrderBy("agent_code DESC").Limit(1)
rows, err := l.svcCtx.AgentModel.FindAll(ctx, builder, "")
if err != nil {
return 0, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理编码失败, %v", err)
}
var next int64 = 16800
if len(rows) > 0 && rows[0].AgentCode > 0 {
next = rows[0].AgentCode + 1
}
return next, nil
}

View File

@@ -60,15 +60,10 @@ func (l *ShortLinkRedirectLogic) ShortLinkRedirect(shortCode string, r *http.Req
}
}
} else if shortLink.Type == 2 {
// 邀请好友类型:验证邀请码是否存在
if shortLink.InviteCode.Valid && shortLink.InviteCode.String != "" {
_, err = l.svcCtx.AgentInviteCodeModel.FindOneByCode(l.ctx, shortLink.InviteCode.String)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return errors.Wrapf(xerr.NewErrCode(xerr.REUQEST_PARAM_ERROR), "邀请码不存在或已失效")
}
if err != nil && !errors.Is(err, model.ErrNotFound) {
l.Errorf("查询邀请码失败: %v", err)
// 即使查询失败,也继续重定向,避免影响用户体验
}
}
}
@@ -111,4 +106,3 @@ func (l *ShortLinkRedirectLogic) ShortLinkRedirect(shortCode string, r *http.Req
return nil
}

View File

@@ -9,6 +9,7 @@ import (
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/lzUtils"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/sqlx"
@@ -79,21 +80,21 @@ func (l *UpgradeSubordinateLogic) UpgradeSubordinate(req *types.UpgradeSubordina
err = l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
// 7.1 创建升级记录
upgradeRecord := &model.AgentUpgrade{
Id: uuid.New().String(),
AgentId: subordinateAgent.Id,
FromLevel: 1, // 普通
ToLevel: toLevel,
UpgradeType: 2, // 钻石升级下级
UpgradeFee: 0, // 免费
RebateAmount: 0, // 无返佣
OperatorAgentId: sql.NullInt64{Int64: operatorAgent.Id, Valid: true},
OperatorAgentId: sql.NullString{String: operatorAgent.Id, Valid: true},
Status: 1, // 待处理
}
upgradeResult, err := l.svcCtx.AgentUpgradeModel.Insert(transCtx, session, upgradeRecord)
_, err := l.svcCtx.AgentUpgradeModel.Insert(transCtx, session, upgradeRecord)
if err != nil {
return errors.Wrapf(err, "创建升级记录失败")
}
upgradeId, _ := upgradeResult.LastInsertId()
// 7.2 执行升级操作
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, subordinateAgent.Id, toLevel, 2, 0, 0, "", operatorAgent.Id); err != nil {
@@ -101,7 +102,6 @@ func (l *UpgradeSubordinateLogic) UpgradeSubordinate(req *types.UpgradeSubordina
}
// 7.3 更新升级记录状态
upgradeRecord.Id = upgradeId
upgradeRecord.Status = 2 // 已完成
upgradeRecord.Remark = lzUtils.StringToNullString("钻石代理升级下级成功")
if err := l.svcCtx.AgentUpgradeModel.UpdateWithVersion(transCtx, session, upgradeRecord); err != nil {
@@ -121,7 +121,7 @@ func (l *UpgradeSubordinateLogic) UpgradeSubordinate(req *types.UpgradeSubordina
}
// isSubordinate 递归检查 targetId 是否是 parentId 的下级(直接或间接)
func (l *UpgradeSubordinateLogic) isSubordinate(parentId, targetId int64) bool {
func (l *UpgradeSubordinateLogic) isSubordinate(parentId, targetId string) bool {
// 查询直接下级
builder := l.svcCtx.AgentRelationModel.SelectBuilder().
Where("parent_id = ? AND relation_type = ? AND del_state = ?", parentId, 1, globalkey.DelStateNo)

View File

@@ -0,0 +1,42 @@
package app
import (
"context"
"strconv"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"github.com/zeromicro/go-zero/core/logx"
)
type GetAppConfigLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetAppConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAppConfigLogic {
return &GetAppConfigLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetAppConfigLogic) GetAppConfig() (resp *types.GetAppConfigResp, err error) {
retentionDays := int64(0)
cfg, cfgErr := l.svcCtx.QueryCleanupConfigModel.FindOneByConfigKey(l.ctx, "retention_days")
if cfgErr == nil && cfg.Status == 1 {
if v, parseErr := strconv.ParseInt(cfg.ConfigValue, 10, 64); parseErr == nil && v >= 0 {
retentionDays = v
}
} else if cfgErr != nil && cfgErr != model.ErrNotFound {
l.Errorf("获取清理配置失败: %v", cfgErr)
}
return &types.GetAppConfigResp{
QueryRetentionDays: retentionDays,
}, nil
}

View File

@@ -28,13 +28,13 @@ func (l *DownloadAuthorizationDocumentLogic) DownloadAuthorizationDocument(req *
// 1. 从数据库获取授权书信息
authDoc, err := l.svcCtx.AuthorizationDocumentModel.FindOne(l.ctx, req.DocumentId)
if err != nil {
logx.Errorf("获取授权书失败: documentId=%d, error=%v", req.DocumentId, err)
logx.Errorf("获取授权书失败: documentId=%s, error=%v", req.DocumentId, err)
return nil, err
}
// 2. 检查授权书状态
if authDoc.Status != "active" {
logx.Errorf("授权书状态异常: documentId=%d, status=%s", req.DocumentId, authDoc.Status)
logx.Errorf("授权书状态异常: documentId=%s, status=%s", req.DocumentId, authDoc.Status)
return nil, errors.New("授权书不可用")
}

View File

@@ -37,7 +37,7 @@ func (l *GetAuthorizationDocumentByOrderLogic) GetAuthorizationDocumentByOrder(r
// 只返回状态为active的授权书
if authDoc.Status == "active" {
fullFileURL := l.svcCtx.AuthorizationService.GetFullFileURL(authDoc.FileUrl)
documents = append(documents, types.AuthorizationDocumentInfo{
DocumentId: authDoc.Id,
UserId: authDoc.UserId,

View File

@@ -182,7 +182,7 @@ func (l *AlipayCallbackLogic) handleAgentUpgradeOrderPayment(w http.ResponseWrit
if order.Status == "paid" {
err := l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
// 8.1 执行升级操作
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, upgradeRecord.AgentId, upgradeRecord.ToLevel, upgradeRecord.UpgradeType, upgradeRecord.UpgradeFee, upgradeRecord.RebateAmount, orderNo, 0); err != nil {
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, upgradeRecord.AgentId, upgradeRecord.ToLevel, upgradeRecord.UpgradeType, upgradeRecord.UpgradeFee, upgradeRecord.RebateAmount, orderNo, ""); err != nil {
return errors.Wrapf(err, "执行升级操作失败")
}

View File

@@ -2,11 +2,12 @@ package pay
import (
"context"
"fmt"
"time"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/lzUtils"
"time"
"github.com/pkg/errors"
@@ -29,7 +30,7 @@ func NewIapCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *IapCa
func (l *IapCallbackLogic) IapCallback(req *types.IapCallbackReq) error {
// Step 1: 查找订单
order, findOrderErr := l.svcCtx.OrderModel.FindOne(l.ctx, req.OrderID)
order, findOrderErr := l.svcCtx.OrderModel.FindOne(l.ctx, fmt.Sprintf("%d", req.OrderID))
if findOrderErr != nil {
logx.Errorf("苹果内购支付回调,查找订单失败: %+v", findOrderErr)
return nil

View File

@@ -16,6 +16,7 @@ import (
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/lzUtils"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/redis/go-redis/v9"
"github.com/zeromicro/go-zero/core/logx"
@@ -31,7 +32,7 @@ type PaymentTypeResp struct {
amount float64
outTradeNo string
description string
orderID int64 // 订单ID用于开发环境测试支付模式
orderID string // 订单ID用于开发环境测试支付模式
}
func NewPaymentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PaymentLogic {
@@ -45,7 +46,7 @@ func NewPaymentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PaymentLo
func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp, err error) {
var paymentTypeResp *PaymentTypeResp
var prepayData interface{}
var orderID int64
var orderID string
// 检查是否为开发环境的测试支付模式
env := os.Getenv("ENV")
@@ -77,14 +78,14 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
// 注意:订单状态更新在事务外进行,避免在事务中查询不到订单的问题
if isDevTestPayment {
// 获取订单ID从 QueryOrderPayment 返回的 orderID
if paymentTypeResp.orderID <= 0 {
if paymentTypeResp.orderID == "" {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "开发测试模式订单ID无效")
}
orderID = paymentTypeResp.orderID
// 在事务中只记录订单ID不更新订单状态
// 订单状态的更新和后续流程在事务提交后处理
logx.Infof("开发环境测试支付模式:订单 %s (ID: %d) 将在事务提交后更新状态", paymentTypeResp.outTradeNo, orderID)
logx.Infof("开发环境测试支付模式:订单 %s (ID: %s) 将在事务提交后更新状态", paymentTypeResp.outTradeNo, orderID)
// 返回测试支付标识
prepayData = "test_payment_success"
@@ -110,7 +111,7 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
}
// 开发环境测试支付模式:事务提交后处理订单状态更新和后续流程
if isDevTestPayment && paymentTypeResp != nil && paymentTypeResp.orderID > 0 {
if isDevTestPayment && paymentTypeResp != nil && paymentTypeResp.orderID != "" {
// 使用 goroutine 异步处理,确保事务已完全提交
go func() {
// 短暂延迟,确保事务已完全提交到数据库
@@ -121,7 +122,7 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
// 查找订单并更新状态为已支付
order, findOrderErr := l.svcCtx.OrderModel.FindOne(context.Background(), finalOrderID)
if findOrderErr != nil {
logx.Errorf("开发测试模式查找订单失败订单ID: %d, 错误: %v", finalOrderID, findOrderErr)
logx.Errorf("开发测试模式查找订单失败订单ID: %s, 错误: %v", finalOrderID, findOrderErr)
return
}
@@ -133,17 +134,17 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
// 空报告模式:在 PaymentPlatform 字段中标记,用于后续生成空报告
if isEmptyReportMode {
order.PaymentPlatform = "test_empty"
logx.Infof("开发环境空报告模式:订单 %s (ID: %d) 已标记为空报告模式", paymentTypeResp.outTradeNo, finalOrderID)
logx.Infof("开发环境空报告模式:订单 %s (ID: %s) 已标记为空报告模式", paymentTypeResp.outTradeNo, finalOrderID)
}
// 更新订单状态(在事务外执行)
updateErr := l.svcCtx.OrderModel.UpdateWithVersion(context.Background(), nil, order)
if updateErr != nil {
logx.Errorf("开发测试模式更新订单状态失败订单ID: %d, 错误: %+v", finalOrderID, updateErr)
logx.Errorf("开发测试模式更新订单状态失败订单ID: %s, 错误: %+v", finalOrderID, updateErr)
return
}
logx.Infof("开发环境测试支付模式:订单 %s (ID: %d) 已自动标记为已支付", paymentTypeResp.outTradeNo, finalOrderID)
logx.Infof("开发环境测试支付模式:订单 %s (ID: %s) 已自动标记为已支付", paymentTypeResp.outTradeNo, finalOrderID)
// 再次短暂延迟,确保订单状态更新已提交
time.Sleep(100 * time.Millisecond)
@@ -162,7 +163,7 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
// 执行升级操作
err := l.svcCtx.AgentWalletModel.Trans(context.Background(), func(transCtx context.Context, session sqlx.Session) error {
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, upgradeRecord.AgentId, upgradeRecord.ToLevel, upgradeRecord.UpgradeType, upgradeRecord.UpgradeFee, upgradeRecord.RebateAmount, paymentTypeResp.outTradeNo, 0); err != nil {
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, upgradeRecord.AgentId, upgradeRecord.ToLevel, upgradeRecord.UpgradeType, upgradeRecord.UpgradeFee, upgradeRecord.RebateAmount, paymentTypeResp.outTradeNo, ""); err != nil {
return errors.Wrapf(err, "执行升级操作失败")
}
@@ -179,14 +180,14 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
if err != nil {
logx.Errorf("开发测试模式,处理升级订单失败,订单号: %s, 错误: %+v", paymentTypeResp.outTradeNo, err)
} else {
logx.Infof("开发测试模式,代理升级成功,订单号: %s, 代理ID: %d", paymentTypeResp.outTradeNo, upgradeRecord.AgentId)
logx.Infof("开发测试模式,代理升级成功,订单号: %s, 代理ID: %s", paymentTypeResp.outTradeNo, upgradeRecord.AgentId)
}
} else {
// 查询订单:发送支付成功通知任务,触发后续流程(生成报告和代理处理)
if sendErr := l.svcCtx.AsynqService.SendQueryTask(finalOrderID); sendErr != nil {
logx.Errorf("开发测试模式发送支付成功通知任务失败订单ID: %d, 错误: %+v", finalOrderID, sendErr)
logx.Errorf("开发测试模式发送支付成功通知任务失败订单ID: %s, 错误: %+v", finalOrderID, sendErr)
} else {
logx.Infof("开发测试模式已发送支付成功通知任务订单ID: %d", finalOrderID)
logx.Infof("开发测试模式已发送支付成功通知任务订单ID: %s", finalOrderID)
}
}
}()
@@ -247,8 +248,8 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
if user.Inside == 1 {
amount = 0.01
}
var orderID int64
order := model.Order{
Id: uuid.NewString(),
OrderNo: outTradeNo,
UserId: userID,
ProductId: product.Id,
@@ -257,15 +258,11 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
Amount: amount,
Status: "pending",
}
orderInsertResult, insertOrderErr := l.svcCtx.OrderModel.Insert(l.ctx, session, &order)
_, insertOrderErr := l.svcCtx.OrderModel.Insert(l.ctx, session, &order)
if insertOrderErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存订单失败: %+v", insertOrderErr)
}
insertedOrderID, lastInsertIdErr := orderInsertResult.LastInsertId()
if lastInsertIdErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取保存订单ID失败: %+v", lastInsertIdErr)
}
orderID = insertedOrderID
orderID := order.Id
// 如果是代理推广订单,创建完整的代理订单记录
if data.AgentIdentifier != "" && agentLinkModel != nil {
@@ -279,7 +276,7 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
productConfig, err := l.svcCtx.AgentProductConfigModel.FindOneByProductId(l.ctx, product.Id)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单失败,产品配置不存在, productId: %d,请先在后台配置产品价格参数", product.Id)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单失败,产品配置不存在, productId: %s,请先在后台配置产品价格参数", product.Id)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 查询产品配置失败: %+v", err)
}
@@ -314,6 +311,7 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
// 创建代理订单记录
agentOrder := model.AgentOrder{
Id: uuid.NewString(),
AgentId: agentLinkModel.AgentId,
OrderId: orderID,
ProductId: product.Id,
@@ -346,10 +344,7 @@ func (l *PaymentLogic) AgentUpgradeOrderPayment(req *types.PaymentReq, session s
}
// 1. 解析升级记录ID
upgradeId, err := strconv.ParseInt(req.Id, 10, 64)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "无效的升级记录ID: %s", req.Id)
}
upgradeId := req.Id
// 2. 查找升级记录
upgradeRecord, err := l.svcCtx.AgentUpgradeModel.FindOne(l.ctx, upgradeId)
@@ -374,8 +369,12 @@ func (l *PaymentLogic) AgentUpgradeOrderPayment(req *types.PaymentReq, session s
return nil, errors.Wrapf(xerr.NewErrMsg("无权支付此升级订单"), "")
}
// 5. 生成订单号(使用 U_ 前缀表示升级订单)
outTradeNo := fmt.Sprintf("U_%d_%d", upgradeId, time.Now().Unix())
// 5. 生成订单号(升级订单前缀 U_限制长度不超过32
base := l.svcCtx.AlipayService.GenerateOutTradeNo()
outTradeNo := "U_" + base
if len(outTradeNo) > 32 {
outTradeNo = outTradeNo[:32]
}
// 6. 获取用户信息(用于内部用户判断)
user, err := l.svcCtx.UserModel.FindOne(l.ctx, userID)
@@ -391,9 +390,10 @@ func (l *PaymentLogic) AgentUpgradeOrderPayment(req *types.PaymentReq, session s
// 8. 创建订单记录
order := model.Order{
Id: uuid.NewString(),
OrderNo: outTradeNo,
UserId: userID,
ProductId: 0, // 升级订单没有产品ID
ProductId: "", // 升级订单没有产品ID
PaymentPlatform: req.PayMethod,
PaymentScene: "app",
Amount: amount,
@@ -403,10 +403,8 @@ func (l *PaymentLogic) AgentUpgradeOrderPayment(req *types.PaymentReq, session s
if insertOrderErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建订单失败: %+v", insertOrderErr)
}
orderID, lastInsertIdErr := orderInsertResult.LastInsertId()
if lastInsertIdErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取订单ID失败: %+v", lastInsertIdErr)
}
_ = orderInsertResult
orderID := order.Id
// 9. 更新升级记录的订单号
upgradeRecord.OrderNo = lzUtils.StringToNullString(outTradeNo)
@@ -425,10 +423,10 @@ func (l *PaymentLogic) AgentUpgradeOrderPayment(req *types.PaymentReq, session s
description := fmt.Sprintf("代理升级:%s → %s", fromLevelName, toLevelName)
return &PaymentTypeResp{
amount: amount,
outTradeNo: outTradeNo,
amount: amount,
outTradeNo: outTradeNo,
description: description,
orderID: orderID,
orderID: orderID,
}, nil
}

View File

@@ -177,7 +177,7 @@ func (l *WechatPayCallbackLogic) handleAgentUpgradeOrderPayment(w http.ResponseW
if order.Status == "paid" {
err := l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
// 8.1 执行升级操作
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, upgradeRecord.AgentId, upgradeRecord.ToLevel, upgradeRecord.UpgradeType, upgradeRecord.UpgradeFee, upgradeRecord.RebateAmount, orderNo, 0); err != nil {
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, upgradeRecord.AgentId, upgradeRecord.ToLevel, upgradeRecord.UpgradeType, upgradeRecord.UpgradeFee, upgradeRecord.RebateAmount, orderNo, ""); err != nil {
return errors.Wrapf(err, "执行升级操作失败")
}

Some files were not shown because too many files have changed in this diff Show More