Files
ycc-proxy-server/邀请链接和二维码生成逻辑说明.md
2025-12-02 19:57:10 +08:00

212 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 邀请链接和二维码生成逻辑说明
## 一、邀请链接生成逻辑
### 1. API 端点
- **路径**: `GET /agent/invite_link`
- **处理器**: `GetInviteLinkHandler`
- **逻辑**: `GetInviteLinkLogic`
### 2. 生成流程
#### 步骤 1: 验证代理身份
```go
// 获取当前用户ID
userID := ctxdata.GetUidFromCtx(ctx)
// 查询代理信息
agent := AgentModel.FindOneByUserId(userID)
```
#### 步骤 2: 生成邀请码
- 生成一个8位随机邀请码使用 `tool.Krand(8, tool.KC_RAND_KIND_ALL)`
- 检查邀请码是否已存在最多重试10次
- 创建邀请码记录:
- `agent_id`: 当前代理ID
- `target_level`: 1普通代理
- `status`: 0未使用
- `expire_time`: NULL不过期
- `remark`: "邀请链接生成"
#### 步骤 3: 构建邀请链接
```go
frontendDomain := "https://example.com" // TODO: 需要配置
inviteLink := fmt.Sprintf("%s/register?invite_code=%s", frontendDomain, inviteCode)
```
#### 步骤 4: 生成二维码URL
```go
qrCodeUrl := fmt.Sprintf("%s/api/v1/image/qrcode?type=invitation&content=%s", frontendDomain, inviteLink)
```
### 3. 当前问题
-`frontendDomain` 硬编码为 `"https://example.com"`,需要配置化
- ❌ 二维码API (`/api/v1/image/qrcode`) 可能还未实现
## 二、二维码生成逻辑
### 1. 两种生成方式
#### 方式 A: 前端生成(当前使用)
- **位置**: `ycc-proxy-webview/src/components/QRcode.vue`
- **库**: `qrcode` (npm)
- **逻辑**:
```javascript
// 如果提供了后端返回的 qrCodeUrl优先使用
if (mode === "invitation" && qrCodeUrl) {
// 加载后端生成的二维码图片
qrImg.src = qrCodeUrl;
} else {
// 前端生成二维码
QRCode.toDataURL(url, { width: 150, margin: 0 });
}
```
#### 方式 B: 后端生成已实现服务但可能缺少API端点
- **服务**: `ImageService.ProcessImageWithQRCode()`
- **功能**:
- 支持两种类型:`promote`(推广)和 `invitation`(邀请)
- 加载背景图片(`static/images/yq_qrcode_1.png` 或 `tg_qrcode_1.png`
- 生成二维码并合成到背景图上
- 返回 PNG 格式图片
### 2. 二维码海报生成流程
#### 推广海报promote模式
- **背景图**: `static/images/tg_qrcode_1.png` - `tg_qrcode_8.jpg`8张轮播图
- **二维码位置**: 左下角
- 尺寸: 280px
- 位置: X=192px, Y=距离底部190px
- **用途**: 推广产品查询服务
#### 邀请海报invitation模式
- **背景图**: `static/images/yq_qrcode_1.png`
- **二维码位置**: 中间偏上
- 尺寸: 360px
- 位置: 水平居中垂直位置Y=555px
- **用途**: 邀请好友成为下级代理
### 3. 前端海报合成逻辑
```javascript
// 1. 加载海报背景图
posterImg.src = posterImages[index];
// 2. 生成或加载二维码
if (mode === "invitation" && qrCodeUrl) {
// 使用后端返回的二维码
qrImg.src = qrCodeUrl;
} else {
// 前端生成二维码
QRCode.toDataURL(url);
}
// 3. 在Canvas上绘制
ctx.drawImage(posterImg, 0, 0); // 背景
ctx.drawImage(qrCodeImg, x, y, size, size); // 二维码
```
## 三、数据流程
### 邀请链接流程
```
用户点击"生成邀请链接"
前端调用 GET /agent/invite_link
后端逻辑 (GetInviteLinkLogic):
1. 验证代理身份
2. 生成新的邀请码8位随机不过期
3. 保存到 agent_invite_code 表
4. 构建邀请链接: https://domain/register?invite_code=XXXXX
5. 构建二维码URL: https://domain/api/v1/image/qrcode?type=invitation&content=...
返回 { invite_link, qr_code_url }
前端显示链接和二维码
```
### 二维码使用流程
#### 邀请模式 (invitation)
```
后端返回 qrCodeUrl
前端 QRcode 组件加载二维码图片
如果加载成功: 直接使用后端生成的二维码海报
如果加载失败: 降级到前端生成二维码
合成到邀请海报背景图 (yq_qrcode_1.png)
用户可以保存或分享海报
```
#### 推广模式 (promote)
```
前端生成二维码 (使用 qrcode 库)
合成到推广海报背景图 (tg_qrcode_1.png - 8.png)
用户可以在多张海报中切换
用户可以保存或分享海报
```
## 四、相关数据库表
### agent_invite_code
- 存储邀请码信息
- 每个邀请链接对应一个邀请码记录
- 备注:`"邀请链接生成"` 表示这是通过链接生成的
### agent_invite_code_usage
- 存储邀请码使用历史
- 记录每个代理是通过哪个邀请码成为的
- 支持统计和查询
## 五、待完善的问题
### 1. 前端域名配置
- ❌ 当前硬编码为 `"https://example.com"`
- ✅ 应该从配置文件读取
### 2. 二维码API实现
- ❓ `/api/v1/image/qrcode` 端点是否存在?
- ✅ `ImageService.ProcessImageWithQRCode()` 已实现
- ❓ 是否需要创建对应的 Handler 和路由?
### 3. 邀请码复用
- 当前每次调用都生成新的邀请码
- 是否应该复用已有的邀请码?
## 六、链接格式对比
### 邀请链接(成为代理)
```
格式: https://domain/register?invite_code=XXXXX
参数: invite_code (8位邀请码)
用途: 用户通过此链接注册成为代理
```
### 推广链接(推广产品)
```
格式: https://domain/agent/promotionInquire/{linkIdentifier}
参数: linkIdentifier (加密的JSON字符串包含agent_id, product_id, set_price)
用途: 用户通过此链接查询产品
```
## 七、文件位置
### 后端
- **邀请链接逻辑**: `app/main/api/internal/logic/agent/getinvitelinklogic.go`
- **二维码服务**: `app/main/api/internal/service/imageService.go`
- **推广链接逻辑**: `app/main/api/internal/logic/agent/generatinglinklogic.go`
### 前端
- **二维码组件**: `ycc-proxy-webview/src/components/QRcode.vue`
- **邀请页面**: `ycc-proxy-webview/src/views/Invitation.vue`
- **推广查询页**: `ycc-proxy-webview/src/views/PromotionInquire.vue`