Files
medical-mall/mall_sql/docs/MODULE_ANALYSIS.md
2026-01-30 16:11:23 +08:00

21 KiB
Raw Blame History

📊 doc_mall 模块深度分析报告

📋 目录

  1. 模块概述
  2. 数据库存储方式
  3. 数据库交互方式
  4. 开发模式
  5. 开发流程
  6. 技术架构总结

一、模块概述

1.1 模块定位

doc_mall 是一个电商商城系统模块,属于"梅州市智慧医养数字赋能平台"中的医养商城子系统。该模块提供医疗用品、保健产品、医养结合服务的在线销售平台。

1.2 核心功能

  • 🛒 商品管理: 商品展示、分类、品牌、多规格SKU
  • 🏪 店铺管理: 商家店铺信息、认证、营业管理
  • 📦 订单系统: 订单创建、支付、发货、收货、评价全流程
  • 🛍️ 购物车: 商品选择、数量管理
  • 🎫 营销系统: 优惠券、收藏、浏览历史、搜索记录
  • 🚚 配送管理: 配送员管理、配送任务、实时位置跟踪
  • 评价系统: 商品评价、商家回复、匿名评价

1.3 技术栈

  • 数据库: PostgreSQL 13+ / Supabase
  • 前端框架: uni-app-x (UTS Android 兼容)
  • 认证系统: Supabase Auth
  • API方式: Supabase REST API + PostgREST

二、数据库存储方式

2.1 数据库类型

PostgreSQL + Supabase 兼容架构

  • 主数据库: PostgreSQL 13+
  • 云服务: Supabase (PostgreSQL 托管 + 扩展服务)
  • 兼容性: 同时支持标准 PostgreSQL 和 Supabase 环境

2.2 存储架构设计

2.2.1 表命名规范

  • 前缀策略: 所有商城表使用 ml_ 前缀 (mall)
  • 复用策略: 仅复用 ak_users 用户主表,其他表全部独立
  • 命名示例:
    • ml_products - 商品表
    • ml_orders - 订单表
    • ml_user_profiles - 用户扩展表

2.2.2 数据表结构 (21张表)

功能模块 表数量 主要表名 说明
用户管理 2张 ml_user_profiles, ml_user_addresses 用户扩展信息、地址管理
商品管理 5张 ml_products, ml_product_skus, ml_categories, ml_brands, ml_product_specs 商品、SKU、分类、品牌、规格
店铺管理 1张 ml_shops 商家店铺信息
订单管理 2张 ml_orders, ml_order_items 订单主表、订单商品明细
购物车 1张 ml_shopping_cart 购物车商品
营销系统 2张 ml_coupon_templates, ml_user_coupons 优惠券模板、用户优惠券
配送管理 2张 ml_delivery_drivers, ml_delivery_tasks 配送员、配送任务
评价系统 1张 ml_product_reviews 商品评价
用户行为 3张 ml_user_favorites, ml_browse_history, ml_search_history 收藏、浏览历史、搜索记录
系统配置 2张 ml_system_configs, ml_regions 系统配置、地区数据

2.2.3 核心设计特性

1. UUID 主键设计

id UUID PRIMARY KEY DEFAULT uuid_generate_v4()
  • 所有表使用 UUID 作为主键
  • 支持分布式系统避免ID冲突
  • 使用 uuid-ossp 扩展生成

2. SEO 友好的自增ID (cid)

cid SERIAL UNIQUE NOT NULL  -- SEO友好的自增ID
  • 为主要表添加 cid 字段用于URL生成
  • 提供简洁、语义化的URL路径
  • 例如: /product/123 而不是 /product/uuid-string

3. JSONB 灵活数据存储

image_urls JSONB DEFAULT '[]'
preferences JSONB DEFAULT '{}'
specifications JSONB DEFAULT '{}'
  • 使用 JSONB 存储灵活的JSON数据
  • 支持高效查询和索引 (GIN索引)
  • 适合存储数组、对象等非结构化数据

4. 时间戳字段

created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
  • 标准的时间戳字段
  • 自动记录创建和更新时间
  • 通过触发器自动更新 updated_at

5. 外键约束

user_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE
  • 完整的引用完整性约束
  • 级联删除保证数据一致性
  • 复用 ak_users 表实现单点登录

