「伴享」技术方案 V1.1 — 扩展架构
版本: V1.1
对应PRD: PRD-V1.1-体验优化版
更新日期: 2026-02-16
1. 架构变更概述
V1.1在V1.0基础上新增:社区队长、会员订阅、家政服务、日常消费。无架构层面重大变更,主要是新增数据表和API端点。
1.1 变更影响矩阵
| 层级 |
变更 |
影响范围 |
| 数据库 |
新增6张表 |
队长/会员/服务商/服务人员/商品/购物车 |
| API |
新增4组端点 |
/captains, /membership, /services, /products |
| Flutter |
新增4个Feature模块 |
captain/, membership/, housekeeping/, shopping/ |
| 第三方 |
无新增 |
- |
| 部署 |
无变更 |
同V1.0 Docker Compose |
2. 新增数据库表
2.1 增量DDL
-- ===========================
-- V1.1 增量DDL
-- ===========================
-- 1. 队长相关
CREATE TABLE captain_applications (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT REFERENCES users(id),
bio TEXT,
specialties TEXT[],
serving_area VARCHAR(50),
contact_info JSONB,
status VARCHAR(20) DEFAULT 'pending'
CHECK (status IN ('pending', 'approved', 'rejected')),
reviewer_note TEXT,
reviewed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE captains (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT UNIQUE REFERENCES users(id),
level VARCHAR(20) DEFAULT 'trainee'
CHECK (level IN ('trainee', 'silver', 'gold', 'honor')),
bio TEXT,
specialties TEXT[],
serving_area VARCHAR(50),
total_activities INTEGER DEFAULT 0,
total_participants INTEGER DEFAULT 0,
total_new_users INTEGER DEFAULT 0,
avg_rating DECIMAL(2,1) DEFAULT 0,
monthly_subsidy DECIMAL(10,2) DEFAULT 0,
status VARCHAR(20) DEFAULT 'active',
approved_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- 2. 会员
CREATE TABLE memberships (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT REFERENCES users(id),
plan VARCHAR(20) NOT NULL CHECK (plan IN ('monthly', 'yearly')),
price DECIMAL(10,2) NOT NULL,
paid_by_user_id BIGINT REFERENCES users(id),
starts_at TIMESTAMP NOT NULL,
expires_at TIMESTAMP NOT NULL,
auto_renew BOOLEAN DEFAULT FALSE,
status VARCHAR(20) DEFAULT 'active'
CHECK (status IN ('active', 'expired', 'cancelled')),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_membership_user ON memberships(user_id, status);
-- 用户表新增字段
ALTER TABLE users ADD COLUMN is_member BOOLEAN DEFAULT FALSE;
ALTER TABLE users ADD COLUMN member_expires_at TIMESTAMP;
ALTER TABLE users ADD COLUMN is_captain BOOLEAN DEFAULT FALSE;
ALTER TABLE users ADD COLUMN captain_level VARCHAR(20);
-- 3. 服务商
CREATE TABLE service_providers (
id BIGSERIAL PRIMARY KEY,
company_name VARCHAR(100),
category VARCHAR(50),
contact_phone VARCHAR(20),
license_no VARCHAR(50),
address TEXT,
lat DECIMAL(10,7),
lng DECIMAL(10,7),
rating DECIMAL(2,1) DEFAULT 5.0,
status VARCHAR(20) DEFAULT 'active',
created_at TIMESTAMP DEFAULT NOW()
);
-- 4. 服务人员
CREATE TABLE service_workers (
id BIGSERIAL PRIMARY KEY,
provider_id BIGINT REFERENCES service_providers(id),
name VARCHAR(50),
avatar_url TEXT,
skills TEXT[],
rating DECIMAL(2,1) DEFAULT 5.0,
service_count INTEGER DEFAULT 0,
hourly_rate DECIMAL(10,2),
status VARCHAR(20) DEFAULT 'available',
created_at TIMESTAMP DEFAULT NOW()
);
-- 5. 服务订单
CREATE TABLE service_orders (
id BIGSERIAL PRIMARY KEY,
order_no VARCHAR(20) UNIQUE NOT NULL,
user_id BIGINT REFERENCES users(id),
worker_id BIGINT REFERENCES service_workers(id),
service_type VARCHAR(50),
scheduled_date DATE,
scheduled_time TIME,
duration_hours DECIMAL(3,1),
address TEXT,
requirements TEXT,
amount DECIMAL(10,2),
platform_fee DECIMAL(10,2),
status VARCHAR(20) DEFAULT 'pending',
rating INTEGER CHECK (rating BETWEEN 1 AND 5),
review TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
-- 6. 商品
CREATE TABLE products (
id BIGSERIAL PRIMARY KEY,
provider_id BIGINT REFERENCES service_providers(id),
name VARCHAR(100),
category VARCHAR(50),
description TEXT,
image_url TEXT,
price DECIMAL(10,2),
unit VARCHAR(20),
stock INTEGER DEFAULT 0,
status VARCHAR(20) DEFAULT 'available',
created_at TIMESTAMP DEFAULT NOW()
);
-- 7. 购物车
CREATE TABLE cart_items (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT REFERENCES users(id),
product_id BIGINT REFERENCES products(id),
quantity INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(user_id, product_id)
);
-- 8. 配送订单
CREATE TABLE delivery_orders (
id BIGSERIAL PRIMARY KEY,
order_no VARCHAR(20) UNIQUE NOT NULL,
user_id BIGINT REFERENCES users(id),
provider_id BIGINT REFERENCES service_providers(id),
items JSONB,
total_amount DECIMAL(10,2),
delivery_fee DECIMAL(10,2) DEFAULT 0,
delivery_address TEXT,
delivery_phone VARCHAR(11),
estimated_delivery TIMESTAMP,
status VARCHAR(20) DEFAULT 'pending',
created_at TIMESTAMP DEFAULT NOW()
);
-- 9. 队长排行榜物化视图
CREATE MATERIALIZED VIEW captain_monthly_ranking AS
SELECT
c.user_id,
u.nickname,
u.avatar_url,
c.level,
COUNT(a.id) AS monthly_activities,
c.avg_rating
FROM captains c
JOIN users u ON c.user_id = u.id
LEFT JOIN activities a ON a.creator_id = c.user_id
AND a.start_time >= date_trunc('month', CURRENT_DATE)
WHERE c.status = 'active'
GROUP BY c.user_id, u.nickname, u.avatar_url, c.level, c.avg_rating
ORDER BY monthly_activities DESC;
3. 新增API端点
3.1 队长模块 /captains
| 方法 |
路径 |
描述 |
| POST |
/captains/apply |
申请成为队长 |
| GET |
/captains/application-status |
查看申请状态 |
| GET |
/captains/me/dashboard |
队长数据面板 |
| GET |
/captains/ranking |
队长排行榜 |
| GET |
/captains/:userId |
查看队长主页 |
管理端(内部):
| 方法 |
路径 |
描述 |
| GET |
/admin/captains/applications |
待审核列表 |
| POST |
/admin/captains/applications/:id/approve |
审核通过 |
| POST |
/admin/captains/applications/:id/reject |
审核拒绝 |
3.2 会员模块 /membership
| 方法 |
路径 |
描述 |
| GET |
/membership/plans |
会员方案列表 |
| GET |
/membership/status |
当前会员状态 |
| POST |
/membership/subscribe |
开通会员 |
| POST |
/membership/generate-pay-link |
生成子女代付链接 |
| GET |
/membership/pay/:token |
子女代付页面数据 |
| POST |
/membership/pay/:token/confirm |
子女确认支付 |
3.3 家政服务 /services/housekeeping
| 方法 |
路径 |
描述 |
| GET |
/services/housekeeping/workers |
服务人员列表 |
| GET |
/services/housekeeping/workers/:id |
人员详情 |
| POST |
/services/housekeeping/orders |
预约下单 |
| GET |
/services/housekeeping/orders |
我的服务订单 |
| POST |
/services/housekeeping/orders/:id/cancel |
取消 |
| POST |
/services/housekeeping/orders/:id/review |
评价 |
3.4 日常消费 /shopping
| 方法 |
路径 |
描述 |
| GET |
/shopping/providers |
商家列表 |
| GET |
/shopping/products |
商品列表 |
| GET |
/shopping/cart |
购物车 |
| POST |
/shopping/cart/add |
加入购物车 |
| PUT |
/shopping/cart/:id |
修改数量 |
| DELETE |
/shopping/cart/:id |
删除 |
| POST |
/shopping/orders |
配送下单 |
| GET |
/shopping/orders |
配送订单列表 |
4. Flutter新增模块
4.1 新增Feature模块
features/
├── captain/ # 社区队长
│ ├── captain_apply_page.dart
│ ├── captain_dashboard_page.dart
│ ├── captain_ranking_page.dart
│ └── captain_profile_page.dart
├── membership/ # 会员中心
│ ├── membership_page.dart
│ ├── pay_link_page.dart
│ └── widgets/
├── housekeeping/ # 家政服务
│ ├── worker_list_page.dart
│ ├── worker_detail_page.dart
│ ├── booking_page.dart
│ └── widgets/
├── shopping/ # 日常消费
│ ├── provider_list_page.dart
│ ├── product_list_page.dart
│ ├── cart_page.dart
│ ├── checkout_page.dart
│ └── widgets/
└── onboarding/ # 新手引导
├── onboarding_page.dart
└── guide_overlay.dart
4.2 微信分享集成
// 使用 fluwx 插件
dependencies:
fluwx: ^4.x
// 活动分享
Future<void> shareActivity(Activity activity) async {
await fluwx.shareToWeChat(
WeChatShareWebPageModel(
webPage: 'https://h5.banxiang.com/activity/${activity.id}',
title: activity.title,
description: '来「伴享」一起参加吧!还剩${activity.remainingSlots}个名额',
thumbnail: WeChatImage.network(activity.coverImage),
scene: WeChatScene.session,
),
);
}
5. 队长等级自动计算
// 定时任务:每日凌晨更新队长等级
async function updateCaptainLevels() {
const captains = await db.query('SELECT * FROM captains WHERE status = $1', ['active']);
for (const captain of captains.rows) {
let newLevel = 'trainee';
if (captain.total_activities >= 50 && captain.avg_rating >= 4.75 && captain.total_new_users >= 100) {
newLevel = 'gold';
} else if (captain.total_activities >= 20 && captain.avg_rating >= 4.5 && captain.total_new_users >= 20) {
newLevel = 'silver';
}
if (newLevel !== captain.level) {
await db.query('UPDATE captains SET level = $1, updated_at = NOW() WHERE id = $2', [newLevel, captain.id]);
// 发送升级通知
await sendNotification(captain.user_id, 'CAPTAIN_LEVEL_UP', { newLevel });
}
}
// 刷新排行榜
await db.query('REFRESH MATERIALIZED VIEW captain_monthly_ranking');
}
6. 会员权限中间件
// middleware/membership.js
function requireMembership(req, res, next) {
if (!req.user.is_member || new Date(req.user.member_expires_at) < new Date()) {
return res.status(403).json({
success: false,
error: {
code: 'MEMBERSHIP_REQUIRED',
message: '此功能需要开通会员',
upgrade_url: '/membership/plans'
}
});
}
next();
}
// 免费用户限额检查
function checkFreeLimit(type) {
return async (req, res, next) => {
if (req.user.is_member) return next();
const limits = {
ai_chat: 20, // 每天20条
activity_join: 3, // 每月3次
};
const count = await getUsageCount(req.user.id, type);
if (count >= limits[type]) {
return res.status(403).json({
success: false,
error: {
code: 'FREE_LIMIT_EXCEEDED',
message: type === 'ai_chat'
? '今日AI对话次数已用完,开通会员享无限对话'
: '本月活动次数已用完,开通会员享无限参与',
upgrade_url: '/membership/plans'
}
});
}
next();
};
}
7. 子女代付H5页面
技术栈:Vue 3 + Vant(H5页面,微信内置浏览器打开)
流程:
1. 父母端生成代付链接 → 分享到微信
2. 子女点击链接 → 打开H5页面
3. H5页面展示:父母信息 + 会员方案 + 价格
4. 子女点击支付 → 调起微信支付JSAPI
5. 支付成功 → 后端更新会员状态 → Push通知父母
文档结束