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

2
.gitignore vendored
View File

@@ -20,3 +20,5 @@ data/*
/tmp/ /tmp/
/app/api /app/api
deploy/script/js

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -9,10 +9,10 @@ info (
//============================> user v1 <============================ //============================> user v1 <============================
// 用户基本类型定义 // 用户基本类型定义
type User { type User {
Id int64 `json:"id"` Id string `json:"id"`
Mobile string `json:"mobile"` Mobile string `json:"mobile"`
NickName string `json:"nickName"` NickName string `json:"nickName"`
UserType int64 `json:"userType"` UserType int64 `json:"userType"`
} }
//no need login //no need login
@@ -21,6 +21,9 @@ type User {
group: user group: user
) )
service main { service main {
@doc "unified auth"
@handler auth
post /user/auth (AuthReq) returns (AuthResp)
@doc "mobile code login" @doc "mobile code login"
@handler mobileCodeLogin @handler mobileCodeLogin
post /user/mobileCodeLogin (MobileCodeLoginReq) returns (MobileCodeLoginResp) post /user/mobileCodeLogin (MobileCodeLoginReq) returns (MobileCodeLoginResp)
@@ -38,6 +41,18 @@ service main {
} }
type ( 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 { MobileCodeLoginReq {
Mobile string `json:"mobile"` Mobile string `json:"mobile"`
Code string `json:"code" validate:"required"` Code string `json:"code" validate:"required"`

View File

@@ -1,6 +1,7 @@
Name: main Name: main
Host: 0.0.0.0 Host: 0.0.0.0
Port: 8888 Port: 8888
Timeout: 0
DataSource: "ycc:5vg67b3UNHu8@tcp(127.0.0.1:21001)/ycc?charset=utf8mb4&parseTime=True&loc=Local" DataSource: "ycc:5vg67b3UNHu8@tcp(127.0.0.1:21001)/ycc?charset=utf8mb4&parseTime=True&loc=Local"
CacheRedis: CacheRedis:
- Host: "127.0.0.1:21002" - 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", Path: "/product_config",
Handler: agent.GetAgentProductConfigHandler(serverCtx), Handler: agent.GetAgentProductConfigHandler(serverCtx),
}, },
{
Method: http.MethodGet,
Path: "/promotion/query/list",
Handler: agent.GetPromotionQueryListHandler(serverCtx),
},
{ {
Method: http.MethodPost, Method: http.MethodPost,
Path: "/real_name", Path: "/real_name",
@@ -745,6 +750,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes( server.AddRoutes(
[]rest.Route{ []rest.Route{
{
Method: http.MethodGet,
Path: "/app/config",
Handler: app.GetAppConfigHandler(serverCtx),
},
{ {
Method: http.MethodGet, Method: http.MethodGet,
Path: "/app/version", Path: "/app/version",
@@ -828,7 +838,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes( server.AddRoutes(
rest.WithMiddlewares( rest.WithMiddlewares(
[]rest.Middleware{serverCtx.UserAuthInterceptor}, []rest.Middleware{serverCtx.AuthInterceptor},
[]rest.Route{ []rest.Route{
{ {
Method: http.MethodPost, Method: http.MethodPost,
@@ -900,7 +910,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes( server.AddRoutes(
rest.WithMiddlewares( rest.WithMiddlewares(
[]rest.Middleware{serverCtx.UserAuthInterceptor}, []rest.Middleware{serverCtx.AuthInterceptor},
[]rest.Route{ []rest.Route{
{ {
// query service // query service
@@ -916,7 +926,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes( server.AddRoutes(
rest.WithMiddlewares( rest.WithMiddlewares(
[]rest.Middleware{serverCtx.UserAuthInterceptor}, []rest.Middleware{serverCtx.AuthInterceptor},
[]rest.Route{ []rest.Route{
{ {
// 生成分享链接 // 生成分享链接
@@ -991,6 +1001,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes( server.AddRoutes(
[]rest.Route{ []rest.Route{
{
// unified auth
Method: http.MethodPost,
Path: "/user/auth",
Handler: user.AuthHandler(serverCtx),
},
{ {
// mobile code login // mobile code login
Method: http.MethodPost, 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 package admin_agent
import ( import (
"context" "context"
"database/sql" "database/sql"
"time" "time"
"ycc-server/app/main/model" "ycc-server/app/main/model"
"ycc-server/common/tool" "ycc-server/common/tool"
"ycc-server/common/xerr" "ycc-server/common/xerr"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/sqlx" "github.com/zeromicro/go-zero/core/stores/sqlx"
"ycc-server/app/main/api/internal/svc" "ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types" "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 { type AdminGenerateDiamondInviteCodeLogic struct {
@@ -70,14 +71,15 @@ func (l *AdminGenerateDiamondInviteCodeLogic) AdminGenerateDiamondInviteCode(req
} }
// 创建邀请码记录(平台发放的钻石邀请码) // 创建邀请码记录(平台发放的钻石邀请码)
inviteCode := &model.AgentInviteCode{ inviteCode := &model.AgentInviteCode{
Code: code, Id: uuid.NewString(),
AgentId: sql.NullInt64{Valid: false}, // NULL表示平台发放 Code: code,
TargetLevel: 3, // 钻石代理 AgentId: sql.NullString{Valid: false}, // NULL表示平台发放
Status: 0, // 未使用 TargetLevel: 3, // 钻石代理
ExpireTime: expireTime, Status: 0, // 未使用
Remark: sql.NullString{String: req.Remark, Valid: req.Remark != ""}, ExpireTime: expireTime,
} Remark: sql.NullString{String: req.Remark, Valid: req.Remark != ""},
}
_, err := l.svcCtx.AgentInviteCodeModel.Insert(transCtx, session, inviteCode) _, err := l.svcCtx.AgentInviteCodeModel.Insert(transCtx, session, inviteCode)
if err != nil { if err != nil {

View File

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

View File

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

View File

@@ -44,15 +44,15 @@ func (l *AdminGetAgentLinkListLogic) AdminGetAgentLinkList(req *types.AdminGetAg
} }
// 批量查product_id->name避免N+1 // 批量查product_id->name避免N+1
productIdSet := make(map[int64]struct{}) productIdSet := make(map[string]struct{})
for _, link := range links { for _, link := range links {
productIdSet[link.ProductId] = struct{}{} productIdSet[link.ProductId] = struct{}{}
} }
productIdList := make([]int64, 0, len(productIdSet)) productIdList := make([]string, 0, len(productIdSet))
for id := range productIdSet { for id := range productIdSet {
productIdList = append(productIdList, id) productIdList = append(productIdList, id)
} }
productNameMap := make(map[int64]string) productNameMap := make(map[string]string)
if len(productIdList) > 0 { if len(productIdList) > 0 {
products, _ := l.svcCtx.ProductModel.FindAll(l.ctx, l.svcCtx.ProductModel.SelectBuilder().Where(squirrel.Eq{"id": productIdList}), "") products, _ := l.svcCtx.ProductModel.FindAll(l.ctx, l.svcCtx.ProductModel.SelectBuilder().Where(squirrel.Eq{"id": productIdList}), "")
for _, p := range products { for _, p := range products {
@@ -63,14 +63,14 @@ func (l *AdminGetAgentLinkListLogic) AdminGetAgentLinkList(req *types.AdminGetAg
items := make([]types.AgentLinkListItem, 0, len(links)) items := make([]types.AgentLinkListItem, 0, len(links))
for _, link := range links { for _, link := range links {
items = append(items, types.AgentLinkListItem{ items = append(items, types.AgentLinkListItem{
Id: link.Id, Id: link.Id,
AgentId: link.AgentId, AgentId: link.AgentId,
ProductId: link.ProductId, ProductId: link.ProductId,
ProductName: productNameMap[link.ProductId], ProductName: productNameMap[link.ProductId],
SetPrice: link.SetPrice, SetPrice: link.SetPrice,
ActualBasePrice: link.ActualBasePrice, ActualBasePrice: link.ActualBasePrice,
LinkIdentifier: link.LinkIdentifier, LinkIdentifier: link.LinkIdentifier,
CreateTime: link.CreateTime.Format("2006-01-02 15:04:05"), 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) { func (l *AdminGetAgentListLogic) AdminGetAgentList(req *types.AdminGetAgentListReq) (resp *types.AdminGetAgentListResp, err error) {
builder := l.svcCtx.AgentModel.SelectBuilder() builder := l.svcCtx.AgentModel.SelectBuilder()
// 如果传入TeamLeaderId则查找该团队首领下的所有代理 // 如果传入TeamLeaderId则查找该团队首领下的所有代理
if req.TeamLeaderId != nil { if req.TeamLeaderId != nil {
builder = builder.Where(squirrel.Eq{"team_leader_id": *req.TeamLeaderId}) 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) wallet, _ := l.svcCtx.AgentWalletModel.FindOneByAgentId(l.ctx, agent.Id)
// 查询实名认证信息 // 查询实名认证信息
realNameInfo, _ := l.svcCtx.AgentRealNameModel.FindOneByAgentId(l.ctx, agent.Id) realNameInfo, _ := l.svcCtx.AgentRealNameModel.FindOneByAgentId(l.ctx, agent.Id)
isRealName := false isRealName := false
@@ -90,9 +90,9 @@ func (l *AdminGetAgentListLogic) AdminGetAgentList(req *types.AdminGetAgentListR
if agent.WechatId.Valid { if agent.WechatId.Valid {
wechatId = agent.WechatId.String wechatId = agent.WechatId.String
} }
teamLeaderId := int64(0) teamLeaderId := ""
if agent.TeamLeaderId.Valid { 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{ item := types.AgentListItem{
Id: agent.Id, Id: agent.Id,
UserId: agent.UserId, UserId: agent.UserId,
Level: agent.Level, Level: agent.Level,
LevelName: levelName, LevelName: levelName,
Region: region, Region: region,
Mobile: agent.Mobile, Mobile: agent.Mobile,
WechatId: wechatId, WechatId: wechatId,
TeamLeaderId: teamLeaderId, TeamLeaderId: teamLeaderId,
Balance: 0, AgentCode: agent.AgentCode,
TotalEarnings: 0, Balance: 0,
FrozenBalance: 0, TotalEarnings: 0,
FrozenBalance: 0,
WithdrawnAmount: 0, WithdrawnAmount: 0,
IsRealName: isRealName, IsRealName: isRealName,
CreateTime: agent.CreateTime.Format("2006-01-02 15:04:05"), CreateTime: agent.CreateTime.Format("2006-01-02 15:04:05"),
} }
if wallet != nil { if wallet != nil {
item.Balance = wallet.Balance item.Balance = wallet.Balance
item.TotalEarnings = wallet.TotalEarnings 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 { for _, order := range orders {
productIdSet[order.ProductId] = struct{}{} productIdSet[order.ProductId] = struct{}{}
} }
productIdList := make([]int64, 0, len(productIdSet)) productIdList := make([]string, 0, len(productIdSet))
for id := range productIdSet { for id := range productIdSet {
productIdList = append(productIdList, id) productIdList = append(productIdList, id)
} }
productNameMap := make(map[int64]string) productNameMap := make(map[string]string)
if len(productIdList) > 0 { if len(productIdList) > 0 {
products, _ := l.svcCtx.ProductModel.FindAll(l.ctx, l.svcCtx.ProductModel.SelectBuilder().Where(squirrel.Eq{"id": productIdList}), "") products, _ := l.svcCtx.ProductModel.FindAll(l.ctx, l.svcCtx.ProductModel.SelectBuilder().Where(squirrel.Eq{"id": productIdList}), "")
for _, p := range products { 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 { for _, rebate := range rebates {
productIdSet[rebate.ProductId] = struct{}{} productIdSet[rebate.ProductId] = struct{}{}
} }
productIdList := make([]int64, 0, len(productIdSet)) productIdList := make([]string, 0, len(productIdSet))
for id := range productIdSet { for id := range productIdSet {
productIdList = append(productIdList, id) productIdList = append(productIdList, id)
} }
productNameMap := make(map[int64]string) productNameMap := make(map[string]string)
if len(productIdList) > 0 { if len(productIdList) > 0 {
products, _ := l.svcCtx.ProductModel.FindAll(l.ctx, l.svcCtx.ProductModel.SelectBuilder().Where(squirrel.Eq{"id": productIdList}), "") products, _ := l.svcCtx.ProductModel.FindAll(l.ctx, l.svcCtx.ProductModel.SelectBuilder().Where(squirrel.Eq{"id": productIdList}), "")
for _, p := range products { for _, p := range products {
@@ -79,12 +79,12 @@ func (l *AdminGetAgentRebateListLogic) AdminGetAgentRebateList(req *types.AdminG
for _, rebate := range rebates { for _, rebate := range rebates {
items = append(items, types.AgentRebateListItem{ items = append(items, types.AgentRebateListItem{
Id: rebate.Id, Id: rebate.Id,
AgentId: rebate.AgentId, AgentId: rebate.AgentId,
SourceAgentId: rebate.SourceAgentId, SourceAgentId: rebate.SourceAgentId,
OrderId: rebate.OrderId, OrderId: rebate.OrderId,
RebateType: rebate.RebateType, RebateType: rebate.RebateType,
Amount: rebate.RebateAmount, Amount: rebate.RebateAmount,
CreateTime: rebate.CreateTime.Format("2006-01-02 15:04:05"), 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 != "" { if req.Code != nil && *req.Code != "" {
builder = builder.Where("code = ?", *req.Code) builder = builder.Where("code = ?", *req.Code)
} }
if req.AgentId != nil { if req.AgentId != nil && *req.AgentId != "" {
if *req.AgentId == 0 { if *req.AgentId == "0" {
// agent_id = 0 表示查询平台发放的邀请码agent_id为NULL // agent_id = 0 表示查询平台发放的邀请码agent_id为NULL
builder = builder.Where("agent_id IS NULL") builder = builder.Where("agent_id IS NULL")
} else { } else {
@@ -59,16 +59,16 @@ func (l *AdminGetInviteCodeListLogic) AdminGetInviteCodeList(req *types.AdminGet
} }
// 3. 批量查询代理信息(用于显示代理手机号) // 3. 批量查询代理信息(用于显示代理手机号)
agentIds := make(map[int64]struct{}) agentIds := make(map[string]struct{})
for _, v := range list { for _, v := range list {
if v.AgentId.Valid && v.AgentId.Int64 > 0 { if v.AgentId.Valid && v.AgentId.String != "" {
agentIds[v.AgentId.Int64] = struct{}{} agentIds[v.AgentId.String] = struct{}{}
} }
} }
agentMobileMap := make(map[int64]string) agentMobileMap := make(map[string]string)
if len(agentIds) > 0 { if len(agentIds) > 0 {
agentIdList := make([]int64, 0, len(agentIds)) agentIdList := make([]string, 0, len(agentIds))
for id := range agentIds { for id := range agentIds {
agentIdList = append(agentIdList, id) agentIdList = append(agentIdList, id)
} }
@@ -90,7 +90,7 @@ func (l *AdminGetInviteCodeListLogic) AdminGetInviteCodeList(req *types.AdminGet
item := types.InviteCodeListItem{ item := types.InviteCodeListItem{
Id: v.Id, Id: v.Id,
Code: v.Code, Code: v.Code,
AgentId: 0, AgentId: "",
AgentMobile: "", AgentMobile: "",
TargetLevel: v.TargetLevel, TargetLevel: v.TargetLevel,
Status: v.Status, Status: v.Status,
@@ -98,15 +98,15 @@ func (l *AdminGetInviteCodeListLogic) AdminGetInviteCodeList(req *types.AdminGet
} }
if v.AgentId.Valid { if v.AgentId.Valid {
item.AgentId = v.AgentId.Int64 item.AgentId = v.AgentId.String
item.AgentMobile = agentMobileMap[v.AgentId.Int64] item.AgentMobile = agentMobileMap[v.AgentId.String]
} }
if v.UsedUserId.Valid { if v.UsedUserId.Valid {
item.UsedUserId = v.UsedUserId.Int64 item.UsedUserId = v.UsedUserId.String
} }
if v.UsedAgentId.Valid { if v.UsedAgentId.Valid {
item.UsedAgentId = v.UsedAgentId.Int64 item.UsedAgentId = v.UsedAgentId.String
} }
if v.UsedTime.Valid { if v.UsedTime.Valid {
item.UsedTime = v.UsedTime.Time.Format("2006-01-02 15:04:05") item.UsedTime = v.UsedTime.Time.Format("2006-01-02 15:04:05")

View File

@@ -2,6 +2,7 @@ package admin_agent
import ( import (
"context" "context"
"database/sql"
"strconv" "strconv"
"ycc-server/common/xerr" "ycc-server/common/xerr"
@@ -9,6 +10,7 @@ import (
"ycc-server/app/main/api/internal/svc" "ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types" "ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"github.com/zeromicro/go-zero/core/logx" "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) { 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 { updateConfig := func(key string, value *float64) error {
if value == nil { if value == nil {
return nil return nil
} }
valStr := strconv.FormatFloat(*value, 'f', -1, 64)
config, err := l.svcCtx.AgentConfigModel.FindOneByConfigKey(l.ctx, key) config, err := l.svcCtx.AgentConfigModel.FindOneByConfigKey(l.ctx, key)
if err != nil { 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) return errors.Wrapf(err, "查询配置失败, key: %s", key)
} }
config.ConfigValue = strconv.FormatFloat(*value, 'f', -1, 64) config.ConfigValue = valStr
return l.svcCtx.AgentConfigModel.UpdateWithVersion(l.ctx, nil, config) 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) 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{ return &types.AdminUpdateAgentConfigResp{
Success: true, Success: true,
}, nil }, nil

View File

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

View File

@@ -8,6 +8,7 @@ import (
"ycc-server/app/main/model" "ycc-server/app/main/model"
"ycc-server/common/xerr" "ycc-server/common/xerr"
"github.com/google/uuid"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
) )
@@ -58,6 +59,7 @@ func (l *AdminCreateApiLogic) AdminCreateApi(req *types.AdminCreateApiReq) (resp
// 3. 创建API记录 // 3. 创建API记录
apiData := &model.AdminApi{ apiData := &model.AdminApi{
Id: uuid.NewString(),
ApiName: req.ApiName, ApiName: req.ApiName,
ApiCode: req.ApiCode, ApiCode: req.ApiCode,
Method: req.Method, Method: req.Method,
@@ -71,8 +73,7 @@ func (l *AdminCreateApiLogic) AdminCreateApi(req *types.AdminCreateApiReq) (resp
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
"创建API失败, err: %v", err) "创建API失败, err: %v", err)
} }
// 4. 返回结果 // 4. 返回结果
apiId, _ := result.LastInsertId() _ = result
return &types.AdminCreateApiResp{Id: apiId}, nil 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) { func (l *AdminDeleteApiLogic) AdminDeleteApi(req *types.AdminDeleteApiReq) (resp *types.AdminDeleteApiResp, err error) {
// 1. 参数验证 // 1. 参数验证
if req.Id <= 0 { if req.Id == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR), 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是否存在 // 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) { func (l *AdminGetApiDetailLogic) AdminGetApiDetail(req *types.AdminGetApiDetailReq) (resp *types.AdminGetApiDetailResp, err error) {
// 1. 参数验证 // 1. 参数验证
if req.Id <= 0 { if req.Id == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR), 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详情 // 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) { func (l *AdminUpdateApiLogic) AdminUpdateApi(req *types.AdminUpdateApiReq) (resp *types.AdminUpdateApiResp, err error) {
// 1. 参数验证 // 1. 参数验证
if req.Id <= 0 { if req.Id == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR), 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 == "" { if req.ApiName == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR), 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数组 // 获取角色ID数组
roleIds := make([]int64, 0) roleIds := make([]string, 0)
for _, permission := range permissions { for _, permission := range permissions {
roleIds = append(roleIds, permission.RoleId) 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 expiresAt := l.svcCtx.Config.AdminConfig.AccessExpire
claims := jwtx.JwtClaims{ claims := jwtx.JwtClaims{
UserId: user.Id, UserId: user.Id,
AgentId: 0, AgentId: "",
Platform: model.PlatformAdmin, Platform: model.PlatformAdmin,
UserType: model.UserTypeAdmin, UserType: model.UserTypeAdmin,
IsAgent: model.AgentStatusNo, IsAgent: model.AgentStatusNo,

View File

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

View File

@@ -8,6 +8,7 @@ import (
"ycc-server/app/main/model" "ycc-server/app/main/model"
"ycc-server/common/xerr" "ycc-server/common/xerr"
"github.com/google/uuid"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx" "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) { func (l *AdminCreateFeatureLogic) AdminCreateFeature(req *types.AdminCreateFeatureReq) (resp *types.AdminCreateFeatureResp, err error) {
// 1. 数据转换 // 1. 数据转换
data := &model.Feature{ data := &model.Feature{
Id: uuid.NewString(),
ApiId: req.ApiId, ApiId: req.ApiId,
Name: req.Name, Name: req.Name,
} }
@@ -41,6 +43,6 @@ func (l *AdminCreateFeatureLogic) AdminCreateFeature(req *types.AdminCreateFeatu
} }
// 3. 返回结果 // 3. 返回结果
id, _ := result.LastInsertId() _ = result
return &types.AdminCreateFeatureResp{Id: id}, nil 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) { if errors.Is(err, model.ErrNotFound) {
// 示例数据不存在,返回空数据 // 示例数据不存在,返回空数据
return &types.AdminGetFeatureExampleResp{ return &types.AdminGetFeatureExampleResp{
Id: 0, Id: "",
FeatureId: req.FeatureId, FeatureId: req.FeatureId,
ApiId: "", ApiId: "",
Data: "", 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) { func (l *AdminUpdateFeatureLogic) AdminUpdateFeature(req *types.AdminUpdateFeatureReq) (resp *types.AdminUpdateFeatureResp, err error) {
// 1. 参数验证 // 1. 参数验证
if req.Id <= 0 { if req.Id == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR), return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
"功能ID必须大于0, id: %d", req.Id) "功能ID不能为空, id: %s", req.Id)
} }
// 2. 查询记录是否存在 // 2. 查询记录是否存在

View File

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

View File

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

View File

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

View File

@@ -45,13 +45,13 @@ func (l *UpdateMenuLogic) UpdateMenu(req *types.UpdateMenuReq) (resp *types.Upda
} }
// 3. 检查父菜单是否存在(如果不是根菜单) // 3. 检查父菜单是否存在(如果不是根菜单)
if req.Pid > 0 { if req.Pid != nil && *req.Pid != "0" {
parentMenu, err := l.svcCtx.AdminMenuModel.FindOne(l.ctx, req.Pid) parentMenu, err := l.svcCtx.AdminMenuModel.FindOne(l.ctx, *req.Pid)
if err != nil { 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 { 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. 更新菜单信息 // 5. 更新菜单信息
menu.Pid = req.Pid menu.Pid = sql.NullString{String: *req.Pid, Valid: req.Pid != nil}
menu.Name = req.Name menu.Name = req.Name
menu.Path = req.Path menu.Path = req.Path
menu.Component = req.Component menu.Component = req.Component

View File

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

View File

@@ -11,6 +11,7 @@ import (
"ycc-server/app/main/model" "ycc-server/app/main/model"
"ycc-server/common/xerr" "ycc-server/common/xerr"
"github.com/google/uuid"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx" "github.com/zeromicro/go-zero/core/stores/sqlx"
@@ -48,6 +49,7 @@ func (l *AdminCreateOrderLogic) AdminCreateOrder(req *types.AdminCreateOrderReq)
// 创建订单对象 // 创建订单对象
order := &model.Order{ order := &model.Order{
Id: uuid.NewString(),
OrderNo: orderNo, OrderNo: orderNo,
PlatformOrderId: sql.NullString{String: req.PlatformOrderId, Valid: req.PlatformOrderId != ""}, PlatformOrderId: sql.NullString{String: req.PlatformOrderId, Valid: req.PlatformOrderId != ""},
ProductId: product.Id, 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 { 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 { if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "AdminCreateOrder, 创建订单失败 err: %v", err) return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "AdminCreateOrder, 创建订单失败 err: %v", err)
} }
orderId = order.Id
// 获取订单ID
orderId, err = result.LastInsertId()
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "AdminCreateOrder, 获取订单ID失败 err: %v", err)
}
return nil return nil
}) })

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -11,6 +11,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx" "github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/google/uuid"
) )
type CreateRoleLogic struct { 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) return nil, errors.Wrapf(xerr.NewErrMsg("角色名称已存在"), "创建角色失败, 角色名称已存在: %v", err)
} }
// 创建角色 // 创建角色
role := &model.AdminRole{ role := &model.AdminRole{
RoleName: req.RoleName, Id: uuid.NewString(),
RoleCode: req.RoleCode, RoleName: req.RoleName,
Description: req.Description, RoleCode: req.RoleCode,
Status: req.Status, Description: req.Description,
Sort: req.Sort, Status: req.Status,
} Sort: req.Sort,
var roleId int64 }
var roleId string
// 使用事务创建角色和关联菜单 // 使用事务创建角色和关联菜单
err = l.svcCtx.AdminRoleModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error { err = l.svcCtx.AdminRoleModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
// 创建角色 // 创建角色
result, err := l.svcCtx.AdminRoleModel.Insert(ctx, session, role) _, err := l.svcCtx.AdminRoleModel.Insert(ctx, session, role)
if err != nil { if err != nil {
return errors.New("插入新角色失败") return errors.New("插入新角色失败")
} }
roleId, err = result.LastInsertId() roleId = role.Id
if err != nil {
return errors.New("获取新角色ID失败")
}
// 创建角色菜单关联 // 创建角色菜单关联
if len(req.MenuIds) > 0 { if len(req.MenuIds) > 0 {
for _, menuId := range req.MenuIds { for _, menuId := range req.MenuIds {
roleMenu := &model.AdminRoleMenu{ roleMenu := &model.AdminRoleMenu{
RoleId: roleId, Id: uuid.NewString(),
MenuId: menuId, RoleId: roleId,
} MenuId: menuId,
_, err = l.svcCtx.AdminRoleMenuModel.Insert(ctx, session, roleMenu) }
if err != nil { _, err = l.svcCtx.AdminRoleMenuModel.Insert(ctx, session, roleMenu)
return errors.New("插入角色菜单关联失败") 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 nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建角色失败: %v", err)
} }
return &types.CreateRoleResp{ return &types.CreateRoleResp{
Id: roleId, Id: roleId,
}, nil }, 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) { func (l *GetRoleDetailLogic) GetRoleDetail(req *types.GetRoleDetailReq) (resp *types.GetRoleDetailResp, err error) {
// 使用MapReduceVoid并发获取角色信息和菜单ID // 使用MapReduceVoid并发获取角色信息和菜单ID
var role *model.AdminRole var role *model.AdminRole
var menuIds []int64 var menuIds []string
var mutex sync.Mutex var mutex sync.Mutex
var wg sync.WaitGroup var wg sync.WaitGroup
@@ -62,7 +62,7 @@ func (l *GetRoleDetailLogic) GetRoleDetail(req *types.GetRoleDetailReq) (resp *t
return return
} }
mutex.Lock() 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 return item.MenuId
}) })
mutex.Unlock() mutex.Unlock()

View File

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

View File

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

View File

@@ -1,15 +1,16 @@
package admin_role_api package admin_role_api
import ( import (
"context" "context"
"ycc-server/app/main/api/internal/svc" "ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types" "ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model" "ycc-server/app/main/model"
"ycc-server/common/xerr" "ycc-server/common/xerr"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
"github.com/google/uuid"
) )
type AdminAssignRoleApiLogic struct { 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) { func (l *AdminAssignRoleApiLogic) AdminAssignRoleApi(req *types.AdminAssignRoleApiReq) (resp *types.AdminAssignRoleApiResp, err error) {
// 1. 参数验证 // 1. 参数验证
if req.RoleId <= 0 { if req.RoleId == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR), 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 { if len(req.ApiIds) == 0 {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR), return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
@@ -51,7 +52,7 @@ func (l *AdminAssignRoleApiLogic) AdminAssignRoleApi(req *types.AdminAssignRoleA
// 3. 批量分配API权限 // 3. 批量分配API权限
successCount := 0 successCount := 0
for _, apiId := range req.ApiIds { for _, apiId := range req.ApiIds {
if apiId <= 0 { if apiId == "" {
continue continue
} }
@@ -59,10 +60,10 @@ func (l *AdminAssignRoleApiLogic) AdminAssignRoleApi(req *types.AdminAssignRoleA
_, err := l.svcCtx.AdminApiModel.FindOne(l.ctx, apiId) _, err := l.svcCtx.AdminApiModel.FindOne(l.ctx, apiId)
if err != nil { if err != nil {
if errors.Is(err, model.ErrNotFound) { if errors.Is(err, model.ErrNotFound) {
logx.Errorf("API不存在, apiId: %d", apiId) logx.Errorf("API不存在, apiId: %s", apiId)
continue continue
} }
logx.Errorf("查询API失败, err: %v, apiId: %d", err, apiId) logx.Errorf("查询API失败, err: %v, apiId: %s", err, apiId)
continue continue
} }
@@ -77,10 +78,11 @@ func (l *AdminAssignRoleApiLogic) AdminAssignRoleApi(req *types.AdminAssignRoleA
} }
// 创建关联 // 创建关联
roleApiData := &model.AdminRoleApi{ roleApiData := &model.AdminRoleApi{
RoleId: req.RoleId, Id: uuid.NewString(),
ApiId: apiId, RoleId: req.RoleId,
} ApiId: apiId,
}
_, err = l.svcCtx.AdminRoleApiModel.Insert(l.ctx, nil, roleApiData) _, err = l.svcCtx.AdminRoleApiModel.Insert(l.ctx, nil, roleApiData)
if err != nil { 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) { func (l *AdminGetAllApiListLogic) AdminGetAllApiList(req *types.AdminGetAllApiListReq) (resp *types.AdminGetAllApiListResp, err error) {
// 1. 构建查询条件 // 1. 构建查询条件
builder := l.svcCtx.AdminApiModel.SelectBuilder() builder := l.svcCtx.AdminApiModel.SelectBuilder()
// 添加状态过滤 // 添加状态过滤
if req.Status > 0 { if req.Status > 0 {
builder = builder.Where("status = ?", req.Status) builder = builder.Where("status = ?", req.Status)
@@ -45,8 +45,8 @@ func (l *AdminGetAllApiListLogic) AdminGetAllApiList(req *types.AdminGetAllApiLi
var apiList []types.AdminRoleApiInfo var apiList []types.AdminRoleApiInfo
for _, api := range apis { for _, api := range apis {
apiList = append(apiList, types.AdminRoleApiInfo{ apiList = append(apiList, types.AdminRoleApiInfo{
Id: 0, // 这里不是关联ID而是API ID Id: api.Id,
RoleId: 0, // 这里不是角色ID RoleId: "",
ApiId: api.Id, ApiId: api.Id,
ApiName: api.ApiName, ApiName: api.ApiName,
ApiCode: api.ApiCode, 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) { func (l *AdminGetRoleApiListLogic) AdminGetRoleApiList(req *types.AdminGetRoleApiListReq) (resp *types.AdminGetRoleApiListResp, err error) {
// 1. 参数验证 // 1. 参数验证
if req.RoleId <= 0 { if req.RoleId == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR), return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
"角色ID必须大于0, roleId: %d", req.RoleId) "角色ID不能为空, roleId: %s", req.RoleId)
} }
// 2. 查询角色是否存在 // 2. 查询角色是否存在
@@ -38,7 +38,7 @@ func (l *AdminGetRoleApiListLogic) AdminGetRoleApiList(req *types.AdminGetRoleAp
if err != nil { if err != nil {
if errors.Is(err, model.ErrNotFound) { if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), 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), return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
"查询角色失败, err: %v, roleId: %d", err, req.RoleId) "查询角色失败, err: %v, roleId: %d", err, req.RoleId)
@@ -47,7 +47,7 @@ func (l *AdminGetRoleApiListLogic) AdminGetRoleApiList(req *types.AdminGetRoleAp
// 3. 查询角色API权限列表 // 3. 查询角色API权限列表
builder := l.svcCtx.AdminRoleApiModel.SelectBuilder(). builder := l.svcCtx.AdminRoleApiModel.SelectBuilder().
Where("role_id = ?", req.RoleId) Where("role_id = ?", req.RoleId)
roleApis, err := l.svcCtx.AdminRoleApiModel.FindAll(l.ctx, builder, "") roleApis, err := l.svcCtx.AdminRoleApiModel.FindAll(l.ctx, builder, "")
if err != nil { if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), 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) { func (l *AdminRemoveRoleApiLogic) AdminRemoveRoleApi(req *types.AdminRemoveRoleApiReq) (resp *types.AdminRemoveRoleApiResp, err error) {
// 1. 参数验证 // 1. 参数验证
if req.RoleId <= 0 { if req.RoleId == "" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR), 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 { if len(req.ApiIds) == 0 {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR), return nil, errors.Wrapf(xerr.NewErrCode(xerr.PARAM_VERIFICATION_ERROR),
@@ -51,7 +51,7 @@ func (l *AdminRemoveRoleApiLogic) AdminRemoveRoleApi(req *types.AdminRemoveRoleA
// 3. 批量移除API权限 // 3. 批量移除API权限
successCount := 0 successCount := 0
for _, apiId := range req.ApiIds { for _, apiId := range req.ApiIds {
if apiId <= 0 { if apiId == "" {
continue continue
} }
@@ -61,7 +61,7 @@ func (l *AdminRemoveRoleApiLogic) AdminRemoveRoleApi(req *types.AdminRemoveRoleA
if errors.Is(err, model.ErrNotFound) { if errors.Is(err, model.ErrNotFound) {
continue // 不存在,跳过 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 continue
} }

View File

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

View File

@@ -9,6 +9,7 @@ import (
"ycc-server/common/xerr" "ycc-server/common/xerr"
"ycc-server/pkg/lzkit/crypto" "ycc-server/pkg/lzkit/crypto"
"github.com/google/uuid"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx" "github.com/zeromicro/go-zero/core/stores/sqlx"
@@ -43,8 +44,9 @@ func (l *AdminCreateUserLogic) AdminCreateUser(req *types.AdminCreateUserReq) (r
} }
// 创建用户 // 创建用户
user := &model.AdminUser{ user := &model.AdminUser{
Id: uuid.NewString(),
Username: req.Username, Username: req.Username,
Password: password, // 注意:实际应用中需要加密密码 Password: password,
RealName: req.RealName, RealName: req.RealName,
Status: req.Status, 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 { 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 { if err != nil {
return err return err
} }
userId, err := result.LastInsertId()
if err != nil {
return err
}
// 创建用户角色关联 // 创建用户角色关联
if len(req.RoleIds) > 0 { if len(req.RoleIds) > 0 {
for _, roleId := range req.RoleIds { for _, roleId := range req.RoleIds {
userRole := &model.AdminUserRole{ userRole := &model.AdminUserRole{
UserId: userId, Id: uuid.NewString(),
UserId: user.Id,
RoleId: roleId, RoleId: roleId,
} }
_, err = l.svcCtx.AdminUserRoleModel.Insert(ctx, session, userRole) _, 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) { func (l *AdminGetUserDetailLogic) AdminGetUserDetail(req *types.AdminGetUserDetailReq) (resp *types.AdminGetUserDetailResp, err error) {
// 使用MapReduceVoid并发获取用户信息和角色ID // 使用MapReduceVoid并发获取用户信息和角色ID
var user *model.AdminUser var user *model.AdminUser
var roleIds []int64 var roleIds []string
var mutex sync.Mutex var mutex sync.Mutex
var wg sync.WaitGroup var wg sync.WaitGroup
@@ -61,7 +61,7 @@ func (l *AdminGetUserDetailLogic) AdminGetUserDetail(req *types.AdminGetUserDeta
return return
} }
mutex.Lock() 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 return item.RoleId
}) })
mutex.Unlock() mutex.Unlock()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -53,7 +53,7 @@ func (l *DeleteInviteCodeLogic) DeleteInviteCode(req *types.DeleteInviteCodeReq)
} }
// 3. 验证邀请码是否属于当前代理 // 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("无权删除此邀请码"), "") return nil, errors.Wrapf(xerr.NewErrMsg("无权删除此邀请码"), "")
} }

View File

@@ -87,9 +87,9 @@ func (l *GenerateInviteCodeLogic) GenerateInviteCode(req *types.GenerateInviteCo
// 创建邀请码记录 // 创建邀请码记录
inviteCode := &model.AgentInviteCode{ inviteCode := &model.AgentInviteCode{
Code: code, Code: code,
AgentId: sql.NullInt64{Int64: agent.Id, Valid: true}, AgentId: sql.NullString{String: agent.Id, Valid: true},
TargetLevel: 1, // 代理发放的邀请码,目标等级为普通代理 TargetLevel: 1, // 代理发放的邀请码,目标等级为普通代理
Status: 0, // 未使用 Status: 0, // 未使用
ExpireTime: expireTime, ExpireTime: expireTime,
Remark: sql.NullString{String: req.Remark, Valid: req.Remark != ""}, 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/svc"
"ycc-server/app/main/api/internal/types" "ycc-server/app/main/api/internal/types"
"github.com/google/uuid"
"github.com/zeromicro/go-zero/core/logx" "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) return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取等级加成配置失败, %v", err)
} }
// 4. 计算实际底价(产品基础底价 + 等级加成) basePrice := productConfig.BasePrice
basePrice := productConfig.BasePrice actualBasePrice := basePrice + float64(levelBonus)
actualBasePrice := basePrice + float64(levelBonus) systemMaxPrice := productConfig.SystemMaxPrice
systemMaxPrice := productConfig.SystemMaxPrice upliftAmount, err := l.getLevelMaxUpliftAmount(agentModel.Level)
if err != nil {
// 5. 验证设定价格范围 return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取等级上调金额失败, %v", err)
if req.SetPrice < actualBasePrice || req.SetPrice > systemMaxPrice { }
return nil, errors.Wrapf(xerr.NewErrMsg("设定价格必须在 %.2f 到 %.2f 之间"), "设定价格必须在 %.2f 到 %.2f 之间", actualBasePrice, systemMaxPrice) levelMaxPrice := systemMaxPrice + upliftAmount
} if req.SetPrice < actualBasePrice || req.SetPrice > levelMaxPrice {
return nil, errors.Wrapf(xerr.NewErrMsg("设定价格必须在 %.2f 到 %.2f 之间"), "设定价格必须在 %.2f 到 %.2f 之间", actualBasePrice, levelMaxPrice)
}
// 6. 检查是否已存在相同的链接(同一代理、同一产品、同一价格) // 6. 检查是否已存在相同的链接(同一代理、同一产品、同一价格)
builder := l.svcCtx.AgentLinkModel.SelectBuilder().Where(squirrel.And{ builder := l.svcCtx.AgentLinkModel.SelectBuilder().Where(squirrel.And{
@@ -98,7 +101,7 @@ func (l *GeneratingLinkLogic) GeneratingLink(req *types.AgentGeneratingLinkReq)
if targetPath == "" { if targetPath == "" {
targetPath = "/agent/promotionInquire/" 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 { if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取或创建短链失败, %v", err) return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取或创建短链失败, %v", err)
} }
@@ -132,6 +135,7 @@ func (l *GeneratingLinkLogic) GeneratingLink(req *types.AgentGeneratingLinkReq)
// 9. 保存推广链接 // 9. 保存推广链接
agentLink := &model.AgentLink{ agentLink := &model.AgentLink{
// Id: uuid.NewString(),
AgentId: agentModel.Id, AgentId: agentModel.Id,
UserId: userID, UserId: userID,
ProductId: req.ProductId, ProductId: req.ProductId,
@@ -140,16 +144,12 @@ func (l *GeneratingLinkLogic) GeneratingLink(req *types.AgentGeneratingLinkReq)
ActualBasePrice: actualBasePrice, ActualBasePrice: actualBasePrice,
} }
result, err := l.svcCtx.AgentLinkModel.Insert(l.ctx, nil, agentLink) _, err = l.svcCtx.AgentLinkModel.Insert(l.ctx, nil, agentLink)
if err != nil { if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "保存推广链接失败, %v", err) return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "保存推广链接失败, %v", err)
} }
// 获取插入的ID linkId := agentLink.Id
linkId, err := result.LastInsertId()
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取推广链接ID失败, %v", err)
}
// 使用默认target_path如果未提供 // 使用默认target_path如果未提供
targetPath := req.TargetPath targetPath := req.TargetPath
@@ -158,7 +158,7 @@ func (l *GeneratingLinkLogic) GeneratingLink(req *types.AgentGeneratingLinkReq)
} }
// 生成短链类型1=推广报告) // 生成短链类型1=推广报告)
shortLink, err := l.createShortLink(1, linkId, 0, encrypted, "", targetPath) shortLink, err := l.createShortLink(1, linkId, "", encrypted, "", targetPath)
if err != nil { if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成短链失败, %v", err) 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 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 获取或创建短链 // getOrCreateShortLink 获取或创建短链
// type: 1=推广报告(promotion), 2=邀请好友(invite) // type: 1=推广报告(promotion), 2=邀请好友(invite)
// linkId: 推广链接ID仅推广报告使用 // linkId: 推广链接ID仅推广报告使用
@@ -212,20 +236,20 @@ func (l *GeneratingLinkLogic) getLevelBonus(level int64) (int64, error) {
// linkIdentifier: 推广链接标识(仅推广报告使用) // linkIdentifier: 推广链接标识(仅推广报告使用)
// inviteCode: 邀请码(仅邀请好友使用) // inviteCode: 邀请码(仅邀请好友使用)
// targetPath: 目标地址(前端传入) // 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 existingShortLink *model.AgentShortLink
var err error var err error
if linkType == 1 { if linkType == 1 {
// 推广报告类型使用link_id查询 // 推广报告类型使用link_id查询
if linkId > 0 { if linkId != "" {
existingShortLink, err = l.svcCtx.AgentShortLinkModel.FindOneByLinkIdTypeDelState(l.ctx, sql.NullInt64{Int64: linkId, Valid: true}, linkType, globalkey.DelStateNo) existingShortLink, err = l.svcCtx.AgentShortLinkModel.FindOneByLinkIdTypeDelState(l.ctx, sql.NullString{String: linkId, Valid: true}, linkType, globalkey.DelStateNo)
} }
} else { } else {
// 邀请好友类型使用invite_code_id查询 // 邀请好友类型使用invite_code_id查询
if inviteCodeId > 0 { if inviteCodeId != "" {
existingShortLink, err = l.svcCtx.AgentShortLinkModel.FindOneByInviteCodeIdTypeDelState(l.ctx, sql.NullInt64{Int64: inviteCodeId, Valid: true}, linkType, globalkey.DelStateNo) 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 创建短链 // createShortLink 创建短链
// type: 1=推广报告(promotion), 2=邀请好友(invite) // 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 promotionConfig := l.svcCtx.Config.Promotion
// 如果没有配置推广域名,返回空字符串(保持向后兼容) // 如果没有配置推广域名,返回空字符串(保持向后兼容)
@@ -291,6 +315,7 @@ func (l *GeneratingLinkLogic) createShortLink(linkType int64, linkId, inviteCode
// 创建短链记录 // 创建短链记录
shortLink := &model.AgentShortLink{ shortLink := &model.AgentShortLink{
Id: uuid.NewString(),
Type: linkType, Type: linkType,
ShortCode: shortCode, ShortCode: shortCode,
TargetPath: targetPath, TargetPath: targetPath,
@@ -300,13 +325,13 @@ func (l *GeneratingLinkLogic) createShortLink(linkType int64, linkId, inviteCode
// 根据类型设置对应字段 // 根据类型设置对应字段
if linkType == 1 { if linkType == 1 {
// 推广报告类型 // 推广报告类型
shortLink.LinkId = sql.NullInt64{Int64: linkId, Valid: linkId > 0} shortLink.LinkId = sql.NullString{String: linkId, Valid: linkId != ""}
if linkIdentifier != "" { if linkIdentifier != "" {
shortLink.LinkIdentifier = sql.NullString{String: linkIdentifier, Valid: true} shortLink.LinkIdentifier = sql.NullString{String: linkIdentifier, Valid: true}
} }
} else if linkType == 2 { } else if linkType == 2 {
// 邀请好友类型 // 邀请好友类型
shortLink.InviteCodeId = sql.NullInt64{Int64: inviteCodeId, Valid: inviteCodeId > 0} shortLink.InviteCodeId = sql.NullString{String: inviteCodeId, Valid: inviteCodeId != ""}
if inviteCode != "" { if inviteCode != "" {
shortLink.InviteCode = sql.NullString{String: inviteCode, Valid: true} 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) { if errors.Is(err, model.ErrNotFound) {
// 不是代理,返回空信息 // 不是代理,返回空信息
return &types.AgentInfoResp{ return &types.AgentInfoResp{
AgentId: 0, AgentId: "",
Level: 0, Level: 0,
LevelName: "", LevelName: "",
Region: "", Region: "",
Mobile: "", Mobile: "",
WechatId: "", WechatId: "",
TeamLeaderId: 0, TeamLeaderId: "",
IsRealName: false, IsRealName: false,
}, nil }, nil
} }
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败, %v", err) 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 // 获取团队首领ID
teamLeaderId := int64(0) teamLeaderId := ""
if agent.TeamLeaderId.Valid { 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{ return &types.AgentInfoResp{
AgentId: agent.Id, AgentId: agent.Id,
Level: agent.Level, Level: agent.Level,
LevelName: l.getLevelName(agent.Level), LevelName: l.getLevelName(agent.Level),
Region: region, Region: region,
Mobile: mobile, Mobile: mobile,
WechatId: wechatId, WechatId: wechatId,
TeamLeaderId: teamLeaderId, TeamLeaderId: teamLeaderId,
IsRealName: isRealName, IsRealName: isRealName,
AgentCode: agent.AgentCode,
}, nil }, nil
} }

View File

@@ -78,9 +78,9 @@ func (l *GetAgentProductConfigLogic) GetAgentProductConfig() (resp *types.AgentP
// 计算该产品的实际底价 // 计算该产品的实际底价
productActualBasePrice := productBasePrice + float64(levelBonus) productActualBasePrice := productBasePrice + float64(levelBonus)
// 价格范围:实际底价 ≤ 设定价格 ≤ 产品配置的最高价格 priceRangeMin := productActualBasePrice
priceRangeMin := productActualBasePrice upliftAmount, _ := l.getLevelMaxUpliftAmount(agentModel.Level)
priceRangeMax := productConfig.SystemMaxPrice priceRangeMax := productConfig.SystemMaxPrice + upliftAmount
// 使用产品配置的提价阈值和手续费比例如果为NULL则使用0 // 使用产品配置的提价阈值和手续费比例如果为NULL则使用0
productPriceThreshold := 0.0 productPriceThreshold := 0.0
@@ -144,3 +144,27 @@ func (l *GetAgentProductConfigLogic) getLevelBonus(level int64) (int64, error) {
} }
return int64(value), nil 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 { for _, commission := range commissions {
// 查询产品名称 // 查询产品名称
productName := "" productName := ""
if commission.ProductId > 0 { if commission.ProductId != "" {
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, commission.ProductId) product, err := l.svcCtx.ProductModel.FindOne(l.ctx, commission.ProductId)
if err == nil { if err == nil {
productName = product.ProductName productName = product.ProductName
@@ -87,7 +87,7 @@ func (l *GetCommissionListLogic) GetCommissionList(req *types.GetCommissionListR
// 查询订单号 // 查询订单号
orderNo := "" orderNo := ""
if commission.OrderId > 0 { if commission.OrderId != "" {
order, err := l.svcCtx.OrderModel.FindOne(l.ctx, commission.OrderId) order, err := l.svcCtx.OrderModel.FindOne(l.ctx, commission.OrderId)
if err == nil { if err == nil {
orderNo = order.OrderNo orderNo = order.OrderNo

View File

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

View File

@@ -4,18 +4,22 @@ import (
"context" "context"
"database/sql" "database/sql"
"fmt" "fmt"
"strconv"
"strings"
"time" "time"
"ycc-server/app/main/model" "ycc-server/app/main/model"
"ycc-server/common/ctxdata" "ycc-server/common/ctxdata"
"ycc-server/common/globalkey" "ycc-server/common/globalkey"
"ycc-server/common/tool" "ycc-server/common/tool"
"ycc-server/common/xerr" "ycc-server/common/xerr"
"ycc-server/pkg/lzkit/crypto"
"github.com/pkg/errors" "github.com/pkg/errors"
"ycc-server/app/main/api/internal/svc" "ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types" "ycc-server/app/main/api/internal/types"
"github.com/google/uuid"
"github.com/zeromicro/go-zero/core/logx" "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("邀请码不能为空"), "") return nil, errors.Wrapf(xerr.NewErrMsg("邀请码不能为空"), "")
} }
// 3. 查询邀请码是否存在且属于当前代理 ref := strings.TrimSpace(req.InviteCode)
inviteCodeRecord, err := l.svcCtx.AgentInviteCodeModel.FindOneByCode(l.ctx, req.InviteCode) var inviteCodeRecord *model.AgentInviteCode
if err != nil { inviteCodeRecord, err = l.svcCtx.AgentInviteCodeModel.FindOneByCode(l.ctx, ref)
if errors.Is(err, model.ErrNotFound) { if err != nil && !errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrMsg("邀请码不存在"), "")
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询邀请码失败, %v", err) return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询邀请码失败, %v", err)
} }
// 4. 验证邀请码是否属于当前代理 if inviteCodeRecord != nil {
if !inviteCodeRecord.AgentId.Valid || inviteCodeRecord.AgentId.Int64 != agent.Id { if !inviteCodeRecord.AgentId.Valid || inviteCodeRecord.AgentId.String != agent.Id {
return nil, errors.Wrapf(xerr.NewErrMsg("无权使用此邀请码"), "") return nil, errors.Wrapf(xerr.NewErrMsg("无权使用此邀请码"), "")
} }
if inviteCodeRecord.Status != 0 {
// 5. 验证邀请码状态 if inviteCodeRecord.Status == 1 {
if inviteCodeRecord.Status != 0 { return nil, errors.Wrapf(xerr.NewErrMsg("邀请码已使用"), "")
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如果未提供 // 7. 使用默认target_path如果未提供
targetPath := req.TargetPath targetPath := req.TargetPath
if 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(func() string {
shortLink, err := l.createInviteShortLink(inviteCodeRecord.Id, req.InviteCode, targetPath) if inviteCodeRecord != nil {
return inviteCodeRecord.Id
}
return ""
}(), ref, targetPath)
if err != nil { if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成短链失败, %v", err) 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 创建邀请好友短链 // 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 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 { if err == nil && existingShortLink != nil {
// 已存在短链,直接返回 // 已存在短链,直接返回
return fmt.Sprintf("%s/s/%s", promotionConfig.PromotionDomain, existingShortLink.ShortCode), 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, "查询短链失败") 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位随机字符串大小写字母+数字) // 生成短链标识6位随机字符串大小写字母+数字)
var shortCode string var shortCode string
maxRetries := 10 // 最大重试次数 maxRetries := 10 // 最大重试次数
@@ -140,8 +165,9 @@ func (l *GetInviteLinkLogic) createInviteShortLink(inviteCodeId int64, inviteCod
// 创建短链记录类型2=邀请好友) // 创建短链记录类型2=邀请好友)
shortLink := &model.AgentShortLink{ shortLink := &model.AgentShortLink{
Id: uuid.NewString(),
Type: 2, // 邀请好友 Type: 2, // 邀请好友
InviteCodeId: sql.NullInt64{Int64: inviteCodeId, Valid: inviteCodeId > 0}, InviteCodeId: sql.NullString{String: inviteCodeId, Valid: inviteCodeId != ""},
InviteCode: sql.NullString{String: inviteCode, Valid: inviteCode != ""}, InviteCode: sql.NullString{String: inviteCode, Valid: inviteCode != ""},
ShortCode: shortCode, ShortCode: shortCode,
TargetPath: targetPath, TargetPath: targetPath,

View File

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

View File

@@ -52,7 +52,7 @@ func (l *GetLinkDataLogic) GetLinkData(req *types.GetLinkDataReq) (resp *types.G
} }
// 创建featureId到sort的映射用于后续排序 // 创建featureId到sort的映射用于后续排序
featureSortMap := make(map[int64]int64) featureSortMap := make(map[string]int64)
for _, productFeature := range productFeatureAll { for _, productFeature := range productFeatureAll {
featureSortMap[productFeature.FeatureId] = productFeature.Sort featureSortMap[productFeature.FeatureId] = productFeature.Sort
} }
@@ -62,18 +62,18 @@ func (l *GetLinkDataLogic) GetLinkData(req *types.GetLinkDataReq) (resp *types.G
for _, productFeature := range productFeatureAll { for _, productFeature := range productFeatureAll {
source <- productFeature.FeatureId source <- productFeature.FeatureId
} }
}, func(item interface{}, writer mr.Writer[*model.Feature], cancel func(error)) { }, func(item interface{}, writer mr.Writer[*model.Feature], cancel func(error)) {
id := item.(int64) id := item.(string)
feature, findFeatureErr := l.svcCtx.FeatureModel.FindOne(l.ctx, id) feature, findFeatureErr := l.svcCtx.FeatureModel.FindOne(l.ctx, id)
if findFeatureErr != nil { if findFeatureErr != nil {
logx.WithContext(l.ctx).Errorf("获取产品功能失败: %d, err:%v", id, findFeatureErr) logx.WithContext(l.ctx).Errorf("获取产品功能失败: %s, err:%v", id, findFeatureErr)
return return
} }
if feature != nil && feature.Id > 0 { if feature != nil && feature.Id != "" {
writer.Write(feature) writer.Write(feature)
} }
}, func(pipe <-chan *model.Feature, cancel func(error)) { }, func(pipe <-chan *model.Feature, cancel func(error)) {
for item := range pipe { for item := range pipe {
var feature types.Feature var feature types.Feature
_ = copier.Copy(&feature, item) _ = 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 { for _, rebate := range rebates {
// 查询订单号 // 查询订单号
orderNo := "" orderNo := ""
if rebate.OrderId > 0 { if rebate.OrderId != "" {
order, err := l.svcCtx.OrderModel.FindOne(l.ctx, rebate.OrderId) order, err := l.svcCtx.OrderModel.FindOne(l.ctx, rebate.OrderId)
if err == nil { if err == nil {
orderNo = order.OrderNo orderNo = order.OrderNo
@@ -95,7 +95,7 @@ func (l *GetRebateListLogic) GetRebateList(req *types.GetRebateListReq) (resp *t
// 查询来源代理手机号和等级 // 查询来源代理手机号和等级
sourceAgentMobile := "" sourceAgentMobile := ""
sourceAgentLevel := int64(0) sourceAgentLevel := int64(0)
if rebate.SourceAgentId > 0 { if rebate.SourceAgentId != "" {
sourceAgent, err := l.svcCtx.AgentModel.FindOne(l.ctx, rebate.SourceAgentId) sourceAgent, err := l.svcCtx.AgentModel.FindOne(l.ctx, rebate.SourceAgentId)
if err == nil { if err == nil {
if sourceAgent.Mobile != "" { if sourceAgent.Mobile != "" {

View File

@@ -184,7 +184,7 @@ func (l *GetSubordinateContributionDetailLogic) GetSubordinateContributionDetail
} }
// isSubordinate 递归检查 targetId 是否是 parentId 的下级(直接或间接) // isSubordinate 递归检查 targetId 是否是 parentId 的下级(直接或间接)
func (l *GetSubordinateContributionDetailLogic) isSubordinate(parentId, targetId int64) bool { func (l *GetSubordinateContributionDetailLogic) isSubordinate(parentId, targetId string) bool {
// 查询直接下级 // 查询直接下级
builder := l.svcCtx.AgentRelationModel.SelectBuilder(). builder := l.svcCtx.AgentRelationModel.SelectBuilder().
Where("parent_id = ? AND relation_type = ? AND del_state = ?", parentId, 1, globalkey.DelStateNo) 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 return 0
} }
orderIdSet := make(map[int64]bool) orderIdSet := make(map[string]bool)
for _, rebate := range rebates { for _, rebate := range rebates {
orderIdSet[rebate.OrderId] = true orderIdSet[rebate.OrderId] = true
} }
@@ -224,7 +224,7 @@ func (l *GetSubordinateContributionDetailLogic) countDistinctOrders(ctx context.
} }
// getOrderList 获取订单列表(仅显示有返佣的订单) // 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. 查询所有返佣记录 // 1. 查询所有返佣记录
rebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder(). rebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder().
Where("agent_id = ? AND source_agent_id = ? AND del_state = ?", agentId, subordinateId, globalkey.DelStateNo). 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并按创建时间排序 // 2. 在内存中去重订单ID并按创建时间排序
type OrderRebateInfo struct { type OrderRebateInfo struct {
OrderId int64 OrderId string
RebateId int64 RebateId string
ProductId int64 ProductId string
RebateAmount float64 RebateAmount float64
CreateTime time.Time CreateTime time.Time
} }
orderMap := make(map[int64]*OrderRebateInfo) // orderId -> 最新的返佣信息 orderMap := make(map[string]*OrderRebateInfo) // orderId -> 最新的返佣信息
for _, rebate := range allRebates { for _, rebate := range allRebates {
if existing, ok := orderMap[rebate.OrderId]; ok { if existing, ok := orderMap[rebate.OrderId]; ok {
// 如果已存在,保留创建时间最新的 // 如果已存在,保留创建时间最新的
@@ -303,7 +303,7 @@ func (l *GetSubordinateContributionDetailLogic) getOrderList(ctx context.Context
// 5. 组装订单列表 // 5. 组装订单列表
var resultList []types.OrderItem var resultList []types.OrderItem
productCache := make(map[int64]string) // 产品ID -> 产品名称缓存 productCache := make(map[string]string) // 产品ID -> 产品名称缓存
for _, orderInfo := range pagedOrderList { for _, orderInfo := range pagedOrderList {
// 查询订单信息 // 查询订单信息
@@ -344,7 +344,7 @@ func (l *GetSubordinateContributionDetailLogic) getOrderList(ctx context.Context
} }
// getInviteList 获取邀请列表 // 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(). builder := l.svcCtx.AgentRelationModel.SelectBuilder().
Where("parent_id = ? AND relation_type = ? AND del_state = ?", subordinateId, 1, globalkey.DelStateNo) 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. 递归查询所有下级(直接+间接) // 2. 递归查询所有下级(直接+间接)
allSubordinateIds := make(map[int64]bool) allSubordinateIds := make(map[string]bool)
directSubordinateIds := make(map[int64]bool) directSubordinateIds := make(map[string]bool)
// 递归函数收集所有下级ID // 递归函数收集所有下级ID
var collectSubordinates func(int64) error var collectSubordinates func(string) error
collectSubordinates = func(parentId int64) error { collectSubordinates = func(parentId string) error {
// 查询直接下级 // 查询直接下级
builder := l.svcCtx.AgentRelationModel.SelectBuilder(). builder := l.svcCtx.AgentRelationModel.SelectBuilder().
Where("parent_id = ? AND relation_type = ? AND del_state = ?", parentId, 1, globalkey.DelStateNo) 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转换为切片用于查询 // 4. 将下级ID转换为切片用于查询
subordinateIds := make([]int64, 0, len(allSubordinateIds)) subordinateIds := make([]string, 0, len(allSubordinateIds))
for id := range allSubordinateIds { for id := range allSubordinateIds {
subordinateIds = append(subordinateIds, id) subordinateIds = append(subordinateIds, id)
} }
@@ -183,7 +183,7 @@ func (l *GetTeamListLogic) GetTeamList(req *types.GetTeamListReq) (resp *types.G
// calculateTeamStatistics 计算团队统计数据 // calculateTeamStatistics 计算团队统计数据
// 注意:所有统计都基于 subordinateIds下级ID列表不包含自己的数据 // 注意:所有统计都基于 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{ stats := types.TeamStatistics{
TotalMembers: int64(len(subordinateIds)), 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("agent_id = ? AND del_state = ?", agentId, globalkey.DelStateNo).
Where("source_agent_id != ?", agentId). // 明确排除自己 Where("source_agent_id != ?", agentId). // 明确排除自己
Where(squirrel.Eq{"source_agent_id": subordinateIds}) Where(squirrel.Eq{"source_agent_id": subordinateIds})
// 统计去重的订单数量 // 统计去重的订单数量
totalQueries := l.countDistinctOrders(l.ctx, rebateBuilder) totalQueries := l.countDistinctOrders(l.ctx, rebateBuilder)
stats.TotalQueries = totalQueries stats.TotalQueries = totalQueries
@@ -259,7 +259,7 @@ func (l *GetTeamListLogic) countDistinctOrders(ctx context.Context, builder squi
return 0 return 0
} }
orderIdSet := make(map[int64]bool) orderIdSet := make(map[string]bool)
for _, rebate := range rebates { for _, rebate := range rebates {
orderIdSet[rebate.OrderId] = true orderIdSet[rebate.OrderId] = true
} }
@@ -275,7 +275,7 @@ func (l *GetTeamListLogic) countDistinctOrdersForMember(ctx context.Context, bui
return 0 return 0
} }
orderIdSet := make(map[int64]bool) orderIdSet := make(map[string]bool)
for _, rebate := range rebates { for _, rebate := range rebates {
orderIdSet[rebate.OrderId] = true orderIdSet[rebate.OrderId] = true
} }
@@ -284,7 +284,7 @@ func (l *GetTeamListLogic) countDistinctOrdersForMember(ctx context.Context, bui
} }
// buildTeamMemberItem 构建团队成员项 // 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 := "" levelName := ""
switch member.Level { switch member.Level {
case 1: case 1:

View File

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

View File

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

View File

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

View File

@@ -9,6 +9,7 @@ import (
"ycc-server/common/xerr" "ycc-server/common/xerr"
"ycc-server/pkg/lzkit/lzUtils" "ycc-server/pkg/lzkit/lzUtils"
"github.com/google/uuid"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/sqlx" "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 { err = l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
// 7.1 创建升级记录 // 7.1 创建升级记录
upgradeRecord := &model.AgentUpgrade{ upgradeRecord := &model.AgentUpgrade{
Id: uuid.New().String(),
AgentId: subordinateAgent.Id, AgentId: subordinateAgent.Id,
FromLevel: 1, // 普通 FromLevel: 1, // 普通
ToLevel: toLevel, ToLevel: toLevel,
UpgradeType: 2, // 钻石升级下级 UpgradeType: 2, // 钻石升级下级
UpgradeFee: 0, // 免费 UpgradeFee: 0, // 免费
RebateAmount: 0, // 无返佣 RebateAmount: 0, // 无返佣
OperatorAgentId: sql.NullInt64{Int64: operatorAgent.Id, Valid: true}, OperatorAgentId: sql.NullString{String: operatorAgent.Id, Valid: true},
Status: 1, // 待处理 Status: 1, // 待处理
} }
upgradeResult, err := l.svcCtx.AgentUpgradeModel.Insert(transCtx, session, upgradeRecord) _, err := l.svcCtx.AgentUpgradeModel.Insert(transCtx, session, upgradeRecord)
if err != nil { if err != nil {
return errors.Wrapf(err, "创建升级记录失败") return errors.Wrapf(err, "创建升级记录失败")
} }
upgradeId, _ := upgradeResult.LastInsertId()
// 7.2 执行升级操作 // 7.2 执行升级操作
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, subordinateAgent.Id, toLevel, 2, 0, 0, "", operatorAgent.Id); err != nil { 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 更新升级记录状态 // 7.3 更新升级记录状态
upgradeRecord.Id = upgradeId
upgradeRecord.Status = 2 // 已完成 upgradeRecord.Status = 2 // 已完成
upgradeRecord.Remark = lzUtils.StringToNullString("钻石代理升级下级成功") upgradeRecord.Remark = lzUtils.StringToNullString("钻石代理升级下级成功")
if err := l.svcCtx.AgentUpgradeModel.UpdateWithVersion(transCtx, session, upgradeRecord); err != nil { 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 的下级(直接或间接) // isSubordinate 递归检查 targetId 是否是 parentId 的下级(直接或间接)
func (l *UpgradeSubordinateLogic) isSubordinate(parentId, targetId int64) bool { func (l *UpgradeSubordinateLogic) isSubordinate(parentId, targetId string) bool {
// 查询直接下级 // 查询直接下级
builder := l.svcCtx.AgentRelationModel.SelectBuilder(). builder := l.svcCtx.AgentRelationModel.SelectBuilder().
Where("parent_id = ? AND relation_type = ? AND del_state = ?", parentId, 1, globalkey.DelStateNo) 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. 从数据库获取授权书信息 // 1. 从数据库获取授权书信息
authDoc, err := l.svcCtx.AuthorizationDocumentModel.FindOne(l.ctx, req.DocumentId) authDoc, err := l.svcCtx.AuthorizationDocumentModel.FindOne(l.ctx, req.DocumentId)
if err != nil { if err != nil {
logx.Errorf("获取授权书失败: documentId=%d, error=%v", req.DocumentId, err) logx.Errorf("获取授权书失败: documentId=%s, error=%v", req.DocumentId, err)
return nil, err return nil, err
} }
// 2. 检查授权书状态 // 2. 检查授权书状态
if authDoc.Status != "active" { 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("授权书不可用") return nil, errors.New("授权书不可用")
} }

View File

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

View File

@@ -182,7 +182,7 @@ func (l *AlipayCallbackLogic) handleAgentUpgradeOrderPayment(w http.ResponseWrit
if order.Status == "paid" { if order.Status == "paid" {
err := l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error { err := l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
// 8.1 执行升级操作 // 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, "执行升级操作失败") return errors.Wrapf(err, "执行升级操作失败")
} }

View File

@@ -2,11 +2,12 @@ package pay
import ( import (
"context" "context"
"fmt"
"time"
"ycc-server/app/main/api/internal/svc" "ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types" "ycc-server/app/main/api/internal/types"
"ycc-server/common/xerr" "ycc-server/common/xerr"
"ycc-server/pkg/lzkit/lzUtils" "ycc-server/pkg/lzkit/lzUtils"
"time"
"github.com/pkg/errors" "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 { func (l *IapCallbackLogic) IapCallback(req *types.IapCallbackReq) error {
// Step 1: 查找订单 // 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 { if findOrderErr != nil {
logx.Errorf("苹果内购支付回调,查找订单失败: %+v", findOrderErr) logx.Errorf("苹果内购支付回调,查找订单失败: %+v", findOrderErr)
return nil return nil

View File

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

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