2.3 索引优化策略

2.3.1 索引类型

  • 主键索引: 自动创建 (UUID)
  • 唯一索引: 防止数据重复 (product_code, order_no 等)
  • 外键索引: 30+ 个优化查询索引
  • 复合索引: 针对常用查询组合
  • GIN 索引: JSON 和数组字段的高效查询

2.3.2 索引示例

-- 商品表索引
CREATE INDEX idx_ml_products_merchant ON public.ml_products(merchant_id);
CREATE INDEX idx_ml_products_category ON public.ml_products(category_id);
CREATE INDEX idx_ml_products_status ON public.ml_products(status);
CREATE INDEX idx_ml_products_cid ON public.ml_products(cid);  -- SEO查询

-- 订单表索引
CREATE INDEX idx_ml_orders_user ON public.ml_orders(user_id);
CREATE INDEX idx_ml_orders_merchant ON public.ml_orders(merchant_id);
CREATE INDEX idx_ml_orders_status ON public.ml_orders(order_status);
CREATE INDEX idx_ml_orders_created ON public.ml_orders(created_at DESC);

-- JSONB GIN索引
CREATE INDEX idx_ml_products_images_gin ON public.ml_products USING GIN(image_urls);

2.4 数据安全策略 (RLS)

2.4.1 Row Level Security (行级安全)

  • 启用方式: 所有表启用 RLS 策略
  • 认证方式: 使用 Supabase auth.uid() 进行身份验证
  • 权限模型: 基于用户角色的细粒度权限控制

2.4.2 RLS 策略示例

-- 用户只能访问自己的数据
CREATE POLICY ml_user_profiles_select_policy ON public.ml_user_profiles
    FOR SELECT USING (
        auth.uid()::text = (SELECT auth_id::text FROM public.ak_users WHERE id = user_id)
    );

-- 商品公开查看,商家管理
CREATE POLICY ml_products_select_policy ON public.ml_products
    FOR SELECT USING (status = 1);  -- 所有人可查看已上架商品

CREATE POLICY ml_products_update_policy ON public.ml_products
    FOR UPDATE USING (
        auth.uid()::text = (SELECT auth_id::text FROM public.ak_users WHERE id = merchant_id)
    );  -- 商家只能管理自己的商品

-- 订单权限:用户和商家都可查看
CREATE POLICY ml_orders_select_policy ON public.ml_orders
    FOR SELECT USING (
        auth.uid()::text = (SELECT auth_id::text FROM public.ak_users WHERE id = user_id)
        OR
        auth.uid()::text = (SELECT auth_id::text FROM public.ak_users WHERE id = merchant_id)
    );

2.5 触发器自动化

2.5.1 触发器功能

触发器名称 功能 应用表
update_updated_at_column 自动更新时间戳 8张主要表
ensure_single_default_address 确保唯一默认地址 ml_user_addresses
update_product_stock 自动更新商品库存 ml_product_skus
handle_order_status_change 订单状态变更处理 ml_orders

2.5.2 触发器示例

-- 自动更新 updated_at
CREATE TRIGGER trigger_ml_user_profiles_updated_at
    BEFORE UPDATE ON public.ml_user_profiles
    FOR EACH ROW EXECUTE FUNCTION public.update_updated_at_column();

-- 确保唯一默认地址
CREATE TRIGGER trigger_ensure_single_default_address
    BEFORE INSERT OR UPDATE ON public.ml_user_addresses
    FOR EACH ROW EXECUTE FUNCTION public.ensure_single_default_address();

2.6 数据库函数

2.6.1 业务函数

函数名称 功能描述 返回类型
generate_order_no() 生成唯一订单号 TEXT
generate_coupon_code() 生成优惠券码 TEXT
get_user_default_address() 获取用户默认地址 TABLE
is_verified_merchant() 检查是否认证商家 BOOLEAN
calculate_cart_total() 计算购物车总金额 DECIMAL
get_product_available_stock() 获取商品可用库存 INTEGER

2.6.2 函数示例

-- 生成订单号
CREATE OR REPLACE FUNCTION public.generate_order_no()
RETURNS TEXT AS $$
BEGIN
    RETURN 'ORD' || TO_CHAR(NOW(), 'YYYYMMDD') || LPAD(NEXTVAL('order_no_seq')::TEXT, 6, '0');
