06488f0237
功能: - Go后端 (Gin + GORM + PostgreSQL) - UniApp用户端 (iOS/Android/小程序) - DaisyUI5后台管理 - JWT认证 + 微信登录 - 盲选加权算法 - 会员系统 + 优惠券 - 打分评价 + 偏好学习
27 KiB
27 KiB
"帮我选"盲选应用 - 开发大纲 v3
一、项目概述
AI驱动开发的盲选应用,用户盲选吃喝玩乐套餐,支持会员盈利, 通过用户历史行为智能更新偏好权重,去了打分驱动推荐质量。
二、技术栈
AI 开发配置
api:
key: "sk-26391ddf421f3d09546969d968e73295a3ec493ae327a6792a840c6f5fcdd517"
endpoint: "https://qs.szscp.com"
# 用途:AI推荐、智能分类、用户偏好分析、月度报告
后端:Go + Gin + GORM + PostgreSQL + Redis
App前端:UniApp + Vue3(一套代码→iOS/Android/小程序)
后台管理:DaisyUI5 + Tailwind + Alpine.js
三、会员盈利体系(简化:仅VIP)
会员方案
免费用户:
├── 每天3次盲选机会
├── 基础分类可用
└── 普通优先级
VIP会员(¥29/月 或 ¥199/年):
├── 每天10次盲选
├── 全部分类解锁
├── 优先匹配优质套餐
├── 专属盲选风格
├── 去重天数更长(3天→1天)
└── 月度盲选报告
盈利模型
1. 会员订阅(主要收入)
2. 商家佣金(5-15%)
3. 优惠券佣金(联动商家优惠券,每次核销商家付佣金)
4. 品牌盲盒溢价
商家优惠券联动
商家在后台创建优惠券:
├── 券类型:满减券 / 折扣券 / 免费兑换券 / 赠品券
├── 面额:后台设置(如满100减20)
├── 数量:发放总量 + 剩余量
├── 有效期:起止时间
├── 适用套餐:指定某些套餐可用
└── 佣金比例:用户通过盲选核销该券,平台抽佣 10-20%
用户侧表现:
├── 盲选结果卡上显示"附带优惠券"
├── 优惠券卡片样式(像微信卡包)
├── 核销后记录,商家确认使用
└── 优惠券是商家的"引流工具",平台收佣金
优惠券联动逻辑:
商家A想引流 → 后台创建100张"满80减15"券 → 设核销后佣金8元
→ 用户盲选抽到商家A的套餐 → 自动获得该券
→ 用户到店出示核销 → 商家确认 → 平台收8元佣金
→ 用户得到优惠,商家获得客流,平台赚佣金 → 三方共赢
四、用户偏好学习系统(含打分机制)
4.1 打分机制(核心)
用户每次盲选揭晓后,可选"去了"或"跳过了":
用户选择"去了"后 → 进入打分页:
┌─────────────────────────────┐
│ 你对这次盲选体验打几分? │
│ │
│ ⭐⭐⭐⭐⭐ (1-5星) │
│ │
│ 评分维度(可选填): │
│ 🍽️ 口味: ████░ (1-5) │
│ 💰 性价比: ███░░ (1-5) │
│ 📍 距离: ████░ (1-5) │
│ 🎯 符合预期: ████░ (1-5) │
│ │
│ 备注(可选): │
│ ┌─────────────────────────┐ │
│ │ 写点什么... │ │
│ └─────────────────────────┘ │
│ │
│ [提交] │
└─────────────────────────────┘
打分影响权重:
五星好评(5分):
→ 该分类偏好 +2.0 ★★
→ 该商家偏好 +3.0 ★★★
→ 该标签(如"日料")偏好 +1.5
四星好评(4分):
→ 该分类偏好 +1.0
→ 该商家偏好 +1.5
→ 该标签偏好 +0.8
三星中立(3分):
→ 该分类偏好 +0.3(轻微正向)
→ 无商家偏好加成
二星(2分):
→ 该分类偏好 -0.3
→ 该商家偏好 -0.5
一星差评(1分):
→ 该分类偏好 -1.0
→ 该商家偏好 -2.0 ★★
→ 该商家加入"黑名单"候选(需用户确认)
4.2 行为追踪
type UserBehavior struct {
ID uint
UserID uint
PackageID uint
BehaviorType string // "viewed" "selected" "attended" "reviewed" "skipped"
Score float64 // 行为权重(非打分,是系统权重)
ReviewRating int8 // 用户打分 1-5
ReviewTags string // "口味好""太贵""环境差"等标签
ReviewText string // 用户文字评价
DistanceScore int8 // 距离评分
ValueScore int8 // 性价比评分
ExpectMatch int8 // 符合预期评分
IsRepeat bool // 是否再次前往
CreatedAt time.Time
}
4.3 权重算法
用户偏好分数 = Σ(行为得分 × 时间衰减系数 × 打分系数)
打分系数:
5星 → ×1.5(放大正向影响)
4星 → ×1.0(标准正向影响)
3星 → ×0.5(轻微影响)
2星 → ×-0.5(轻微负向)
1星 → ×-1.5(放大负向影响)
时间衰减:
最近30天 × 1.0
30-90天 × 0.7
90-180天 × 0.4
180天+ × 0.2
示例计算:
用户A在45天前去了日料店,打了5星 → 权重 = +2.0 × 0.7 × 1.5 = +2.1
用户A在200天前去了日料店,打了2星 → 权重 = -0.5 × 0.2 × -0.5 = +0.05(几乎忽略)
4.4 偏好标签自动打标
基于用户打分数据自动打标:
用户A(日料5星×5次,西餐3星×3次,火锅5星×2次)
→ 标签: ["日料狂魔", "火锅爱好者", "中餐不挑"]
→ 盲选策略: 80%日料/火锅,20%其他探索
用户B(所有都3-4星,没有明显偏好)
→ 标签: ["探索型", "随机接受度高"]
→ 盲选策略: 增加品类多样性,避免重复
用户C(多次1-2星差评)
→ 标签: ["易踩雷", "高要求", "需要精准匹配"]
→ 盲选策略: 提高推荐门槛,降低盲选随机性,接近定向选择
4.5 商家维度打分积累
每个套餐也积累评分:
套餐评分 = Σ(所有用户打分) / 打分人数
影响:
- 套餐评分低的 → 降低盲选权重(少抽到)
- 套餐评分高的 → 提高盲选权重(多抽到)
- 但保留一定随机性(给用户探索惊喜)
五、功能模块
5.1 用户端(UniApp)
首页
├── 顶部:欢迎语(AI生成,基于今日偏好)
│ 例:"今天想带你吃点治愈系的~"
│ 例:"好久没吃辣了,来场火锅盲选?"
│ 例:"根据你的口味,今天推荐隐藏日料店!"
├── 盲选卡片池(可滑动切换类别)
│ ├── 🍜 餐饮盲选
│ ├── 🎮 娱乐盲选
│ ├── 🛍️ 购物盲选
│ └── 🎭 活动盲选
├── 今日推荐(AI分析后推荐类别,VIP专享)
└── 盲选按钮(大,带动画)→ 抽!
盲选揭晓页
├── 动画效果(翻牌/转盘)
├── 揭晓内容:
│ ├── 商家名称 + 评分 + 距离
│ ├── 套餐描述(模糊描述,价格区间可见)
│ ├── 推荐理由(AI生成,基于匹配度)
│ │ 例:"你的日料偏好度85%,这家匹配度很高!"
│ ├── 优惠券 🎁(如有)
│ │ 例:"满80减15 · 限时3天"
│ └── 匹配度进度条
├── 操作:
│ ├── ✅ 接受/前往(记录行为 +0.5)
│ ├── 🔄 换一个(-0.2分,不消耗机会)
│ ├── ⭐ 标记"已去过"(进入打分流程)
│ ├── 🔖 收藏
│ └── 📍 导航
└── 已去过?→ 跳转打分页
打分页
┌─────────────────────────┐
│ 🎉 感谢你的盲选体验! │
│ │
│ 你对这次体验打几分? │
│ ⭐⭐⭐⭐⭐ (当前: 4) │
│ │
│ 评分维度: │
│ 🍽️ 口味: ⭐⭐⭐⭐⭐ │
│ 💰 性价比: ⭐⭐⭐⭐░ │
│ 📍 距离: ⭐⭐⭐░░ │
│ 🎯 符合预期:⭐⭐⭐⭐⭐ │
│ │
│ 你想怎么形容这次体验? │
│ [口味赞] [环境好] [性价比] [值得再来] [服务棒] [踩雷] [太贵] [难吃] [远]
│ │
│ 备注(可选): │
│ ┌─────────────────────┐ │
│ │ 写点什么... │ │
│ └─────────────────────┘ │
│ │
│ [提交] │
└─────────────────────────┘
提交后:
├── 更新用户偏好权重
├── 更新商家/套餐评分
├── 更新用户标签
└── 显示:"已记录!这会影响下次推荐哦~"
我的偏好
├── 偏好雷达图(口味/价格/距离/品质/探索度)
├── 品类偏好排名(柱状图)
│ 日料 ████████░░ 80%
│ 火锅 ██████░░░░ 60%
│ 西餐 ████░░░░░░ 40%
│ 甜品 ███░░░░░░░ 30%
├── AI标签列表
├── 去重设置
├── 黑名单商家
└── 偏好调整滑块
优惠券中心
├── 我的优惠券
│ ├── 未使用(到期倒计时)
│ ├── 已使用
│ └── 已过期
├── 卡包样式(像微信卡包)
└── 使用说明
会员中心
├── 当前状态
├── 会员权益对比表
├── 开通/续费按钮
├── 购买记录
└── 邀请好友(双方各得7天VIP)
个人
├── 个人信息
├── 盲选记录(按时间线)
├── 收藏
├── 评价历史
├── 地址管理
└── 设置
5.2 后台管理(DaisyUI5)
仪表盘
├── 今日:新增用户 / 活跃 / 盲选次数 / 订单数
├── 会员:总数 / 转化率 / 月收入 / 续费率
├── 热门:分类TOP / 套餐TOP / 商家TOP
├── 评分:平均打分 / 差评预警
├── 优惠券:发放量 / 核销率 / 佣金收入
└── 趋势图(近30天)
商家管理
├── 商家列表 + 搜索
├── 入驻审核
├── 编辑/上下架
├── 佣金设置
└── 商家数据(被选次数 / 平均评分 / 优惠券核销)
套餐管理
├── 套餐CRUD
├── 价格区间设置
├── 标签管理
├── 库存管理
├── 评分查看
└── 权重调整
优惠券管理
├── 创建优惠券
│ ├── 选择商家
│ ├── 券类型(满减/折扣/兑换/赠品)
│ ├── 面额设置
│ ├── 数量
│ ├── 有效期
│ ├── 适用套餐
│ └── 佣金比例(平台抽佣)
├── 优惠券列表(使用状态/核销情况)
├── 佣金收入统计
└── 核销审核(防作弊)
用户管理
├── 用户列表 + 搜索
├── 用户详情(行为 + 偏好 + 打分 + 会员)
├── 会员管理
├── 黑名单管理
└── 行为分析
打分分析
├── 平均打分趋势
├── 各分类平均评分
├── 差评预警(连续低分套餐)
├── 商家质量排名
└── 用户反馈词云
算法配置
├── 行为权重调整
├── 时间衰减曲线
├── 打分系数
├── 去重天数默认值
├── 会员加成比例
├── 热门权重
└── A/B测试
内容管理
├── Banner
├── 公告
├── 欢迎语模板
├── 推荐语模板
└── 标签管理
数据报表
├── 用户增长曲线
├── 收入报表(会员+佣金+优惠券)
├── 转化率漏斗(注册→首盲选→付费会员)
├── 留存分析(7日/30日)
├── 商家质量报告
└── 导出CSV/Excel
六、数据库设计
-- 用户表
users (
id, nickname, avatar, phone, wechat_openid,
preference JSONB, -- {"日料": 0.85, "火锅": 0.6, ...}
tags TEXT[], -- ["日料狂魔", "品质型"]
member_level INT DEFAULT 0, -- 0免费 1VIP
member_expires_at,
created_at, updated_at
)
-- 商家表
merchants (
id, name, avatar, category_id,
rating, -- 平均评分
price_range, -- "50-100"
location GEOGRAPHY(Point), -- 经纬度
tags TEXT[],
total_reviews INT DEFAULT 0,
total_score NUMERIC DEFAULT 0,
quality_score NUMERIC, -- 综合质量分(用于盲选权重)
status,
created_at, updated_at
)
-- 分类表
categories (
id, name, icon, type, -- food/entertainment/shopping/activity
sort_order,
status,
created_at
)
-- 套餐表
packages (
id, merchant_id, category_id,
name, -- 套餐名
description, -- 模糊描述(盲选可见)
price_min, price_max, -- 价格区间
actual_price, -- 实际价格(盲选揭晓后显示)
tags TEXT[], -- "适合约会""亲子"
stock,
weight, -- 推荐权重
rating, -- 平均评分
review_count, -- 评分人数
status,
created_at, updated_at
)
-- 用户行为表(含打分)
user_behaviors (
id, user_id, package_id,
behavior_type, -- viewed/selected/attended/reviewed/skipped
system_score, -- 系统行为权重
review_rating, -- 用户打分 1-5
taste_score, -- 口味评分 1-5
value_score, -- 性价比评分 1-5
distance_score, -- 距离评分 1-5
match_score, -- 符合预期 1-5
tags TEXT[], -- 反馈标签 ["口味赞","太贵"]
text TEXT, -- 文字评价
is_repeat, -- 是否再次前往
created_at
)
-- 优惠券表
coupons (
id, merchant_id, package_id,
type, -- discount/coupon/free/gift
value, -- 面额或折扣
min_amount, -- 满减门槛
total_count, -- 总量
remain_count, -- 剩余
user_id, -- 领取用户(NULL=池发)
user_code, -- 用户专属码
pool_code, -- 池码(用户领取时复制)
status, -- available/claimed/used/expired
used_at,
valid_start, valid_end,
commission, -- 平台佣金
created_at, updated_at
)
-- 盲选会话表
blind_sessions (
id, user_id, category_id,
price_range, distance_range,
result_package_id,
result_revealed_at,
user_accepted,
created_at
)
-- 订单表
orders (
id, user_id, package_id, blind_session_id,
actual_price,
coupon_id, -- 使用的优惠券
status, -- pending/paid/completed/cancelled
created_at, updated_at
)
-- 会员表
members (
id, user_id, level,
start_date, end_date,
payment_method,
amount,
status,
created_at
)
-- 活动表
activities (
id, name, type, start_date, end_date,
config JSONB,
status
)
-- 管理员表
admins (
id, username, password_hash,
role, permissions,
created_at
)
七、API设计
7.1 认证
POST /api/v1/auth/register # 注册
POST /api/v1/auth/login # 手机登录
POST /api/v1/auth/wechat/login # 微信登录
POST /api/v1/auth/refresh # 刷新token
POST /api/v1/admin/login # 后台登录
7.2 用户
GET /api/v1/user/profile # 个人信息
PUT /api/v1/user/profile # 更新信息
GET /api/v1/user/preferences # 偏好数据
PUT /api/v1/user/preferences # 调整偏好
GET /api/v1/user/tags # AI标签
GET /api/v1/user/behaviors # 行为记录
7.3 盲选(核心)
GET /api/v1/blind/categories # 分类列表
GET /api/v1/blind/pool # 可选池(模糊信息)
POST /api/v1/blind/choose # 盲选
GET /api/v1/blind/result/:id # 揭晓结果
GET /api/v1/blind/recommend # AI推荐
POST /api/v1/blind/accept # 接受
POST /api/v1/blind/decline # 换一个
GET /api/v1/blind/history # 历史记录
7.4 打分(核心)
POST /api/v1/review/submit # 提交打分评价
GET /api/v1/review/stats # 打分统计
GET /api/v1/review/summary # 商家/套餐评分汇总
7.5 优惠券
GET /api/v1/coupon/list # 我的优惠券
GET /api/v1/coupon/available # 可领取优惠券
POST /api/v1/coupon/claim # 领取优惠券
POST /api/v1/coupon/verify # 核销优惠券
GET /api/v1/coupon/commission # 佣金记录
7.6 会员
GET /api/v1/member/status # 会员状态
GET /api/v1/member/plans # 会员套餐
POST /api/v1/member/subscribe # 开通
POST /api/v1/member/cancel # 取消
GET /api/v1/member/report # 月度报告(VIP)
7.7 后台管理
POST /api/v1/admin/dashboard # 仪表盘
CRUD /api/v1/admin/merchants # 商家管理
CRUD /api/v1/admin/packages # 套餐管理
GET /api/v1/admin/coupons # 优惠券管理
POST /api/v1/admin/coupons/create # 创建优惠券
GET /api/v1/admin/users # 用户列表
GET /api/v1/admin/users/:id # 用户详情
GET /api/v1/admin/reviews # 打分管理
GET /api/v1/admin/statistics # 数据报表
PUT /api/v1/admin/algorithm/config # 算法配置
GET /api/v1/admin/export # 数据导出
7.8 AI
POST /api/v1/ai/recommend # AI推荐
POST /api/v1/ai/analyze-preference # 分析偏好
POST /api/v1/ai/generate-tag # 生成标签
POST /api/v1/ai/generate-report # 生成月报
POST /api/v1/ai/generate-welcome # 生成欢迎语
八、项目结构
blind-select/
├── backend/ # Go后端
│ ├── cmd/server/main.go
│ ├── internal/
│ │ ├── config/
│ │ ├── middleware/ # JWT/日志/限流/会员校验
│ │ ├── handler/
│ │ │ ├── v1/
│ │ │ │ ├── auth.go
│ │ │ │ ├── blind.go
│ │ │ │ ├── user.go
│ │ │ │ ├── review.go # 打分
│ │ │ │ ├── coupon.go
│ │ │ │ ├── member.go
│ │ │ │ ├── ai.go
│ │ │ │ └── admin/
│ │ │ │ ├── dashboard.go
│ │ │ │ ├── merchant.go
│ │ │ │ ├── package.go
│ │ │ │ ├── coupon.go
│ │ │ │ ├── user.go
│ │ │ │ ├── review.go
│ │ │ │ ├── stats.go
│ │ │ │ ├── export.go
│ │ │ │ └── config.go
│ │ ├── service/
│ │ │ ├── blind_service.go # 盲选逻辑
│ │ │ ├── preference_service.go # 偏好学习
│ │ │ ├── review_service.go # 打分服务
│ │ │ ├── coupon_service.go # 优惠券
│ │ │ ├── member_service.go # 会员
│ │ │ ├── ai_service.go # AI调用
│ │ │ └── report_service.go # 报表
│ │ ├── model/ # GORM模型
│ │ ├── repository/ # 数据访问
│ │ └── utils/
│ ├── migrations/
│ ├── config.yaml
│ ├── go.mod
│ └── Makefile
│
├── frontend-admin/ # 后台 (DaisyUI5)
│ ├── index.html
│ ├── src/
│ │ ├── main.js
│ │ ├── App.vue
│ │ ├── views/
│ │ ├── components/
│ │ ├── api/
│ │ └── router/
│ ├── vite.config.js
│ └── package.json
│
├── frontend-app/ # UniApp多端
│ ├── pages/
│ │ ├── index/index.vue # 首页
│ │ ├── blind/blind.vue # 盲选页
│ │ ├── blind/result.vue # 揭晓
│ │ ├── blind/review.vue # 打分页
│ │ ├── coupon/list.vue # 优惠券
│ │ ├── member/member.vue # 会员中心
│ │ ├── user/profile.vue
│ │ ├── user/preferences.vue
│ │ └── user/history.vue
│ ├── components/
│ ├── api/
│ ├── store/
│ ├── pages.json
│ └── manifest.json
│
└── docs/
└── API文档.md
九、开发阶段
Phase 1: 后端基础(Week 1)
- 项目初始化
- Go项目骨架 + 配置
- 数据库初始化 + 模型
- JWT认证 + 用户登录
- 后台管理员登录
Phase 2: 核心业务(Week 2-3)
- 商家CRUD + 套餐管理
- 盲选加权随机算法
- 用户行为追踪
- 打分系统 + 偏好学习算法
- AI集成(推荐/标签/报告)
Phase 3: 会员+优惠券(Week 4)
- VIP会员系统
- 优惠券创建+领取+核销
- 佣金计算
- 中间件:会员校验
Phase 4: UniApp前端(Week 5-6)
- 项目初始化 + 页面框架
- 首页 + 盲选入口
- 揭晓动画 + 打分页
- 个人中心 + 偏好展示
- 优惠券中心
- 会员中心
- 微信小程序适配
Phase 5: 后台管理(Week 7)
- DaisyUI5 + Tailwind 搭建
- 仪表盘 + 数据可视化
- 商家/套餐管理
- 优惠券管理
- 打分分析
- 数据报表 + 导出
Phase 6: 测试上线(Week 8-9)
- 端到端测试
- 性能优化(Redis缓存)
- App打包
- 部署上线
十、关键算法详解
10.1 盲选加权随机
func (s *BlindService) Select(user *User, category string, priceRange PriceRange) (*Package, error) {
candidates := s.getCandidates(category, priceRange)
for i := range candidates {
w := 1.0 // 基础权重
// 用户偏好加成
pref := s.getPreferenceScore(user.ID, candidates[i].Category)
w *= (1 + pref)
// 套餐质量分(基于打分积累)
quality := candidates[i].Rating / 5.0
w *= (0.5 + quality * 0.5) // 0.5-1.0范围
// 去重惩罚
if s.isRepeated(user.ID, candidates[i].ID, user.RepeatDays) {
w *= 0.1
}
// 会员加成
if user.MemberLevel == 1 {
w *= 1.2
}
candidates[i].Weight = w
}
return s.weightedRandom(candidates)
}
10.2 偏好学习 + 打分影响
func (s *PrefService) SubmitReview(userID, packageID uint, review Review) {
// 1. 保存打分
behavior := Behavior{
UserID: userID,
PackageID: packageID,
Type: "reviewed",
ReviewRating: review.Rating,
TasteScore: review.Taste,
ValueScore: review.Value,
DistanceScore: review.Distance,
MatchScore: review.Match,
Tags: review.Tags,
Text: review.Text,
IsRepeat: review.IsRepeat,
CreatedAt: time.Now(),
}
db.Create(&behavior)
// 2. 计算打分系数
scoreMultiplier := reviewScoreMultiplier(review.Rating)
// 5星→1.5, 4星→1.0, 3星→0.5, 2星→-0.5, 1星→-1.5
// 3. 更新用户偏好
pkg := getPackage(packageID)
category := pkg.Category
// 基础行为权重
baseScore := 0.0
switch {
case review.Rating >= 4:
baseScore = 1.0 // 好评,正向影响
case review.Rating == 3:
baseScore = 0.3 // 中立
case review.Rating == 2:
baseScore = -0.3 // 差评
default:
baseScore = -1.0 // 严重差评
}
// 加入商家ID的特殊影响
if review.IsRepeat {
baseScore += 1.0 // 再次前往,大幅正向
}
// 应用打分系数和时间衰减
finalScore := baseScore * scoreMultiplier * getTimeDecay(behavior.CreatedAt)
// 更新偏好
updateCategoryPreference(userID, category, finalScore)
// 4. 更新商家评分
updateMerchantRating(pkg.MerchantID, review.Rating)
// 5. 更新套餐评分
updatePackageRating(packageID, review.Rating)
// 6. 重新生成标签
tags := generateTags(userID)
updateTags(userID, tags)
}
func reviewScoreMultiplier(rating int8) float64 {
switch rating {
case 5: return 1.5
case 4: return 1.0
case 3: return 0.5
case 2: return -0.5
case 1: return -1.5
default: return 0.0
}
}
10.3 优惠券联动
func (s *CouponService) OnBlindSelectComplete(session *BlindSession) {
pkg := session.Package
// 1. 查找该套餐可用的优惠券
coupons := getCouponsForPackage(pkg.ID)
// 2. 随机发放一张(如果有)
if len(coupons) > 0 {
coupon := coupons[rand.Intn(len(coupons))]
if coupon.RemainCount > 0 {
// 为用户领取
userCoupon := Coupon{
MerchantID: coupon.MerchantID,
PackageID: pkg.ID,
Type: coupon.Type,
Value: coupon.Value,
UserID: session.UserID,
Status: "available",
ValidStart: coupon.ValidStart,
ValidEnd: coupon.ValidEnd,
Commission: coupon.Commission,
CreatedAt: time.Now(),
}
db.Create(&userCoupon)
coupon.RemainCount--
coupon.Save()
}
}
}
func (s *CouponService) OnCouponVerified(couponID uint) {
coupon := getCoupon(couponID)
// 1. 标记已使用
coupon.Status = "used"
coupon.UsedAt = time.Now()
coupon.Save()
// 2. 记录平台佣金
commission := Commission{
CouponID: coupon.ID,
MerchantID: coupon.MerchantID,
Amount: coupon.Commission,
Status: "pending",
CreatedAt: time.Now(),
}
db.Create(&commission)
// 3. 通知商家
notifyMerchant(coupon.MerchantID, "用户核销了优惠券,佣金已记录")
}