banxiang/docs/技术方案-V2.0-完整架构.md
2026-02-18 18:06:31 +00:00

16 KiB
Raw Blame History

slug
tech-v2-0-full-architecture

「伴享」技术方案 V2.0 — 完整架构

版本: V2.0
对应PRD: PRD-V2.0-完整产品
更新日期: 2026-02-16


1. 架构演进

V2.0标志着产品从MVP走向完整商业化。核心变更商家后台Web端完整9大服务板块积分/优惠券/拼团Elasticsearch搜索

1.1 完整架构图

┌───────────────────────────────────────────────────────────┐
│                        客户端层                             │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────────┐ │
│  │Flutter  │  │子女端   │  │商家后台 │  │管理后台     │ │
│  │APP      │  │小程序   │  │Web     │  │Web内部  │ │
│  └────┬────┘  └────┬────┘  └────┬────┘  └──────┬──────┘ │
└───────┼────────────┼────────────┼───────────────┼─────────┘
        │            │            │               │
┌───────▼────────────▼────────────▼───────────────▼─────────┐
│                    Nginx API网关                            │
│  /api/v1/* → APP    /api/merchant/* → 商家                 │
│  /api/child/* → 子女  /api/admin/* → 管理                  │
└────────────────────────┬──────────────────────────────────┘
                         │
┌────────────────────────▼──────────────────────────────────┐
│                   业务服务层 (Node.js)                      │
│  用户│活动│AI管家│医疗│支付│通知│队长│会员│健康│子女│社区  │
│  商家│积分│优惠券│拼团│家政│配送│候鸟│文教│法律│设备│课程  │
└────────────────────────┬──────────────────────────────────┘
                         │
┌────────────────────────▼──────────────────────────────────┐
│                    Worker层                                 │
│  健康同步│预警检测│队长等级│结算│积分过期│排行榜│会员到期  │
└────────────────────────┬──────────────────────────────────┘
                         │
┌────────────────────────▼──────────────────────────────────┐
│                     数据层                                  │
│  PostgreSQL │ Redis │ OSS │ Elasticsearch                  │
└───────────────────────────────────────────────────────────┘

1.2 新增技术组件

组件 用途 版本
Elasticsearch 全文搜索+日志 8.x
React + Ant Design Pro 商家后台 React 18
Bull 任务队列 4.x

2. 商家后台架构

2.1 技术选型

  • 前端: React 18 + Ant Design Pro + ECharts + Vite
  • 状态管理: Zustand
  • 部署: Nginx静态托管 + CDN

2.2 项目结构

banxiang-merchant-web/
├── src/
│   ├── pages/
│   │   ├── login/           # 登录
│   │   ├── register/        # 注册+资质
│   │   ├── dashboard/       # 数据看板
│   │   ├── services/        # 服务管理
│   │   ├── orders/          # 订单管理
│   │   ├── finance/         # 财务结算
│   │   ├── reviews/         # 评价管理
│   │   └── settings/        # 店铺设置
│   ├── components/
│   ├── services/api.ts
│   └── stores/
└── package.json

2.3 增量DDL

-- ===========================
-- V2.0 增量DDL
-- ===========================

-- 1. 商家
CREATE TABLE merchants (
  id BIGSERIAL PRIMARY KEY,
  company_name VARCHAR(200) NOT NULL,
  credit_code VARCHAR(18) UNIQUE,
  category VARCHAR(50) NOT NULL,
  store_name VARCHAR(100),
  store_description TEXT,
  store_logo_url TEXT,
  contact_name VARCHAR(50),
  contact_phone VARCHAR(11),
  contact_email VARCHAR(100),
  business_license_url TEXT,
  industry_license_url TEXT,
  other_licenses TEXT[],
  address TEXT,
  lat DECIMAL(10,7),
  lng DECIMAL(10,7),
  service_area TEXT[],
  business_hours JSONB,
  annual_fee DECIMAL(10,2) DEFAULT 0,
  commission_rate DECIMAL(4,2),
  level VARCHAR(20) DEFAULT 'normal'
    CHECK (level IN ('normal', 'certified', 'strategic')),
  rating DECIMAL(2,1) DEFAULT 5.0,
  total_orders INTEGER DEFAULT 0,
  total_revenue DECIMAL(12,2) DEFAULT 0,
  status VARCHAR(20) DEFAULT 'pending',
  approved_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE merchant_accounts (
  id BIGSERIAL PRIMARY KEY,
  merchant_id BIGINT REFERENCES merchants(id),
  phone VARCHAR(11) UNIQUE NOT NULL,
  password_hash VARCHAR(100),
  role VARCHAR(20) DEFAULT 'owner',
  last_login_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE merchant_services (
  id BIGSERIAL PRIMARY KEY,
  merchant_id BIGINT REFERENCES merchants(id),
  title VARCHAR(200) NOT NULL,
  category VARCHAR(50),
  subcategory VARCHAR(50),
  description TEXT,
  images TEXT[],
  price DECIMAL(10,2),
  original_price DECIMAL(10,2),
  price_unit VARCHAR(20),
  stock INTEGER,
  service_duration VARCHAR(50),
  is_online BOOLEAN DEFAULT TRUE,
  sales_count INTEGER DEFAULT 0,
  rating DECIMAL(2,1) DEFAULT 5.0,
  status VARCHAR(20) DEFAULT 'active',
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE merchant_settlements (
  id BIGSERIAL PRIMARY KEY,
  merchant_id BIGINT REFERENCES merchants(id),
  period_start DATE,
  period_end DATE,
  total_orders INTEGER,
  gross_amount DECIMAL(12,2),
  commission_amount DECIMAL(12,2),
  net_amount DECIMAL(12,2),
  bank_account_encrypted JSONB,
  status VARCHAR(20) DEFAULT 'pending',
  paid_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE merchant_daily_stats (
  merchant_id BIGINT REFERENCES merchants(id),
  stat_date DATE,
  page_views INTEGER DEFAULT 0,
  order_count INTEGER DEFAULT 0,
  revenue DECIMAL(10,2) DEFAULT 0,
  avg_rating DECIMAL(2,1),
  PRIMARY KEY(merchant_id, stat_date)
);

-- 2. 积分
CREATE TABLE point_accounts (
  user_id BIGINT PRIMARY KEY REFERENCES users(id),
  total_points INTEGER DEFAULT 0,
  available_points INTEGER DEFAULT 0,
  used_points INTEGER DEFAULT 0,
  expired_points INTEGER DEFAULT 0,
  updated_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE point_transactions (
  id BIGSERIAL PRIMARY KEY,
  user_id BIGINT REFERENCES users(id),
  type VARCHAR(20),
  action VARCHAR(50),
  points INTEGER,
  balance INTEGER,
  reference_id VARCHAR(50),
  description TEXT,
  expires_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE point_products (
  id BIGSERIAL PRIMARY KEY,
  title VARCHAR(100),
  description TEXT,
  image_url TEXT,
  points_required INTEGER,
  stock INTEGER,
  category VARCHAR(20),
  status VARCHAR(20) DEFAULT 'active',
  created_at TIMESTAMP DEFAULT NOW()
);

-- 3. 优惠券
CREATE TABLE coupon_templates (
  id BIGSERIAL PRIMARY KEY,
  title VARCHAR(100),
  type VARCHAR(20),
  value DECIMAL(10,2),
  min_amount DECIMAL(10,2),
  applicable_categories TEXT[],
  merchant_id BIGINT REFERENCES merchants(id),
  total_count INTEGER,
  issued_count INTEGER DEFAULT 0,
  valid_days INTEGER,
  status VARCHAR(20) DEFAULT 'active',
  created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE user_coupons (
  id BIGSERIAL PRIMARY KEY,
  user_id BIGINT REFERENCES users(id),
  template_id BIGINT REFERENCES coupon_templates(id),
  status VARCHAR(20) DEFAULT 'available',
  used_order_no VARCHAR(20),
  expires_at TIMESTAMP,
  used_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW()
);

-- 4. 拼团
CREATE TABLE group_buy_campaigns (
  id BIGSERIAL PRIMARY KEY,
  service_id BIGINT REFERENCES merchant_services(id),
  original_price DECIMAL(10,2),
  group_price DECIMAL(10,2),
  min_members INTEGER DEFAULT 3,
  valid_hours INTEGER DEFAULT 24,
  status VARCHAR(20) DEFAULT 'active',
  created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE group_buy_orders (
  id BIGSERIAL PRIMARY KEY,
  campaign_id BIGINT REFERENCES group_buy_campaigns(id),
  initiator_id BIGINT REFERENCES users(id),
  current_members INTEGER DEFAULT 1,
  status VARCHAR(20) DEFAULT 'pending',
  expires_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE group_buy_members (
  group_order_id BIGINT REFERENCES group_buy_orders(id),
  user_id BIGINT REFERENCES users(id),
  order_no VARCHAR(20),
  joined_at TIMESTAMP DEFAULT NOW(),
  PRIMARY KEY(group_order_id, user_id)
);

-- 5. 课程
CREATE TABLE courses (
  id BIGSERIAL PRIMARY KEY,
  title VARCHAR(200),
  category VARCHAR(50),
  instructor_name VARCHAR(50),
  description TEXT,
  cover_image TEXT,
  type VARCHAR(20),
  video_url TEXT,
  live_room_id VARCHAR(50),
  scheduled_at TIMESTAMP,
  duration_minutes INTEGER,
  price DECIMAL(10,2) DEFAULT 0,
  enrollment_count INTEGER DEFAULT 0,
  rating DECIMAL(2,1) DEFAULT 5.0,
  status VARCHAR(20) DEFAULT 'active',
  created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE course_enrollments (
  course_id BIGINT REFERENCES courses(id),
  user_id BIGINT REFERENCES users(id),
  progress DECIMAL(5,2) DEFAULT 0,
  completed BOOLEAN DEFAULT FALSE,
  enrolled_at TIMESTAMP DEFAULT NOW(),
  PRIMARY KEY(course_id, user_id)
);

3. 商家API端点

方法 路径 描述
POST /merchant/register 商家注册
POST /merchant/auth/login 登录
GET /merchant/dashboard 看板
GET/POST/PUT/DELETE /merchant/services/* 服务CRUD
GET/POST /merchant/orders/* 订单管理
GET/POST /merchant/settlements/* 结算管理
GET /merchant/stats/* 数据统计
GET/POST /merchant/reviews/* 评价管理
PUT /merchant/settings 店铺设置
POST /merchant/coupons 创建优惠券

4. 结算系统

// workers/settlement.js - 每月1日凌晨生成结算单
cron.schedule('0 2 1 * *', async () => {
  const merchants = await db.query('SELECT * FROM merchants WHERE status = $1', ['active']);
  const lastMonth = moment().subtract(1, 'month');
  
  for (const m of merchants.rows) {
    const stats = await db.query(`
      SELECT COUNT(*) as cnt, COALESCE(SUM(amount), 0) as gross
      FROM orders o
      JOIN merchant_services ms ON o.detail->>'serviceId' = ms.id::text
      WHERE ms.merchant_id = $1 AND o.status = 'completed'
        AND o.completed_at BETWEEN $2 AND $3
    `, [m.id, lastMonth.startOf('month').toDate(), lastMonth.endOf('month').toDate()]);
    
    const gross = parseFloat(stats.rows[0].gross);
    const commission = gross * m.commission_rate / 100;
    
    await db.query(`
      INSERT INTO merchant_settlements 
      (merchant_id, period_start, period_end, total_orders, gross_amount, commission_amount, net_amount)
      VALUES ($1, $2, $3, $4, $5, $6, $7)
    `, [m.id, lastMonth.startOf('month').format('YYYY-MM-DD'), 
        lastMonth.endOf('month').format('YYYY-MM-DD'),
        stats.rows[0].cnt, gross, commission, gross - commission]);
  }
});

5. Elasticsearch搜索

// 商家/服务索引使用ik_max_word分词器
// 支持:全文搜索 + 地理位置排序 + 分类筛选 + 评分排序
// GET /api/v1/search?q=保洁&category=housekeeping&lat=30.57&lng=104.07
router.get('/search', async (req, res) => {
  const { q, category, lat, lng, page = 1, size = 20 } = req.query;
  const result = await esClient.search({
    index: 'banxiang_services',
    body: {
      query: {
        bool: {
          must: [{ multi_match: { query: q, fields: ['title^2', 'description'] } }],
          filter: category ? [{ term: { category } }] : []
        }
      },
      sort: lat ? [{ _geo_distance: { location: { lat, lon: lng }, order: 'asc' } }] : [{ salesCount: 'desc' }],
      from: (page - 1) * size, size
    }
  });
  res.json({ success: true, data: result.hits });
});

6. 完整部署方案

6.1 服务器配置

服务 配置 月费
应用服务器 ECS 4核8G × 2 ¥800
数据库 RDS PG 4核8G主从 ¥600
Redis 2G ¥150
Elasticsearch 2核4G ¥300
OSS + CDN 按量 ¥200
月合计 ¥2050

6.2 Docker Compose

version: '3.8'
services:
  app:
    build: .
    ports: ["3000:3000"]
    deploy: { replicas: 2 }
    depends_on: [db, redis, es]
    restart: always
  worker:
    build: .
    command: node workers/index.js
    depends_on: [db, redis]
    restart: always
  db:
    image: postgres:15
    volumes: [pgdata:/var/lib/postgresql/data]
    restart: always
  redis:
    image: redis:7-alpine
    volumes: [redisdata:/data]
    restart: always
  es:
    image: elasticsearch:8.12.0
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes: [esdata:/usr/share/elasticsearch/data]
    restart: always
  nginx:
    image: nginx:alpine
    ports: ["80:80", "443:443"]
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./merchant-web/dist:/var/www/merchant
    depends_on: [app]
    restart: always
volumes:
  pgdata:
  redisdata:
  esdata:

6.3 Nginx关键配置

# APP API + SSE支持
server {
    listen 443 ssl;
    server_name api.banxiang.com;
    location /api/ { proxy_pass http://app:3000; }
    location /api/v1/ai/chat {
        proxy_pass http://app:3000;
        proxy_buffering off;
        proxy_http_version 1.1;
    }
}
# 商家后台SPA
server {
    listen 443 ssl;
    server_name merchant.banxiang.com;
    root /var/www/merchant;
    location / { try_files $uri /index.html; }
    location /api/merchant/ { proxy_pass http://app:3000; }
}

7. 数据库表总览全版本49张表

版本 表数 核心表
V1.0 17张 users, activities, ai_conversations, orders, hospitals等
V1.1 9张 captains, memberships, service_providers, products等
V1.2 11张 health_records, child_users, posts, service_products等
V2.0 12张 merchants, point_accounts, coupon_templates, courses等
合计 49张

8. 向微服务演进路线

V2.0 (当前): 模块化单体
  → 代码按服务边界分离,共享数据库

V3.0 (计划): 拆分核心服务
  → 用户服务独立DB
  → 活动服务独立DB
  → AI管家服务独立GPU资源
  → 其余保持单体

V4.0 (远期): 完整微服务
  → 所有服务独立
  → API Gateway统一入口
  → 服务间gRPC通信
  → K8s编排

9. 安全合规清单

项目 状态 说明
《个人信息保护法》合规 最小收集、明确告知、分项授权
数据加密 TLS 1.3 + AES-256
健康数据隔离 单独加密存储
医疗免责声明 所有页面标注
金融合规 仅信息展示,不销售
老年人权益 无自动续费、大额二次确认
RBAC权限 用户/商家/管理员角色分离
审计日志 全操作记录
数据备份 每日自动+跨区域
安全渗透测试 📋 V2.0上线前完成

文档结束