END;
$$ LANGUAGE plpgsql;

-- 计算购物车总金额
CREATE OR REPLACE FUNCTION public.calculate_cart_total(p_user_id UUID)
RETURNS DECIMAL AS $$
DECLARE
    total DECIMAL(12,2);
BEGIN
    SELECT COALESCE(SUM(c.quantity * p.base_price), 0)
    INTO total
    FROM ml_shopping_cart c
    JOIN ml_products p ON c.product_id = p.id
    WHERE c.user_id = p_user_id AND c.selected = TRUE;
    RETURN total;
END;
$$ LANGUAGE plpgsql;

2.7 视图设计

2.7.1 业务视图

视图名称 功能描述
ml_users_view 商城用户完整信息视图
ml_products_detail_view 商品详情视图(含分类、品牌、店铺信息)
ml_orders_detail_view 订单详情视图(含客户、商家、状态信息)

2.7.2 视图示例

-- 商品详情视图
CREATE VIEW ml_products_detail_view AS
SELECT 
    p.*,
    c.name as category_name,
    b.name as brand_name,
    s.shop_name,
    s.shop_logo
FROM ml_products p
LEFT JOIN ml_categories c ON p.category_id = c.id
LEFT JOIN ml_brands b ON p.brand_id = b.id
LEFT JOIN ml_shops s ON p.merchant_id = s.merchant_id;

三、数据库交互方式

3.1 API 架构

3.1.1 Supabase REST API

  • 基础URL: https://your-project.supabase.co/rest/v1/
  • 认证方式: JWT Token (Bearer Token)
  • API Key: apikey Header
  • 协议: HTTP/HTTPS RESTful API

3.1.2 PostgREST 自动生成

  • Supabase 基于 PostgREST 自动生成 REST API
  • 每个表自动获得 CRUD 接口
  • 支持复杂查询、过滤、排序、分页

3.2 前端交互方式

3.2.1 Supabase 客户端封装

项目使用自定义的 Supabase 客户端封装 (components/supadb/aksupa.uts):

// 客户端初始化
const supaClient = new AkSupa({
    baseUrl: 'https://your-project.supabase.co',
    apikey: 'your-anon-key'
});

// 查询数据
const response = await supaClient.select('ml_products', null, {
    columns: 'id,name,base_price,main_image_url',
    limit: 20,
    order: 'created_at.desc'
});

// 插入数据
const result = await supaClient.insert('ml_orders', {
    user_id: userId,
    merchant_id: merchantId,
    total_amount: 100.00,
    order_status: 1
});

// 更新数据
await supaClient.update('ml_products', { id: productId }, {
    status: 2,
    updated_at: new Date().toISOString()
});

// 删除数据
await supaClient.delete('ml_user_favorites', { id: favoriteId });

3.2.2 查询选项支持

type AkSupaSelectOptions = {
    columns?: string;        // 选择字段: 'id,name,price'
    limit?: number;           // 限制数量
    order?: string;          // 排序: 'created_at.desc'
    rangeFrom?: number;       // 分页起始
    rangeTo?: number;         // 分页结束
    count?: string;          // 计数方式: 'exact'|'planned'|'estimated'
    single?: boolean;         // 单条记录
    head?: boolean;          // 仅返回元数据
}

3.2.3 过滤条件支持

// 简单过滤
const filter = {
    status: 1,
    merchant_id: userId
};

// 复杂过滤 (PostgREST 操作符)
const filter = {
    base_price: { gte: 100, lte: 500 },      // 范围查询
    name: { ilike: '%商品%' },                // 模糊查询
    category_id: { in: [id1, id2, id3] },    // IN 查询
    created_at: { gte: '2024-01-01' }        // 时间范围
};

3.3 实时数据同步

3.3.1 Supabase Realtime

  • 支持 WebSocket 实时数据同步
  • 表变更自动推送到客户端
  • 适用于订单状态更新、库存变化等场景
// 实时订阅订单状态
supaClient.realtime.subscribe('ml_orders', {
    filter: `id=eq.${orderId}`,
    event: 'UPDATE',
    callback: (payload) => {
        console.log('订单状态更新:', payload);
    }
});

