banxiang/docs/技术方案-V1.1-扩展架构.md
2026-02-18 18:06:31 +00:00

409 lines
11 KiB
Markdown
Raw Permalink 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.

---
slug: tech-v1-1-extension
---
# 「伴享」技术方案 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
```sql
-- ===========================
-- 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 微信分享集成
```dart
// 使用 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. 队长等级自动计算
```javascript
// 定时任务:每日凌晨更新队长等级
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. 会员权限中间件
```javascript
// 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 + VantH5页面微信内置浏览器打开
流程:
1. 父母端生成代付链接 → 分享到微信
2. 子女点击链接 → 打开H5页面
3. H5页面展示父母信息 + 会员方案 + 价格
4. 子女点击支付 → 调起微信支付JSAPI
5. 支付成功 → 后端更新会员状态 → Push通知父母
```
---
**文档结束**