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

11 KiB
Raw Permalink Blame History

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

-- ===========================
-- 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 + VantH5页面微信内置浏览器打开

流程:
1. 父母端生成代付链接 → 分享到微信
2. 子女点击链接 → 打开H5页面
3. H5页面展示父母信息 + 会员方案 + 价格
4. 子女点击支付 → 调起微信支付JSAPI
5. 支付成功 → 后端更新会员状态 → Push通知父母

文档结束