3.4 存储过程调用 (RPC)

3.4.1 数据库函数调用

// 调用数据库函数
const result = await supaClient.rpc('calculate_cart_total', {
    p_user_id: userId
});

// 调用生成订单号函数
const orderNo = await supaClient.rpc('generate_order_no');

3.5 认证与权限

3.5.1 Supabase Auth 集成

// 用户登录
const { data, error } = await supaClient.auth.signInWithPassword({
    email: 'user@example.com',
    password: 'password'
});

// 获取当前用户
const user = await supaClient.auth.getUser();

// Token 自动附加到请求头
// Authorization: Bearer <jwt_token>

3.5.2 RLS 自动生效

  • 前端请求自动携带 JWT Token
  • RLS 策略根据 auth.uid() 自动过滤数据
  • 用户只能访问被授权的数据

3.6 数据迁移与初始化

3.6.1 数据库脚本执行

# PostgreSQL 直接执行
psql -h localhost -U postgres -d your_database -f complete_mall_database.sql

# Supabase Dashboard 执行
# 1. 登录 Supabase Dashboard
# 2. 进入 SQL Editor
# 3. 复制粘贴 SQL 脚本
# 4. 执行脚本

3.6.2 模拟数据插入

# 先执行主数据库脚本
psql -f complete_mall_database.sql

# 再执行模拟数据
psql -f mock_data_insert.sql

四、开发模式

4.1 架构模式

4.1.1 BaaS (Backend as a Service) 模式

  • 特点: 使用 Supabase 作为后端服务
  • 优势:
    • 无需自建后端服务器
    • 自动生成 REST API
    • 内置认证、权限、实时同步
    • 减少后端开发工作量

4.1.2 数据库优先 (Database-First) 模式

  • 流程: 先设计数据库 → 自动生成 API → 前端调用
  • 优势:
    • 数据结构清晰
    • API 自动生成,减少手写代码
    • 类型安全 (通过 TypeScript/UTS 类型定义)

4.2 前端开发模式

4.2.1 uni-app-x 框架

  • 平台: uni-app-x (跨平台框架)
  • 语言: UTS (UniApp TypeScript)
  • 兼容性: 严格遵循 UTS Android 语法规范

4.2.2 类型定义驱动

// types/mall-types.uts
export type ProductType = {
    id: string
    merchant_id: string
    category_id: string
    name: string
    description: string | null
    images: Array<string>
    price: number
    stock: number
    status: number
    created_at: string
}

4.2.3 组件化开发

  • 页面组件: pages/mall/
  • 业务组件: components/
  • 工具类: utils/
  • 类型定义: types/

4.3 数据访问模式

4.3.1 服务层封装

// 商品服务
class ProductService {
    async getProducts(filters: any) {
        return await supaClient.select('ml_products', filters, {
            limit: 20,
            order: 'created_at.desc'
        });
    }
    
    async getProductById(id: string) {
        return await supaClient.select('ml_products', { id }, {
            single: true
        });
    }
}

4.3.2 响应式数据绑定

  • 使用 uni-app-x 的数据绑定机制
  • 结合 Supabase Realtime 实现实时更新
  • 状态管理通过组件状态或全局状态

4.4 安全模式

4.4.1 多层安全防护

  1. 网络层: HTTPS 加密传输
  2. 认证层: Supabase Auth JWT Token
  3. 权限层: RLS 行级安全策略
  4. 应用层: 前端数据验证

4.4.2 最小权限原则

  • 用户只能访问自己的数据
  • 商家只能管理自己的商品和订单
  • 公开数据 (商品列表) 所有人可查看

五、开发流程

5.1 数据库设计流程

5.1.1 需求分析

  1. 业务需求梳理

    • 商品管理需求
    • 订单流程需求
    • 用户角色需求
    • 营销功能需求
  2. 数据模型设计

    • 实体识别 (商品、订单、用户等)
    • 关系设计 (一对多、多对多)
    • 字段设计 (类型、约束、索引)

5.1.2 数据库脚本编写

-- 1. 创建表结构
CREATE TABLE ml_products (...);

-- 2. 创建索引
CREATE INDEX idx_ml_products_merchant ON ml_products(merchant_id);

-- 3. 创建触发器
CREATE TRIGGER trigger_update_updated_at ...;

-- 4. 创建 RLS 策略
CREATE POLICY ml_products_select_policy ...;

-- 5. 创建函数
CREATE FUNCTION generate_order_no() ...;

-- 6. 创建视图
CREATE VIEW ml_products_detail_view AS ...;

5.1.3 数据库部署

  1. 环境准备

    • PostgreSQL 13+ 或 Supabase 项目
    • 数据库用户权限配置
  2. 脚本执行

    # 执行主数据库脚本
    psql -f complete_mall_database.sql
    
    # 执行模拟数据 (可选)
    psql -f mock_data_insert.sql
    
  3. 验证测试

    # 执行验证脚本
    psql -f validation_test.sql
    

5.2 前端开发流程

5.2.1 类型定义

// 1. 定义 TypeScript/UTS 类型
export type ProductType = {
    id: string
    name: string
    price: number
    // ...
}

5.2.2 API 服务封装

// 2. 封装 API 调用
class MallAPI {
    async getProducts() {
        return await supaClient.select('ml_products', ...);
    }
}

5.2.3 页面开发

<!-- 3. 开发页面组件 -->
<template>
    <view class="product-list">
        <view v-for="product in products" :key="product.id">
            {{ product.name }}
        </view>
    </view>
</template>

<script setup lang="uts">
import { ProductType } from '@/types/mall-types.uts'

const products = ref<Array<ProductType>>([])

onMounted(async () => {
    const res = await MallAPI.getProducts()
    products.value = res.data
})
</script>

5.2.4 测试验证

  • 功能测试: 验证业务流程
  • 权限测试: 验证 RLS 策略
  • 性能测试: 验证查询性能

5.3 迭代开发流程

5.3.1 功能迭代

  1. 需求变更 → 数据库迁移脚本
  2. 表结构更新mall_alter_upgrade.sql
  3. 数据迁移 → 迁移脚本执行
  4. 前端适配 → 类型定义更新 → 页面更新

5.3.2 版本管理

  • 数据库版本: 通过迁移脚本管理
  • 代码版本: Git 版本控制
  • 文档版本: Markdown 文档同步更新

5.4 部署流程

5.4.1 开发环境

  1. 本地 PostgreSQL 或 Supabase 本地实例
  2. 执行数据库脚本
  3. 配置环境变量
  4. 启动前端开发服务器

5.4.2 生产环境

  1. Supabase 云服务部署

    • 创建 Supabase 项目
    • 执行数据库脚本
    • 配置环境变量
    • 部署前端应用
  2. 自建 PostgreSQL 部署

    • 搭建 PostgreSQL 服务器
    • 执行数据库脚本
    • 配置 Nginx 反向代理 (如需要)
    • 部署前端应用

六、技术架构总结

6.1 技术栈总结

层级 技术 说明
数据库 PostgreSQL 13+ 关系型数据库
BaaS平台 Supabase 后端即服务
API层 PostgREST 自动生成 REST API
认证 Supabase Auth JWT Token 认证
前端框架 uni-app-x 跨平台框架
开发语言 UTS UniApp TypeScript
类型系统 TypeScript/UTS 类型安全

6.2 架构特点

优势

  1. 开发效率高: BaaS 模式减少后端开发
  2. 类型安全: 完整的类型定义系统
  3. 自动API: PostgREST 自动生成 REST API
  4. 权限完善: RLS 行级安全策略
  5. 实时同步: Supabase Realtime 支持
  6. 扩展性强: 数据库函数、触发器、视图支持

⚠️ 注意事项

  1. Supabase 依赖: 深度依赖 Supabase 生态
  2. 学习曲线: 需要熟悉 PostgreSQL 和 Supabase
  3. 成本考虑: Supabase 云服务有使用限制
  4. 迁移成本: 如需迁移到其他平台,成本较高

6.3 最佳实践

  1. 数据库设计优先: 先设计好数据库结构
  2. 类型定义同步: 保持数据库和类型定义同步
  3. RLS 策略完善: 确保数据安全
  4. 索引优化: 针对查询场景优化索引
  5. 文档完善: 保持文档与代码同步

📚 相关文档


生成时间: 2025年1月
版本: v1.0
状态: 完整分析报告